Y_Less

Y_Less

Nov 29th, 2007
434
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 121.08 KB | None | 0 0
  1. /*----------------------------------------------------------------------------*-
  2.                     ===============================
  3.                     Y Sever Includes - Objects Core
  4.                     ===============================
  5. Description:
  6.     Handles object streaming for >150 objects per player.  Also provides VW
  7.     support and improved object attachment (i.e. it works).  New versions
  8.     combines mine and Peter's streaming systems to narrow down objects by
  9.     approximation by a grid system then check all objects visible in near
  10.     by sections.
  11. Legal:
  12.     Copyright (C) 2007 Alex "Y_Less" Cole
  13.  
  14.     This program is free software; you can redistribute it and/or
  15.     modify it under the terms of the GNU General Public License
  16.     as published by the Free Software Foundation; either version 2
  17.     of the License, or (at your option) any later version.
  18.  
  19.     This program is distributed in the hope that it will be useful,
  20.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.     GNU General Public License for more details.
  23.  
  24.     You should have received a copy of the GNU General Public License
  25.     along with this program; if not, write to the Free Software
  26.     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  27.     MA 02110-1301, USA.
  28. Version:
  29.     0.2.6
  30. Changelog:
  31.     26/11/07:
  32.         Finished up master system.
  33.         Fixed DestroyDynamicObject not removing client objects.
  34.     16/11/07:
  35.         Removed global flag as it wasn't doing anything.
  36.     27/10/07:
  37.         Fixed moving objects so they actually move
  38.     26/10/07:
  39.         Added object children to attach objects to each other.
  40.     09/10/07:
  41.         FINALLY found compile hang bug.
  42.         Repaired removed code.
  43.         Put object co-ordinate code in Object_ParseSet
  44.     23/09/07:
  45.         Updated FindSector, AddToSector and RemoveFromSector to use new system.
  46.     22/09/07:
  47.         Started work on new sector system, minor macro changes, lots of maths.
  48.         Wrote squareroot macro.
  49.         Updated constructor.
  50.     21/09/07:
  51.         Overhauled sector code, skips columns and interiors plus more efficient.
  52.     20/09/07:
  53.         Made some core functions static so they don't get called by accident.
  54.         Changed auto-adjust code so it rounds to nearest whole log number.
  55.         Moved zone-find code around to skip whole columns at once.
  56.         Added zone sorting so they're done in order of distance.
  57.         Added breakout code so once all objects are found processing is exited.
  58.     19/09/07:
  59.         Added auto-adjusting zone sizes based on object limits.
  60.         Altered zone find code to return only possible visible zones.
  61.         Fixed rare hanging bug in close list code.
  62.     18/09/07:
  63.         My birthday - yes I'm that sad to code on it and put it in a changelog.
  64.         Rewrote sectors code to use known sectors instead of position.
  65.     17/09/07:
  66.         Rewrote find code to find closest objects instead of random close ones.
  67.     03/08/07:
  68.         Updated timer system.
  69.     07/05/07:
  70.         Added groups support via default settings.
  71.         Corrected (unused) flag - bit pointless but meh.
  72.     02/05/07:
  73.         Added YSI_ prefix to all globals.
  74.         Added dynamic object API calls.
  75.     30/04/07:
  76.         Fixed bug in DestroyDynamicObject with OOB objects not 1st in list.
  77.         Exported sector removal code to Object_RemoveFromSector.
  78.         Added SECTOR parameter to E_OBJECT for ease of modification.
  79.     25/04/07:
  80.         Added 3d checking.
  81.         Added DestroyDynamicObject API function.
  82.         Fixed location checking on attached objects.
  83.         Fixed loop itteration for cyclic list structure.
  84.     24/04/07:
  85.         Fixed range leave checking.
  86.         Added moving objects list.
  87.     18/04/07:
  88.         Second version - completely rewritten after a chat with Peter.
  89.     16/04/07:
  90.         First version - adapted from my earlier e_objects.inc include.
  91. Functions:
  92.     Public:
  93.         Object_Loop - Main loop for checking.
  94.         Object_CoOrdRemote - Does object location manipulation remotely.
  95.         Object_Remote - Does normal functions remotely.
  96.         Object_UpdateUnused - Adds an object to the remote unused list.
  97.         Object_Broadcast - Saves an object remotely.
  98.         Object_GetLimit - Gets the number of objects the remove master can hold.
  99.         YSIM_Objects - Processes master system instructions.
  100.         Object_AddRem - Remote wrapper for Object_Add.
  101.     Core:
  102.         Object_Object - Constructor.
  103.         Object_OnPlayerDisconnect - Disconnects objects.
  104.     Stock:
  105.         Object_AddToWorld - Make visible in world.
  106.         Object_RemoveFromWorld - Make invisible in world.
  107.         Object_AddToPlayer - Make visible to player.
  108.         Object_RemoveFromPlayer - Make invisible to player.
  109.         Object_AddToAllWorlds - Make visible in all worlds.
  110.         Object_RemoveFromAllWorlds - Make invisible in all worlds.
  111.         Object_AddToAllPlayers - Make visible to all players.
  112.         Object_RemoveFromAllPlayers - Make invisible to all players.
  113.         Object_IsValidModel - Checks if an object is good to be displayed.
  114.         Object_IsGlobal - Checks if an object is visible by default.
  115.         Object_SetViewDistance - Sets an object's view distance.
  116.         Object_IsDescendant - Checks if an object is related to another object.
  117.     Static:
  118.         Object_Add - Internal add function.
  119.         Object_FindSector - Find a location's sector.
  120.         Object_AddToOOB - Add an object to the OOB list.
  121.         Object_AddToSector - Add an object to the specified list.
  122.         Object_RemoveFromSector - Remove an object from the given sector.
  123.         Object_FindSectors - Get near sectors.
  124.         Object_ParseSet - Check objects in list.
  125.         Object_Update - Updates the position of a moving object.
  126.         Object_UpdateChildSectors - Updates the sectors of moved object children.
  127.         Object_SetPos - Moves an object to the given position.
  128.         Object_UpdateAttach - Updates children after dynamic stop.
  129.         Object_Move - Reursive MoveDynamicObject for children.
  130.         Object_RemoveFromParent - Removes an object from it's parent.
  131.         Object_AddToParent - Adds an object to another object.
  132.         Object_AttachToPlayer - Attaches objects to a player recursively.
  133.         Object_CheckDescendant - Recursive call for Object_IsDescendant.
  134.         Object_Destroy - Delete an object with no checks.
  135.     Inline:
  136.         Object_IsValid - Internal validity check.
  137.         Object_GetAttach - Get player an object's attached to.
  138.         Object_SetAttach - Set player an object's attached to.
  139.         Object_HasPlayer - Checks if a player can see an object.
  140.     API:
  141.         MoveDynamicObject - Wrapper for MoveObject.
  142.         StopDynamicObject - Wrapper for StopObject.
  143.         IsValidDynamicObject - Wrapper for IsValidObject.
  144.         CreateDynamicObject - Wrapper for CreateObject.
  145.         CreatePlayerDynamicObject - Wrapper for CreatePlayerObject.
  146.         CreateVWDynamicObject - Creates an object in only one world.
  147.         CreatePlayerVWDynamicObject - Creates an object for one player in one world.
  148.         DestroyDynamicObject - Wrapper for DestroyObject.
  149.         GetDynamicObjectPos - Wrapper for GetObjectPos.
  150.         GetDynamicObjectRot - Wrapper for GetObjectRot.
  151.         SetDynamicObjectPos = Wrapper for SetObjectPos.
  152.         SetDynamicObjectRot - Wrapper for SetObjectRot.
  153.         AttachDynamicObjectToPlayer - Wrapper for AttachObjectToPlayer.
  154.         DetachDynamicObjectFromPlayer - Removes an object from a player.
  155.         AttachObjectToObject - Attaches an object to another object.
  156.         RemoveObjectFromParent - Removes an object from another object.
  157. Callbacks:
  158.     OnDynamicObjectMoved
  159. Definitions:
  160.     OBJECT_SECTOR_SIZE - Size of edge of a grid square for approximations.
  161.     MAX_DYN_OBJECTS - Maximum number of objects.
  162.     OBJECT_VIEW_DISTANCE - Range to stream objects for.
  163.     NO_OBJECT - No object pointer.
  164.     NO_SECTOR - No sector pointer.
  165.     OBJECT_NO_SECTOR - OOB object marker.
  166.     OBJECT_LOOP_GRANULARITY - Number of itterations per second for the loop.
  167.     NO_ATTACH_PLAYER - Marker for object not attached to anyone.
  168.     OBJECT_WORLDS - Maximum number of worlds objects show up in.
  169.     OBJECT_WORLD_COUNT - Size of bit array of worlds.
  170.     OBJECT_PLAYER_COUNT - Size of bit array of players.
  171. Enums:
  172.     E_OBJECT - Structure of the dynamic object data.
  173.     e_OBJ_FLAG - Flags for the object.
  174. Macros:
  175.     OBJECT_SECTOR_EDGE - Number of sectors on one edge of the world.
  176.     OBJECT_SECTOR_ARRAY - Number of grid squares.
  177.     OBJECT_SIGHT - OBJECT_VIEW_DISTANCE squared for speed.
  178.     OBJECT_VIEW_RATIO - Number of sectors per view radius.
  179.     OBJECT_VIEW_EDGES - Max width of view range in sectors.
  180.     OBJECT_VIEW_SECTORS - Max sectors visible at once.
  181.     NO_OBJECT_CHECK - Invalid model.
  182.     OBJECT_BITS - Number of bits to hold all dynamic objects.
  183.     e_OBJ_FLAG_MOVED - Extension of e_OBJ_FLAG, both move flags together.
  184.     NEW_SECTOR - Sector based on origin sector and current offset.
  185. Tags:
  186.     e_OBJ_FLAG - Flags for objects.
  187. Variables:
  188.     Global:
  189.         -
  190.     Static:
  191.         YSI_g_sObjectSectors - Array of pointers to sector object lists.
  192.         YSI_g_sObjects - Array of objects.
  193.         YSI_g_sOtherSector - Pointer to OOB object list.
  194.         YSI_g_sMovingObjects - Pointer to moving object list.
  195.         YSI_g_sNoObjects - Pointer to unused object list.
  196. Commands:
  197.     -
  198. Compile options:
  199.     NO_PERSONAL_OBJECTS - All players see all objects.
  200.     NO_OBJECT_ATTACH - Objects can't be attached to each other.
  201.     NO_OBJECTS_MOVE - No processing is done for moving objects.
  202.     OBJECT_WORLDS 0 - All objects are visible in all worlds.
  203. Operators:
  204.     -
  205. -*----------------------------------------------------------------------------*/
  206.  
  207. #if !defined OBJECT_BOUNDS_MINX
  208.     #if defined OBJECT_BOUNDS
  209.         #define OBJECT_BOUNDS_MINX (-OBJECT_BOUNDS)
  210.     #else
  211.         #define OBJECT_BOUNDS_MINX (-5000)
  212.     #endif
  213. #endif
  214.  
  215. #if !defined OBJECT_BOUNDS_MINY
  216.     #if defined OBJECT_BOUNDS
  217.         #define OBJECT_BOUNDS_MINY (-OBJECT_BOUNDS)
  218.     #else
  219.         #define OBJECT_BOUNDS_MINY (-5000)
  220.     #endif
  221. #endif
  222.  
  223. #if !defined OBJECT_BOUNDS_MAXX
  224.     #if defined OBJECT_BOUNDS
  225.         #define OBJECT_BOUNDS_MAXX (OBJECT_BOUNDS)
  226.     #else
  227.         #define OBJECT_BOUNDS_MAXX (5000)
  228.     #endif
  229. #endif
  230.  
  231. #if !defined OBJECT_BOUNDS_MAXY
  232.     #if defined OBJECT_BOUNDS
  233.         #define OBJECT_BOUNDS_MAXY (OBJECT_BOUNDS)
  234.     #else
  235.         #define OBJECT_BOUNDS_MAXY (5000)
  236.     #endif
  237. #endif
  238.  
  239. #define OBJECT_BOUNDS_X_SIZE (OBJECT_BOUNDS_MAXX - OBJECT_BOUNDS_MINX)
  240. #define OBJECT_BOUNDS_Y_SIZE (OBJECT_BOUNDS_MAXY - OBJECT_BOUNDS_MINY)
  241.  
  242. #if !defined MAX_DYN_OBJECTS
  243.     #define MAX_DYN_OBJECTS (10000)
  244. #endif
  245.  
  246. #define AVERAGE_OBJECTS_PER_SECTOR (500)
  247.  
  248. #define OBJECT_DISTRIBUTION (((OBJECT_BOUNDS_X_SIZE * OBJECT_BOUNDS_Y_SIZE) / MAX_DYN_OBJECTS) * AVERAGE_OBJECTS_PER_SECTOR)
  249.  
  250. #if !defined OBJECT_SECTOR_SIZE
  251.     #if OBJECT_DISTRIBUTION <= 10
  252.         #define OBJECT_SECTOR_SIZE (1)
  253.     #endif
  254. #endif
  255.  
  256. #if !defined OBJECT_SECTOR_SIZE
  257.     #if OBJECT_DISTRIBUTION <= 100
  258.         #define OBJECT_SECTOR_SIZE (5)
  259.     #endif
  260. #endif
  261.  
  262. #if !defined OBJECT_SECTOR_SIZE
  263.     #if OBJECT_DISTRIBUTION <= 1000
  264.         #define OBJECT_SECTOR_SIZE (10)
  265.     #endif
  266. #endif
  267.  
  268. #if !defined OBJECT_SECTOR_SIZE
  269.     #if OBJECT_DISTRIBUTION <= 10000
  270.         #define OBJECT_SECTOR_SIZE (50)
  271.     #endif
  272. #endif
  273.  
  274. #if !defined OBJECT_SECTOR_SIZE
  275.     #if OBJECT_DISTRIBUTION <= 100000
  276.         #define OBJECT_SECTOR_SIZE (100)
  277.     #endif
  278. #endif
  279.  
  280. #if !defined OBJECT_SECTOR_SIZE
  281.     #if OBJECT_DISTRIBUTION <= 1000000
  282.         #define OBJECT_SECTOR_SIZE (500)
  283.     #endif
  284. #endif
  285.  
  286. #if !defined OBJECT_SECTOR_SIZE
  287.     #if OBJECT_DISTRIBUTION <= 10000000
  288.         #define OBJECT_SECTOR_SIZE (1000)
  289.     #endif
  290. #endif
  291.  
  292. #if !defined OBJECT_SECTOR_SIZE
  293.     #if OBJECT_DISTRIBUTION <= 100000000
  294.         #define OBJECT_SECTOR_SIZE (5000)
  295.     #endif
  296. #endif
  297.  
  298. #if !defined OBJECT_SECTOR_SIZE
  299.     #if OBJECT_DISTRIBUTION <= 1000000000
  300.         #define OBJECT_SECTOR_SIZE (10000)
  301.     #endif
  302. #endif
  303.  
  304. #define OBJECT_SECTOR_X_EDGE (ceildiv(OBJECT_BOUNDS_X_SIZE, OBJECT_SECTOR_SIZE))
  305. #define OBJECT_SECTOR_Y_EDGE (ceildiv(OBJECT_BOUNDS_Y_SIZE, OBJECT_SECTOR_SIZE))
  306.  
  307. #define OBJECT_SECTOR_ARRAY (OBJECT_SECTOR_X_EDGE * OBJECT_SECTOR_Y_EDGE)
  308.  
  309. #define OBJECT_REAL_X_SECTOR_SIZE (float(OBJECT_BOUNDS_X_SIZE) / float(OBJECT_SECTOR_X_EDGE))
  310. #define OBJECT_REAL_Y_SECTOR_SIZE (float(OBJECT_BOUNDS_Y_SIZE) / float(OBJECT_SECTOR_Y_EDGE))
  311.  
  312. #if !defined OBJECT_MAX_VIEW_DISTANCE
  313.     #define OBJECT_MAX_VIEW_DISTANCE 500
  314. #endif
  315.  
  316. #if !defined DEFAULT_OBJECT_VIEW
  317.     #if defined OBJECT_VIEW_DISTANCE
  318.         #define DEFAULT_OBJECT_VIEW (OBJECT_VIEW_DISTANCE)
  319.     #else
  320.         #define DEFAULT_OBJECT_VIEW (200)
  321.     #endif
  322. #endif
  323.  
  324. #define OBJECT_SIGHT (DEFAULT_OBJECT_VIEW * DEFAULT_OBJECT_VIEW)
  325. #define OBJECT_VIEW_RATIO (ceildiv(OBJECT_MAX_VIEW_DISTANCE, OBJECT_SECTOR_SIZE))
  326. #define OBJECT_VIEW_EDGES ((OBJECT_VIEW_RATIO * 2) + 1)
  327. #define OBJECT_VIEW_SECTORS (OBJECT_VIEW_EDGES * OBJECT_VIEW_EDGES)
  328. #define NO_OBJECT -1
  329. #define NO_OBJECT_CHECK (NO_OBJECT & _:e_OBJ_FLAG_MODEL)
  330. #define NO_SECTOR -1
  331. #define OBJECT_NO_SECTOR 0x7FFFFFFF
  332. #define OBJECT_LOD_SECTOR 0x6FFFFFFF
  333. #define OBJECT_INT_SECTOR 0x5FFFFFFF
  334. #define OBJECT_BITS Bit_Bits(MAX_DYN_OBJECTS)
  335. #if !defined OBJECT_LOOP_GRANULARITY
  336.     #define OBJECT_LOOP_GRANULARITY 2
  337. #endif
  338. #define NO_ATTACH_PLAYER 0xFF
  339.  
  340. #define NO_GATE (-1)
  341.  
  342. #define SECTOR_CHECK_TIME (1000)
  343. #define SECTOR_CHECK_FREQUENCY ceildiv(SECTOR_CHECK_TIME, (1000 / OBJECT_LOOP_GRANULARITY))
  344.  
  345. #define MAY_OBJECTS (150)
  346.  
  347. #if !defined OBJECT_WORLDS
  348.     #define OBJECT_WORLDS MAX_WORLDS
  349. #endif
  350.  
  351. #if OBJECT_WORLDS > 32
  352.     #define OBJECT_WORLD_COUNT Bit_Bits(OBJECT_WORLDS)
  353. #else
  354.     #define OBJECT_WORLD_COUNT 2
  355. #endif
  356.  
  357. #define GATE_AREA_TRIGGER (0x80000000)
  358. #define GATE_OPENING (0x40000000)
  359.  
  360. #define ONE_OVER_ROOT_TWO (0.70710678118654752440084436210485)
  361.  
  362. enum e_OBJ_FLAG (<<= 1)
  363. {
  364.     e_OBJ_FLAG_MODEL = 0x00007FFF,
  365.     e_OBJ_FLAG_ATTACH = 0x007F8000,
  366.     e_OBJ_FLAG_ATTACHED = 0x00800000,
  367.     e_OBJ_FLAG_JUMPED,
  368.     e_OBJ_FLAG_MOVED1,
  369.     e_OBJ_FLAG_MOVED2,
  370.     e_OBJ_FLAG_ROTATED,
  371.     e_OBJ_FLAG_ACTIVE,
  372.     e_OBJ_FLAG_RECREATED,
  373.     e_OBJ_FLAG_GATE
  374. }
  375.  
  376. #define e_OBJ_FLAG_MOVED (e_OBJ_FLAG_MOVED1 | e_OBJ_FLAG_MOVED2)
  377.  
  378. enum E_OBJECT
  379. {
  380.     e_OBJ_FLAG:E_OBJECT_MODEL,
  381.     #if defined _YSI_SETUP_MASTER
  382.         E_OBJECT_SCRIPT,
  383.     #endif
  384.     Float:E_OBJECT_X,
  385.     Float:E_OBJECT_Y,
  386.     Float:E_OBJECT_Z,
  387.     Float:E_OBJECT_RX,
  388.     Float:E_OBJECT_RY,
  389.     Float:E_OBJECT_RZ,
  390.     Float:E_OBJECT_VIEW,
  391.     #if OBJECT_WORLDS > 0
  392.         Bit:E_OBJECT_WORLDS[OBJECT_WORLD_COUNT],
  393.     #endif
  394.     #if !defined NO_PERSONAL_OBJECTS
  395.         Bit:E_OBJECT_PLAYERS[PLAYER_BIT_ARRAY],
  396.     #endif
  397.     #if !defined NO_OBJECTS_MOVE
  398.         Float:E_OBJECT_MX,
  399.         Float:E_OBJECT_MY,
  400.         Float:E_OBJECT_MZ,
  401.         Float:E_OBJECT_MS,
  402.     #endif
  403.     E_OBJECT_UPDATES,
  404.     #if !defined NO_OBJECT_ATTACH
  405.         E_OBJECT_PARENT,
  406.         E_OBJECT_SIBLINGS,
  407.         E_OBJECT_CHILDREN,
  408.     #endif
  409.     E_OBJECT_NEXT,
  410.     E_OBJECT_SECTOR
  411. }
  412.  
  413. enum E_OBJECT_ITTER
  414. {
  415.     Float:E_OBJECT_ITTER_DISTANCE,
  416.     E_OBJECT_ITTER_NEXT,
  417.     E_OBJECT_ITTER_LAST,
  418.     E_OBJECT_ITTER_OBJ,
  419.     Float:E_OBJECT_ITTER_X,
  420.     Float:E_OBJECT_ITTER_Y,
  421.     Float:E_OBJECT_ITTER_Z
  422. }
  423.  
  424. enum E_OBJ_SECTOR
  425. {
  426.     E_OBJ_SECTOR_POINTER,
  427.     Float:E_OBJ_SECTOR_MAX_VIEW
  428. }
  429.  
  430. enum E_OSEC_ITTER
  431. {
  432.     E_OSEC_ITTER_SECTOR,
  433.     E_OSEC_ITTER_NEXT,
  434.     Float:E_OSEC_ITTER_DIFF
  435. }
  436.  
  437. enum
  438. {
  439.     E_OBJECT_REMOTE_ISG,
  440.     E_OBJECT_REMOTE_VIEW,
  441.     E_OBJECT_REMOTE_DESTROY,
  442.     E_OBJECT_REMOTE_SETPOS,
  443.     E_OBJECT_REMOTE_SETROT,
  444.     E_OBJECT_REMOTE_ADDW,
  445.     E_OBJECT_REMOTE_REMW,
  446.     E_OBJECT_REMOTE_ADDP,
  447.     E_OBJECT_REMOTE_REMP,
  448.     E_OBJECT_REMOTE_ALLWA,
  449.     E_OBJECT_REMOTE_ALLWR,
  450.     E_OBJECT_REMOTE_ALLPA,
  451.     E_OBJECT_REMOTE_ALLPR,
  452.     E_OBJECT_REMOTE_ISVALID,
  453.     E_OBJECT_REMOTE_DETATCH,
  454.     E_OBJECT_REMOTE_ATTACHOO,
  455.     E_OBJECT_REMOTE_REMOO,
  456.     E_OBJECT_REMOTE_STOP,
  457.     E_OBJECT_REMOTE_GETROT,
  458.     E_OBJECT_REMOTE_GETPOS,
  459.     E_OBJECT_REMOTE_MOVETO,
  460.     E_OBJECT_REMOTE_CHECKDESC,
  461.     E_OBJECT_REMOTE_GET_AREA,
  462.     E_OBJECT_REMOTE_GATE = 0x40000000
  463. }
  464.  
  465. enum E_GATE_INFO
  466. {
  467.     E_GATE_INFO_OBJECT,
  468.     E_GATE_INFO_TIME,
  469.     E_GATE_INFO_TRIGGER,
  470.     E_GATE_INFO_XY,
  471.     E_GATE_INFO_ZA
  472. }
  473.  
  474. #if !defined MAX_GATE_OBJECTS
  475.     #define MAX_GATE_OBJECTS 32
  476. #endif
  477.  
  478. #if MAX_GATE_OBJECTS > 256
  479.     #if !defined EXTENDED_GATE_CODE
  480.         #define EXTENDED_GATE_CODE
  481.     #endif
  482. #endif
  483.  
  484. #if MAX_GATE_OBJECTS > 65536
  485.     #if !defined NO_GATE_AREA_LOOKUP
  486.         #error Only 65536 gates supported in lookup mode
  487.     #endif
  488. #endif
  489.  
  490. forward Object_Loop();
  491. #if defined _YSI_SETUP_MASTER
  492.     forward Object_GetLimit();
  493.     forward Object_AddRem(master, model, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz);
  494.     forward Object_Remote(ident, info, instruction);
  495.     forward Object_CoOrdRemote(ident, instruction, Float:f1, Float:f2, Float:f3, Float:f4);
  496.     forward Object_OnPlayerEnterArea(playerid, areaid);
  497.     forward Object_Broadcast(id, e_OBJ_FLAG:model, master, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, Float:view,
  498.                 Float:mx, Float:my, Float:mz, Float:ms, parent, siblings, children, Bit:worlds[], wCount, Bit:players[], pCount);
  499.     forward YSIM_Objects(command);
  500.     forward Object_UpdateUnused(obj);
  501.     #if !defined NO_OBJECTS_MOVE
  502.         forward Object_AttachRemote(objectid, playerid, Float:X, Float:Y, Float:Z, Float:RX, Float:RY, Float:RZ);
  503.     #endif
  504. #endif
  505. #if defined _YSI_VISUAL_AREAS
  506.     forward Object_GateClose(gate);
  507. #endif
  508.  
  509. static
  510.     Float:YSI_g_sXSectorLocations[OBJECT_SECTOR_X_EDGE + 1],
  511.     Float:YSI_g_sYSectorLocations[OBJECT_SECTOR_Y_EDGE + 1],
  512.     Float:YSI_g_sXSectorSize,
  513.     Float:YSI_g_sYSectorSize,
  514.     YSI_g_sObjectSectors[OBJECT_SECTOR_ARRAY][E_OBJ_SECTOR],
  515.     YSI_g_sObjects[MAX_DYN_OBJECTS][E_OBJECT],
  516.     YSI_g_sOtherSector = NO_OBJECT,
  517.     YSI_g_sMovingObjects = NO_OBJECT,
  518.     YSI_g_sLODObjects = NO_OBJECT,
  519.     YSI_g_sInteriorObjects = NO_OBJECT,
  520.     YSI_g_sPlayerObjects[MAX_PLAYERS][MAY_OBJECTS],
  521.     YSI_g_sSomethingMoved = NO_OBJECT,
  522.     #if defined _YSI_SETUP_MASTER
  523.         YSI_g_sIsMaster,
  524.     #endif
  525.     #if defined _YSI_VISUAL_AREAS
  526.         YSI_g_sGateInfo[MAX_GATE_OBJECTS][E_GATE_INFO],
  527.         #if !defined NO_GATE_AREA_LOOKUP
  528.             YSI_g_sGateAreas[ceildiv(MAX_AREAS, 2)],
  529.         #endif
  530.     #endif
  531.     YSI_g_sNoObjects;
  532.  
  533. /*----------------------------------------------------------------------------*-
  534. Function:
  535.     Object_IsValid
  536. Params:
  537.     objectid - Object to check
  538. Return:
  539.     -
  540. Notes:
  541.     Checks if a passed id is a valid object.
  542. -*----------------------------------------------------------------------------*/
  543.  
  544. #define Object_IsValid(%1) \
  545.     ((%1) >= 0 && (%1) < MAX_DYN_OBJECTS && YSI_g_sObjects[(%1)][E_OBJECT_MODEL] & e_OBJ_FLAG_ACTIVE)
  546.  
  547. /*----------------------------------------------------------------------------*-
  548. Function:
  549.     Object_GetAttach
  550. Params:
  551.     flags - Flags to check.
  552. Return:
  553.     Player the object is attached to.
  554. Notes:
  555.     Actually checks a set of passed flags, not a passed object.
  556. -*----------------------------------------------------------------------------*/
  557.  
  558. #define Object_GetAttach(%1) \
  559.     ((_:(%1) >> 15) & NO_ATTACH_PLAYER)
  560.  
  561. /*----------------------------------------------------------------------------*-
  562. Function:
  563.     Object_IsAttached
  564. Params:
  565.     flags - Flags to check.
  566. Return:
  567.     If the object is attached to a player.
  568. Notes:
  569.     Actually checks a set of passed flags, not a passed object.
  570. -*----------------------------------------------------------------------------*/
  571.  
  572. #define Object_IsAttached(%1) \
  573.     (Object_GetAttach(%1) != NO_ATTACH_PLAYER)
  574.  
  575. /*----------------------------------------------------------------------------*-
  576. Function:
  577.     Object_SetAttach
  578. Params:
  579.     flags - Flags to check.
  580. Return:
  581.     -
  582. Notes:
  583.     Actually checks a set of passed flags, not a passed object.
  584. -*----------------------------------------------------------------------------*/
  585.  
  586. #define Object_SetAttach(%1) \
  587.     e_OBJ_FLAG:(((%1) & NO_ATTACH_PLAYER) << 15)
  588.  
  589. #if defined _YSI_SETUP_MASTER
  590.  
  591.     /*----------------------------------------------------------------------------*-
  592.     Function:
  593.         Object_Remote
  594.     Params:
  595.         ident - Object to do code on.
  596.         info - Extra data for function.
  597.         instruction - Function to perform.
  598.     Return:
  599.         -
  600.     Notes:
  601.         Performs operations on objects remotely.
  602.     -*----------------------------------------------------------------------------*/
  603.  
  604.     public Object_Remote(ident, info, instruction)
  605.     {
  606.         setproperty(0, "YSIReq", 0);
  607.         if (!YSI_g_sIsMaster) return 0;
  608.         switch (instruction)
  609.         {
  610.             case E_OBJECT_REMOTE_VIEW:
  611.             {
  612.                 Object_SetViewDistance(ident, Float:info);
  613.             }
  614.             case E_OBJECT_REMOTE_DESTROY:
  615.             {
  616.                 if (Object_IsValid(ident)) Object_Destroy(ident);
  617.             }
  618.             case E_OBJECT_REMOTE_ADDW:
  619.             {
  620.                 if (Object_IsValid(ident)) Bit_Set(YSI_g_sObjects[ident][E_OBJECT_WORLDS], info, 1, OBJECT_WORLD_COUNT);
  621.             }
  622.             case E_OBJECT_REMOTE_REMW:
  623.             {
  624.                 if (Object_IsValid(ident)) Bit_Set(YSI_g_sObjects[ident][E_OBJECT_WORLDS], info, 0, OBJECT_WORLD_COUNT);
  625.             }
  626.             case E_OBJECT_REMOTE_ADDP:
  627.             {
  628.                 if (Object_IsValid(ident)) Bit_Set(YSI_g_sObjects[ident][E_OBJECT_PLAYERS], info, 1, PLAYER_BIT_ARRAY);
  629.             }
  630.             case E_OBJECT_REMOTE_REMP:
  631.             {
  632.                 if (Object_IsValid(ident)) Bit_Set(YSI_g_sObjects[ident][E_OBJECT_PLAYERS], info, 0, PLAYER_BIT_ARRAY);
  633.             }
  634.             case E_OBJECT_REMOTE_ALLWA:
  635.             {
  636.                 if (Object_IsValid(ident)) Bit_SetAll(YSI_g_sObjects[ident][E_OBJECT_WORLDS], 1, OBJECT_WORLD_COUNT);
  637.             }
  638.             case E_OBJECT_REMOTE_ALLWR:
  639.             {
  640.                 if (Object_IsValid(ident)) Bit_SetAll(YSI_g_sObjects[ident][E_OBJECT_WORLDS], 0, OBJECT_WORLD_COUNT);
  641.             }
  642.             case E_OBJECT_REMOTE_ALLPA:
  643.             {
  644.                 if (Object_IsValid(ident))
  645.                 {
  646.                     Bit_SetAll(YSI_g_sObjects[ident][E_OBJECT_PLAYERS], 1, PLAYER_BIT_ARRAY);
  647.                 }
  648.             }
  649.             case E_OBJECT_REMOTE_ALLPR:
  650.             {
  651.                 if (Object_IsValid(ident))
  652.                 {
  653.                     Bit_SetAll(YSI_g_sObjects[ident][E_OBJECT_PLAYERS], 0, PLAYER_BIT_ARRAY);
  654.                 }
  655.             }
  656.             case E_OBJECT_REMOTE_ISVALID:
  657.             {
  658.                 if (Object_IsValid(ident)) setproperty(0, "YSIReq", 1);
  659.             }
  660.             case E_OBJECT_REMOTE_DETATCH:
  661.             {
  662.                 DetachDynamicObjectFromPlayer(ident);
  663.             }
  664.             case E_OBJECT_REMOTE_ATTACHOO:
  665.             {
  666.                 AttachObjectToObject(ident, info);
  667.             }
  668.             case E_OBJECT_REMOTE_REMOO:
  669.             {
  670.                 RemoveObjectFromParent(ident);
  671.             }
  672.             case E_OBJECT_REMOTE_STOP:
  673.             {
  674.                 StopDynamicObject(ident);
  675.             }
  676.             case E_OBJECT_REMOTE_GETROT:
  677.             {
  678.                 if (!Object_IsValid(ident) || Object_IsAttached(YSI_g_sObjects[ident][E_OBJECT_MODEL]))
  679.                 {
  680.                     setproperty(0, "YSIReq", 0);
  681.                     setproperty(0, "YSIReq2", 0);
  682.                     setproperty(0, "YSIReq3", 0);
  683.                 }
  684.                 else
  685.                 {
  686.                     setproperty(0, "YSIReq", _:YSI_g_sObjects[ident][E_OBJECT_RX]);
  687.                     setproperty(0, "YSIReq2", _:YSI_g_sObjects[ident][E_OBJECT_RY]);
  688.                     setproperty(0, "YSIReq3", _:YSI_g_sObjects[ident][E_OBJECT_RZ]);
  689.                 }
  690.             }
  691.             case E_OBJECT_REMOTE_GETPOS:
  692.             {
  693.                 if (!Object_IsValid(ident))
  694.                 {
  695.                     setproperty(0, "YSIReq", 0);
  696.                     setproperty(0, "YSIReq2", 0);
  697.                     setproperty(0, "YSIReq3", 0);
  698.                 }
  699.                 else
  700.                 {
  701.                     new
  702.                         Float:x,
  703.                         Float:y,
  704.                         Float:z;
  705.                     Object_GetPos(ident, x, y, z);
  706.                     setproperty(0, "YSIReq", _:x);
  707.                     setproperty(0, "YSIReq2", _:y);
  708.                     setproperty(0, "YSIReq3", _:z);
  709.                 }
  710.             }
  711.             case E_OBJECT_REMOTE_CHECKDESC:
  712.             {
  713.                 if (Object_CheckDescendant(ident, info)) setproperty(0, "YSIReq", 1);
  714.             }
  715.             case E_OBJECT_REMOTE_GET_AREA:
  716.             {
  717.                 if (ident >= 0 && ident < MAX_GATE_OBJECTS)
  718.                 {
  719.                     setproperty(0, "YSIReq", YSI_g_sGateInfo[ident][E_GATE_INFO_TRIGGER]);
  720.                 }
  721.             }
  722.         }
  723.         return 1;
  724.     }
  725.    
  726.     /*----------------------------------------------------------------------------*-
  727.     Function:
  728.         YSIM_Objects
  729.     Params:
  730.         command - Instruction from the master system.
  731.     Return:
  732.         -
  733.     Notes:
  734.         Performs instructions on script start/end.
  735.     -*----------------------------------------------------------------------------*/
  736.  
  737.     public YSIM_Objects(command)
  738.     {
  739.         #if OBJECT_WORLDS <= 0 || defined NO_PERSONAL_OBJECTS
  740.             static
  741.                 sFake[2] = {-1, -1};
  742.         #endif
  743.         switch (command & 0xFF000000)
  744.         {
  745.             case E_MASTER_SET_MASTER:
  746.             {
  747.                 YSI_g_sIsMaster = 1;
  748.             }
  749.             case E_MASTER_RELINQUISH:
  750.             {
  751.                 new
  752.                     master = (command & 0x00FFFFFF);
  753.                 if (master == YSI_gMasterID)
  754.                 {
  755.                     CallRemoteFunction("Object_GetLimit", "");
  756.                     new
  757.                         parent = NO_OBJECT,
  758.                         siblings = NO_OBJECT,
  759.                         children = NO_OBJECT,
  760.                         Float:mx,
  761.                         Float:my,
  762.                         Float:mz,
  763.                         Float:ms,
  764.                         maxObjs = getproperty(0, "YSIReq"),
  765.                         i;
  766.                     for ( ; i < MAX_DYN_OBJECTS && i < maxObjs; i++)
  767.                     {
  768.                         if (YSI_g_sObjects[i][E_OBJECT_MODEL] & e_OBJ_FLAG_ACTIVE)
  769.                         {
  770.                             if (YSI_g_sObjects[i][E_OBJECT_SCRIPT] == master)
  771.                             {
  772.                                 Object_Destroy(i, 0);
  773.                             }
  774.                             else
  775.                             {
  776.                                 #if !defined NO_OBJECT_ATTACH
  777.                                     parent = YSI_g_sObjects[i][E_OBJECT_PARENT];
  778.                                     while (parent != NO_OBJECT && (YSI_g_sObjects[parent][E_OBJECT_SCRIPT] == master || parent > maxObjs))
  779.                                     {
  780.                                         Object_Destroy(parent, 0);
  781.                                         parent = YSI_g_sObjects[i][E_OBJECT_PARENT];
  782.                                     }
  783.                                     siblings = YSI_g_sObjects[i][E_OBJECT_SIBLINGS];
  784.                                     while (siblings != NO_OBJECT && (YSI_g_sObjects[siblings][E_OBJECT_SCRIPT] == master || siblings > maxObjs))
  785.                                     {
  786.                                         Object_Destroy(siblings, 0);
  787.                                         siblings = YSI_g_sObjects[i][E_OBJECT_SIBLINGS];
  788.                                     }
  789.                                     children = YSI_g_sObjects[i][E_OBJECT_CHILDREN];
  790.                                     while (children != NO_OBJECT && (YSI_g_sObjects[children][E_OBJECT_SCRIPT] == master || children > maxObjs))
  791.                                     {
  792.                                         Object_Destroy(children, 0);
  793.                                         children = YSI_g_sObjects[i][E_OBJECT_CHILDREN];
  794.                                     }
  795.                                 #endif
  796.                                 #if !defined NO_OBJECTS_MOVE
  797.                                     mx = YSI_g_sObjects[i][E_OBJECT_MX];
  798.                                     my = YSI_g_sObjects[i][E_OBJECT_MY];
  799.                                     mz = YSI_g_sObjects[i][E_OBJECT_MZ];
  800.                                     ms = YSI_g_sObjects[i][E_OBJECT_MS];
  801.                                 #endif
  802.                                 #if OBJECT_WORLDS > 0
  803.                                     #if !defined NO_PERSONAL_OBJECTS
  804.                                         CallRemoteFunction("Object_Broadcast", "iiifffffffffffiiiaiai", i,
  805.                                             _:YSI_g_sObjects[i][E_OBJECT_MODEL],
  806.                                             YSI_g_sObjects[i][E_OBJECT_SCRIPT],
  807.                                             YSI_g_sObjects[i][E_OBJECT_X],
  808.                                             YSI_g_sObjects[i][E_OBJECT_Y],
  809.                                             YSI_g_sObjects[i][E_OBJECT_Z],
  810.                                             YSI_g_sObjects[i][E_OBJECT_RX],
  811.                                             YSI_g_sObjects[i][E_OBJECT_RY],
  812.                                             YSI_g_sObjects[i][E_OBJECT_RZ],
  813.                                             YSI_g_sObjects[i][E_OBJECT_VIEW],
  814.                                             mx, my, mz, ms,
  815.                                             parent, siblings, children,
  816.                                             _:YSI_g_sObjects[i][E_OBJECT_WORLDS], OBJECT_WORLD_COUNT,
  817.                                             _:YSI_g_sObjects[i][E_OBJECT_PLAYERS], PLAYER_BIT_ARRAY
  818.                                         );
  819.                                     #else
  820.                                         CallRemoteFunction("Object_Broadcast", "iiifffffffffffiiiaiai", i,
  821.                                             _:YSI_g_sObjects[i][E_OBJECT_MODEL],
  822.                                             YSI_g_sObjects[i][E_OBJECT_SCRIPT],
  823.                                             YSI_g_sObjects[i][E_OBJECT_X],
  824.                                             YSI_g_sObjects[i][E_OBJECT_Y],
  825.                                             YSI_g_sObjects[i][E_OBJECT_Z],
  826.                                             YSI_g_sObjects[i][E_OBJECT_RX],
  827.                                             YSI_g_sObjects[i][E_OBJECT_RY],
  828.                                             YSI_g_sObjects[i][E_OBJECT_RZ],
  829.                                             YSI_g_sObjects[i][E_OBJECT_VIEW],
  830.                                             mx, my, mz, ms,
  831.                                             parent, siblings, children,
  832.                                             _:YSI_g_sObjects[i][E_OBJECT_WORLDS], OBJECT_WORLD_COUNT,
  833.                                             sFake, 2
  834.                                         );
  835.                                     #endif
  836.                                 #else
  837.                                     #if !defined NO_PERSONAL_OBJECTS
  838.                                         CallRemoteFunction("Object_Broadcast", "iiifffffffffffiiiaiai", i,
  839.                                             _:YSI_g_sObjects[i][E_OBJECT_MODEL],
  840.                                             YSI_g_sObjects[i][E_OBJECT_SCRIPT],
  841.                                             YSI_g_sObjects[i][E_OBJECT_X],
  842.                                             YSI_g_sObjects[i][E_OBJECT_Y],
  843.                                             YSI_g_sObjects[i][E_OBJECT_Z],
  844.                                             YSI_g_sObjects[i][E_OBJECT_RX],
  845.                                             YSI_g_sObjects[i][E_OBJECT_RY],
  846.                                             YSI_g_sObjects[i][E_OBJECT_RZ],
  847.                                             YSI_g_sObjects[i][E_OBJECT_VIEW],
  848.                                             mx, my, mz, ms,
  849.                                             parent, siblings, children,
  850.                                             sFake, 2,
  851.                                             _:YSI_g_sObjects[i][E_OBJECT_PLAYERS], PLAYER_BIT_ARRAY
  852.                                         );
  853.                                     #else
  854.                                         CallRemoteFunction("Object_Broadcast", "iiifffffffffffiiiaiai", i,
  855.                                             _:YSI_g_sObjects[i][E_OBJECT_MODEL],
  856.                                             YSI_g_sObjects[i][E_OBJECT_SCRIPT],
  857.                                             YSI_g_sObjects[i][E_OBJECT_X],
  858.                                             YSI_g_sObjects[i][E_OBJECT_Y],
  859.                                             YSI_g_sObjects[i][E_OBJECT_Z],
  860.                                             YSI_g_sObjects[i][E_OBJECT_RX],
  861.                                             YSI_g_sObjects[i][E_OBJECT_RY],
  862.                                             YSI_g_sObjects[i][E_OBJECT_RZ],
  863.                                             YSI_g_sObjects[i][E_OBJECT_VIEW],
  864.                                             mx, my, mz, ms,
  865.                                             parent, siblings, children,
  866.                                             sFake, 2,
  867.                                             sFake, 2
  868.                                         );
  869.                                     #endif
  870.                                 #endif
  871.                                 continue;
  872.                             }
  873.                         }
  874.                         CallRemoteFunction("Object_UpdateUnused", "i", i);
  875.                     }
  876.                     while (i < maxObjs)
  877.                     {
  878.                         CallRemoteFunction("Object_UpdateUnused", "i", i);
  879.                         i++;
  880.                     }
  881.                     foreach (Player, playerid)
  882.                     {
  883.                         for (new obj = 1; obj <= MAY_OBJECTS; obj++)
  884.                         {
  885.                             if (IsValidPlayerObject(playerid, obj))
  886.                             {
  887.                                 DestroyPlayerObject(playerid, obj);
  888.                                 break;
  889.                             }
  890.                         }
  891.                     }
  892.                 }
  893.                 else
  894.                 {
  895.                     for (new i = 0; i < MAX_DYN_OBJECTS; i++)
  896.                     {
  897.                         if (YSI_g_sObjects[i][E_OBJECT_MODEL] & e_OBJ_FLAG_ACTIVE && YSI_g_sObjects[i][E_OBJECT_SCRIPT] == master)
  898.                         {
  899.                             Object_Destroy(i);
  900.                         }
  901.                     }
  902.                 }
  903.             }
  904.             case E_MASTER_NOT_MASTER:
  905.             {
  906.                 YSI_g_sIsMaster = 0;
  907.             }
  908.         }
  909.     }
  910.    
  911.     /*----------------------------------------------------------------------------*-
  912.     Function:
  913.         Object_GetLimit
  914.     Params:
  915.         -
  916.     Return:
  917.         -
  918.     Notes:
  919.         Sets up the new master for streaming and gets the number of objects it
  920.         can handle.
  921.     -*----------------------------------------------------------------------------*/
  922.  
  923.     public Object_GetLimit()
  924.     {
  925.         if (!YSI_g_sIsMaster) return;
  926.         setproperty(0, "YSIReq", MAX_DYN_OBJECTS);
  927.         YSI_g_sNoObjects = NO_OBJECT;
  928.     }
  929.    
  930.     /*----------------------------------------------------------------------------*-
  931.     Function:
  932.         Object_Broadcast
  933.     Params:
  934.         id - Slot of the object.
  935.         e_OBJ_FLAG:model - Object model data and flags.
  936.         master - Script which owns the object.
  937.         Float:x - X position.
  938.         Float:y - Y position.
  939.         Float:z - Z position.
  940.         Float:rx - X rotation.
  941.         Float:ry - Y rotation.
  942.         Float:rz - Z rotation.
  943.         Float:view - Object view distance.
  944.         Float:mx - Movement x target.
  945.         Float:my - Movement y target.
  946.         Float:mz - Movement z target.
  947.         Float:ms - Movement speed.
  948.         parent - Object attachment parent.
  949.         siblings - Object attachment sibling list.
  950.         children - Object attachment children list.
  951.         Bit:worlds[] - Worlds the object is in.
  952.         wCount - Size of the world array.
  953.         Bit:players[] - Players who can see the object.
  954.         pCount - Size of the players array.
  955.     Return:
  956.         -
  957.     Notes:
  958.         Recieves data sent from the old master to the new master and stores it in
  959.         the object data array.
  960.     -*----------------------------------------------------------------------------*/
  961.  
  962.     public Object_Broadcast(id, e_OBJ_FLAG:model, master, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, Float:view,
  963.                 Float:mx, Float:my, Float:mz, Float:ms, parent, siblings, children, Bit:worlds[], wCount, Bit:players[], pCount)
  964.     {
  965.         if (!YSI_g_sIsMaster) return 0;
  966.         #if !defined NO_OBJECT_ATTACH
  967.             YSI_g_sObjects[id][E_OBJECT_PARENT] = parent;
  968.             YSI_g_sObjects[id][E_OBJECT_SIBLINGS] = siblings;
  969.             YSI_g_sObjects[id][E_OBJECT_CHILDREN] = children;
  970.         #else
  971.             #pragma unused parent, siblings, children
  972.         #endif
  973.         #if !defined NO_OBJECTS_MOVE
  974.             YSI_g_sObjects[id][E_OBJECT_MX] = mx;
  975.             YSI_g_sObjects[id][E_OBJECT_MY] = my;
  976.             YSI_g_sObjects[id][E_OBJECT_MZ] = mz;
  977.             YSI_g_sObjects[id][E_OBJECT_MS] = ms;
  978.         #else
  979.             #pragma unused mx, my, mz, ms
  980.         #endif
  981.         YSI_g_sObjects[id][E_OBJECT_MODEL] = model | e_OBJ_FLAG_RECREATED;
  982.         YSI_g_sObjects[id][E_OBJECT_SCRIPT] = master;
  983.         YSI_g_sObjects[id][E_OBJECT_X] = x;
  984.         YSI_g_sObjects[id][E_OBJECT_Y] = y;
  985.         YSI_g_sObjects[id][E_OBJECT_Z] = z;
  986.         YSI_g_sObjects[id][E_OBJECT_RX] = rx;
  987.         YSI_g_sObjects[id][E_OBJECT_RY] = ry;
  988.         YSI_g_sObjects[id][E_OBJECT_RZ] = rz;
  989.         YSI_g_sObjects[id][E_OBJECT_VIEW] = view;
  990.         #if OBJECT_WORLDS > 0
  991.             for (new i = 0; i < wCount && i < Bit_Bits(OBJECT_WORLDS); i++)
  992.             {
  993.                 YSI_g_sObjects[id][E_OBJECT_WORLDS][i] = worlds[i];
  994.             }
  995.         #else
  996.             #pragma unused worlds, wCount
  997.         #endif
  998.         #if !defined NO_PERSONAL_OBJECTS
  999.             for (new i = 0; i < pCount && i < PLAYER_BIT_ARRAY; i++)
  1000.             {
  1001.                 YSI_g_sObjects[id][E_OBJECT_PLAYERS][i] = players[i];
  1002.             }
  1003.         #else
  1004.             #pragma unused players, pCount
  1005.         #endif
  1006.         YSI_g_sObjects[id][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  1007.         YSI_g_sSomethingMoved = id;
  1008.         Object_AddToSector(Object_FindSector(x, y, z), id, view);
  1009.         return 1;
  1010.     }
  1011.    
  1012.     /*----------------------------------------------------------------------------*-
  1013.     Function:
  1014.         Object_UpdateUnused
  1015.     Params:
  1016.         obj - Object to add to the remote unused list.
  1017.     Return:
  1018.         -
  1019.     Notes:
  1020.         -
  1021.     -*----------------------------------------------------------------------------*/
  1022.    
  1023.     public Object_UpdateUnused(obj)
  1024.     {
  1025.         YSI_g_sObjects[obj][E_OBJECT_NEXT] = YSI_g_sNoObjects;
  1026.         YSI_g_sNoObjects = obj;
  1027.     }
  1028.  
  1029.     /*----------------------------------------------------------------------------*-
  1030.     Function:
  1031.         Object_CoOrdRemote
  1032.     Params:
  1033.         ident - Object to do code on.
  1034.         instruction - Function to perform.
  1035.         Float:f1 - First float data.
  1036.         Float:f2 - Second float data.
  1037.         Float:f3 - Third float data.
  1038.         Float:f4 - Fourth float data.
  1039.     Return:
  1040.         -
  1041.     Notes:
  1042.         Performs operations with locations on objects remotely.
  1043.     -*----------------------------------------------------------------------------*/
  1044.  
  1045.     public Object_CoOrdRemote(ident, instruction, Float:f1, Float:f2, Float:f3, Float:f4)
  1046.     {
  1047.         setproperty(0, "YSIReq", 0);
  1048.         if (!YSI_g_sIsMaster) return 0;
  1049.         switch (instruction)
  1050.         {
  1051.             case E_OBJECT_REMOTE_SETROT:
  1052.             {
  1053.                 if (!Object_IsValid(ident) || Object_IsAttached(YSI_g_sObjects[ident][E_OBJECT_MODEL])) return 0;
  1054.                 YSI_g_sObjects[ident][E_OBJECT_RX] = f1;
  1055.                 YSI_g_sObjects[ident][E_OBJECT_RY] = f2;
  1056.                 YSI_g_sObjects[ident][E_OBJECT_RZ] = f3;
  1057.                 YSI_g_sObjects[ident][E_OBJECT_MODEL] |= e_OBJ_FLAG_ROTATED;
  1058.                 YSI_g_sObjects[ident][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  1059.                 YSI_g_sSomethingMoved = ident;
  1060.                 setproperty(0, "YSIReq", 1);
  1061.                 return 1;
  1062.             }
  1063.             case E_OBJECT_REMOTE_SETPOS:
  1064.             {
  1065.                 if (!Object_IsValid(ident) || Object_IsAttached(YSI_g_sObjects[ident][E_OBJECT_MODEL])) return 0;
  1066.                 #if !defined NO_OBJECT_ATTACH
  1067.                     Object_UpdateChildSectors(YSI_g_sObjects[ident][E_OBJECT_CHILDREN], f1, f2, f3);
  1068.                 #endif
  1069.                 setproperty(0, "YSIReq", Object_SetPos(ident, f1, f2, f3));
  1070.             }
  1071.             case E_OBJECT_REMOTE_MOVETO:
  1072.             {
  1073.                 if (Object_IsValid(ident))
  1074.                 {
  1075.                     Object_Move(ident, f1, f2, f3, f4);
  1076.                     YSI_g_sObjects[ident][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  1077.                     YSI_g_sSomethingMoved = ident;
  1078.                     setproperty(0, "YSIReq", 1);
  1079.                     return 1;
  1080.                 }
  1081.             }
  1082.         }
  1083.         return 0;
  1084.     }
  1085. #endif
  1086.  
  1087. /*----------------------------------------------------------------------------*-
  1088. Function:
  1089.     Object_SetViewDistance
  1090. Params:
  1091.     objectid - Object to set custom view distance for.
  1092.     Float:view - Distance the object can be seen from.
  1093. Return:
  1094.     -
  1095. Notes:
  1096.     Sets how far away an object can be seen from.
  1097. -*----------------------------------------------------------------------------*/
  1098.  
  1099. stock Object_SetViewDistance(objectid, Float:view)
  1100. {
  1101.     #if defined _YSI_SETUP_MASTER
  1102.         if (YSI_g_sIsMaster)
  1103.         {
  1104.     #endif
  1105.             if (Object_IsValid(objectid))
  1106.             {
  1107.                 view *= view;
  1108.                 YSI_g_sObjects[objectid][E_OBJECT_VIEW] = view;
  1109.                 new
  1110.                     sector = YSI_g_sObjects[objectid][E_OBJECT_SECTOR];
  1111.                 if (view > OBJECT_MAX_VIEW_DISTANCE)
  1112.                 {
  1113.                     if (sector != OBJECT_LOD_SECTOR)
  1114.                     {
  1115.                         Object_RemoveFromSector(sector, objectid);
  1116.                         Object_AddToLOD(objectid);
  1117.                     }
  1118.                 }
  1119.                 else if (sector == OBJECT_LOD_SECTOR)
  1120.                 {
  1121.                     Object_RemoveFromSector(sector, objectid);
  1122.                     Object_AddToSector(Object_FindSector(YSI_g_sObjects[objectid][E_OBJECT_X], YSI_g_sObjects[objectid][E_OBJECT_Y], YSI_g_sObjects[objectid][E_OBJECT_Z]), objectid, view);
  1123.                 }
  1124.                 else if (sector < sizeof (YSI_g_sObjectSectors))
  1125.                 {
  1126.                     if (YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_MAX_VIEW] < view) YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_MAX_VIEW] = view;
  1127.                 }
  1128.                 return 1;
  1129.             }
  1130.             return 0;
  1131.     #if defined _YSI_SETUP_MASTER
  1132.         }
  1133.         else
  1134.         {
  1135.             return CallRemoteFunction("Object_Remote", "iii", objectid, _:view, E_OBJECT_REMOTE_VIEW);
  1136.         }
  1137.     #endif
  1138. }
  1139.  
  1140. /*----------------------------------------------------------------------------*-
  1141. Function:
  1142.     Object_Object
  1143. Params:
  1144.     -
  1145. Return:
  1146.     -
  1147. Notes:
  1148.     Sets up variables for initial use.
  1149. -*----------------------------------------------------------------------------*/
  1150.  
  1151. Object_Object()
  1152. {
  1153.     static
  1154.         timer;
  1155.     if (!timer)
  1156.     {
  1157.         #if defined _YSI_SETUP_MASTER
  1158.             YSI_g_sIsMaster = Master_Add("YSIM_Objects");
  1159.         #endif
  1160.         YSI_g_sNoObjects = 0;
  1161.         new
  1162.             i;
  1163.        
  1164.         while (i < MAX_DYN_OBJECTS) YSI_g_sObjects[i++][E_OBJECT_NEXT] = i;
  1165.         YSI_g_sObjects[MAX_DYN_OBJECTS - 1][E_OBJECT_NEXT] = NO_OBJECT;
  1166.        
  1167.         for (i = 0; i < OBJECT_SECTOR_ARRAY; i++)
  1168.         {
  1169.             YSI_g_sObjectSectors[i][E_OBJ_SECTOR_POINTER] = NO_OBJECT;
  1170.             YSI_g_sObjectSectors[i][E_OBJ_SECTOR_MAX_VIEW] = OBJECT_SIGHT;
  1171.         }
  1172.        
  1173.         YSI_g_sXSectorLocations[0] = OBJECT_BOUNDS_MINX;
  1174.         for (i = 1; i < OBJECT_SECTOR_X_EDGE; i++)
  1175.         {
  1176.             YSI_g_sXSectorLocations[i] = (float(OBJECT_BOUNDS_X_SIZE * i) / OBJECT_SECTOR_X_EDGE) + OBJECT_BOUNDS_MINX;
  1177.         }
  1178.         YSI_g_sXSectorLocations[OBJECT_SECTOR_X_EDGE] = OBJECT_BOUNDS_MAXX;
  1179.         YSI_g_sXSectorSize = (YSI_g_sXSectorLocations[1] - YSI_g_sXSectorLocations[0]);
  1180.        
  1181.         YSI_g_sYSectorLocations[0] = OBJECT_BOUNDS_MINY;
  1182.         for (i = 1; i < OBJECT_SECTOR_Y_EDGE; i++)
  1183.         {
  1184.             YSI_g_sYSectorLocations[i] = (float(OBJECT_BOUNDS_Y_SIZE * i) / OBJECT_SECTOR_Y_EDGE) + OBJECT_BOUNDS_MINY;
  1185.         }
  1186.         YSI_g_sYSectorLocations[OBJECT_SECTOR_Y_EDGE] = OBJECT_BOUNDS_MAXY;
  1187.         YSI_g_sYSectorSize = (YSI_g_sYSectorLocations[1] - YSI_g_sYSectorLocations[0]);
  1188.  
  1189.         #if defined _YSI_VISUAL_AREAS
  1190.             #if defined NO_GATE_AREA_LOOKUP
  1191.                 for (i = 0; i < MAX_GATE_OBJECTS; i++)
  1192.                 {
  1193.                     YSI_g_sGateInfo[i][E_GATE_INFO_TRIGGER] = NO_GATE;
  1194.                 }
  1195.             #else
  1196.                 for (i = 0; i < sizeof (YSI_g_sGateAreas); i++)
  1197.                 {
  1198.                     YSI_g_sGateAreas[i] = NO_GATE;
  1199.                 }
  1200.             #endif
  1201.         #endif
  1202.         for (i = 0; i < MAX_PLAYERS; i++)
  1203.         {
  1204.             for (new j = 0; j < MAY_OBJECTS; j++)
  1205.             {
  1206.                 YSI_g_sPlayerObjects[i][j] = NO_OBJECT;
  1207.             }
  1208.         }
  1209.         timer = Timer_Add("Object_Loop", OBJECT_LOOP_GRANULARITY);
  1210.     }
  1211.     return 1;
  1212. }
  1213.  
  1214. /*----------------------------------------------------------------------------*-
  1215. Function:
  1216.     CreateDynamicObject
  1217. Params:
  1218.     model - Model of object.
  1219.     Float:X - x position.
  1220.     Float:Y - y position.
  1221.     Float:Z - z position.
  1222.     Float:RX - x rotation.
  1223.     Float:RY - y rotation.
  1224.     Float:RZ - z rotation.
  1225. Return:
  1226.     -
  1227. Notes:
  1228.     Dynamic wrapper for CreateObject.
  1229. -*----------------------------------------------------------------------------*/
  1230.  
  1231. stock CreateDynamicObject(model, Float:X, Float:Y, Float:Z, Float:RX = 0.0, Float:RY = 0.0, Float:RZ = 0.0)
  1232. {
  1233.     new
  1234.         object = Object_Add(model, X, Y, Z, RX, RY, RZ);
  1235.     if (object != NO_OBJECT)
  1236.     {
  1237.         Object_AddToAllWorlds(object);
  1238.         Object_AddToAllPlayers(object);
  1239.     }
  1240.     return object;
  1241. }
  1242.  
  1243. /*----------------------------------------------------------------------------*-
  1244. Function:
  1245.     CreatePlayerDynamicObject
  1246. Params:
  1247.     playerid - Player to create it for.
  1248.     model - Model of object.
  1249.     Float:X - x position.
  1250.     Float:Y - y position.
  1251.     Float:Z - z position.
  1252.     Float:RX - x rotation.
  1253.     Float:RY - y rotation.
  1254.     Float:RZ - z rotation.
  1255. Return:
  1256.     -
  1257. Notes:
  1258.     Dynamic wrapper for CreatePlayerObject.
  1259. -*----------------------------------------------------------------------------*/
  1260.  
  1261. stock CreatePlayerDynamicObject(playerid, model, Float:X, Float:Y, Float:Z, Float:RX = 0.0, Float:RY = 0.0, Float:RZ = 0.0)
  1262. {
  1263.     new
  1264.         object;
  1265.     #if !defined NO_PLAYER_ONLY
  1266.         object = Object_Add(model, X, Y, Z, RX, RY, RZ);
  1267.         if (object != NO_OBJECT)
  1268.         {
  1269.             Object_RemoveFromAllPlayers(object);
  1270.             Object_AddToPlayer(object, playerid);
  1271.             Object_AddToAllWorlds(object);
  1272.         }
  1273.     #else
  1274.         #pragma unused playerid
  1275.         object = CreateDynamicObject(model, X, Y, Z, RX, RY, RZ);
  1276.     #endif
  1277.     return object;
  1278. }
  1279.  
  1280. /*----------------------------------------------------------------------------*-
  1281. Function:
  1282.     CreateVWDynamicObject
  1283. Params:
  1284.     virtualworld - World to create it in.
  1285.     model - Model of object.
  1286.     Float:X - x position.
  1287.     Float:Y - y position.
  1288.     Float:Z - z position.
  1289.     Float:RX - x rotation.
  1290.     Float:RY - y rotation.
  1291.     Float:RZ - z rotation.
  1292. Return:
  1293.     -
  1294. Notes:
  1295.     Dynamic wrapper for CreateObject with VW support.
  1296. -*----------------------------------------------------------------------------*/
  1297.  
  1298. stock CreateVWDynamicObject(virtualworld, model, Float:X, Float:Y, Float:Z, Float:RX = 0.0, Float:RY = 0.0, Float:RZ = 0.0)
  1299. {
  1300.     new
  1301.         object;
  1302.     #if OBJECT_WORLDS > 0
  1303.         object = Object_Add(model, X, Y, Z, RX, RY, RZ);
  1304.         if (object != NO_OBJECT)
  1305.         {
  1306.             Object_RemoveFromAllWorlds(object);
  1307.             Object_AddToWorld(object, virtualworld);
  1308.             Object_AddToAllPlayers(object);
  1309.         }
  1310.     #else
  1311.         #pragma unused virtualworld
  1312.         object = CreateDynamicObject(model, X, Y, Z, RX, RY, RZ);
  1313.     #endif
  1314.     return object;
  1315. }
  1316.  
  1317. /*----------------------------------------------------------------------------*-
  1318. Function:
  1319.     CreatePlayerVWDynamicObject
  1320. Params:
  1321.     playerid 0 Player to create it for.
  1322.     virtualworld - World to create it in.
  1323.     model - Model of object.
  1324.     Float:X - x position.
  1325.     Float:Y - y position.
  1326.     Float:Z - z position.
  1327.     Float:RX - x rotation.
  1328.     Float:RY - y rotation.
  1329.     Float:RZ - z rotation.
  1330. Return:
  1331.     -
  1332. Notes:
  1333.     Dynamic wrapper for CreatePlayerObject with VW support.
  1334. -*----------------------------------------------------------------------------*/
  1335.  
  1336. stock CreatePlayerVWDynamicObject(playerid, virtualworld, model, Float:X, Float:Y, Float:Z, Float:RX = 0.0, Float:RY = 0.0, Float:RZ = 0.0)
  1337. {
  1338.     new
  1339.         object;
  1340.     #if !defined NO_PLAYER_ONLY
  1341.         #if OBJECT_WORLDS > 0
  1342.             object = Object_Add(model, X, Y, Z, RX, RY, RZ);
  1343.             if (object != NO_OBJECT)
  1344.             {
  1345.                 Object_AddToWorld(object, virtualworld);
  1346.                 Object_AddToPlayer(object, playerid);
  1347.             }
  1348.         #else
  1349.             object = CreatePlayerDynamicObject(playerid, model, X, Y, Z, RX, RY, RZ);
  1350.             #pragma unused virtualworld
  1351.         #endif
  1352.     #else
  1353.         #if OBJECT_WORLDS > 0
  1354.             object = CreateVWDynamicObject(virtualworld, model, X, Y, Z, RX, RY, RZ);
  1355.             #pragma unused playerid
  1356.         #else
  1357.             object = CreateDynamicObject(model, X, Y, Z, RX, RY, RZ);
  1358.             #pragma unused playerid, virtualworld
  1359.         #endif
  1360.     #endif
  1361.     return object;
  1362. }
  1363.  
  1364. /*----------------------------------------------------------------------------*-
  1365. Function:
  1366.     Object_Add
  1367. Params:
  1368.     model - The object model.
  1369.     Float:x - X position.
  1370.     Float:y - Y position.
  1371.     Float:z - Z position.
  1372.     Float:rx - X rotation.
  1373.     Float:ry - Y rotation.
  1374.     Float:rz - Z rotation.
  1375. Return:
  1376.     -
  1377. Notes:
  1378.     Internal object addition function.  Checks if there are any slots open
  1379.     and adds the object to the list if there are.  Sets up initial flags and
  1380.     stores the position.
  1381. -*----------------------------------------------------------------------------*/
  1382.  
  1383. static stock Object_Add(model, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz)
  1384. {
  1385. #if defined _YSI_SETUP_MASTER
  1386.         if (!Object_IsValidModel(model)) return NO_OBJECT;
  1387.         if (!YSI_g_sIsMaster)
  1388.         {
  1389.             CallRemoteFunction("Object_AddRem", "iiffffff", YSI_gMasterID, model, x, y, z, rx, ry, rz);
  1390.             return getproperty(0, "YSIReq");
  1391.         }
  1392.         else
  1393.         {
  1394.             return Object_AddRem(YSI_gMasterID, model, x, y, z, rx, ry, rz);
  1395.         }
  1396.     }
  1397.    
  1398. /*----------------------------------------------------------------------------*-
  1399. Function:
  1400.     Object_AddRem
  1401. Params:
  1402.     master - The script which owns the object being made.
  1403.     model - The object model.
  1404.     Float:x - X position.
  1405.     Float:y - Y position.
  1406.     Float:z - Z position.
  1407.     Float:rx - X rotation.
  1408.     Float:ry - Y rotation.
  1409.     Float:rz - Z rotation.
  1410. Return:
  1411.     -
  1412. Notes:
  1413.     Remote wrapper for Object_Add.
  1414. -*----------------------------------------------------------------------------*/
  1415.  
  1416.     public Object_AddRem(master, model, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz)
  1417.     {
  1418.         if (!YSI_g_sIsMaster) return NO_OBJECT;
  1419.         setproperty(0, "YSIReq", NO_OBJECT);
  1420. #endif
  1421.     model &= _:e_OBJ_FLAG_MODEL;
  1422.     if (YSI_g_sNoObjects == NO_OBJECT) return NO_OBJECT;
  1423. #if !defined _YSI_SETUP_MASTER
  1424.         if (!Object_IsValidModel(model)) return NO_OBJECT;
  1425. #endif
  1426.     new
  1427.         pointer = YSI_g_sNoObjects;
  1428.     YSI_g_sNoObjects = YSI_g_sObjects[pointer][E_OBJECT_NEXT];
  1429.     #if defined _YSI_SETUP_MASTER
  1430.         YSI_g_sObjects[pointer][E_OBJECT_SCRIPT] = master;
  1431.     #endif
  1432.     YSI_g_sObjects[pointer][E_OBJECT_MODEL] = e_OBJ_FLAG:model | e_OBJ_FLAG_ACTIVE | e_OBJ_FLAG_RECREATED | Object_SetAttach(NO_ATTACH_PLAYER);
  1433.     YSI_g_sObjects[pointer][E_OBJECT_X] = x;
  1434.     YSI_g_sObjects[pointer][E_OBJECT_Y] = y;
  1435.     YSI_g_sObjects[pointer][E_OBJECT_Z] = z;
  1436.     YSI_g_sObjects[pointer][E_OBJECT_RX] = rx;
  1437.     YSI_g_sObjects[pointer][E_OBJECT_RY] = ry;
  1438.     YSI_g_sObjects[pointer][E_OBJECT_RZ] = rz;
  1439.     YSI_g_sObjects[pointer][E_OBJECT_VIEW] = OBJECT_SIGHT;
  1440.     #if !defined NO_OBJECT_ATTACH
  1441.         YSI_g_sObjects[pointer][E_OBJECT_PARENT] = NO_OBJECT;
  1442.         YSI_g_sObjects[pointer][E_OBJECT_SIBLINGS] = NO_OBJECT;
  1443.         YSI_g_sObjects[pointer][E_OBJECT_CHILDREN] = NO_OBJECT;
  1444.     #endif
  1445.     YSI_g_sObjects[pointer][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  1446.     YSI_g_sSomethingMoved = pointer;
  1447.     Object_AddToSector(Object_FindSector(x, y, z), pointer, OBJECT_SIGHT);
  1448. #if defined _YSI_SETUP_MASTER
  1449.         setproperty(0, "YSIReq", pointer);
  1450. #endif
  1451.     return pointer;
  1452. }
  1453.  
  1454. /*----------------------------------------------------------------------------*-
  1455. Function:
  1456.     Object_FindSector
  1457. Params:
  1458.     Float:x - X point.
  1459.     Float:y - Y point.
  1460.     Float:z - Z point.
  1461. Return:
  1462.     Point's sector.
  1463. Notes:
  1464.     Finds the sector of a point.
  1465. -*----------------------------------------------------------------------------*/
  1466.  
  1467. static stock Object_FindSector(Float:x, Float:y, Float:z)
  1468. {
  1469.     if (z > 800.0) return OBJECT_INT_SECTOR;
  1470.     if (x < OBJECT_BOUNDS_MINX || x >= OBJECT_BOUNDS_MAXX || y < OBJECT_BOUNDS_MINY || y >= OBJECT_BOUNDS_MAXY) return OBJECT_NO_SECTOR;
  1471.     x = floatsub(x, float(OBJECT_BOUNDS_MINX)) / OBJECT_REAL_X_SECTOR_SIZE;
  1472.     y = floatsub(y, float(OBJECT_BOUNDS_MINY)) / OBJECT_REAL_Y_SECTOR_SIZE;
  1473.     new
  1474.         val;
  1475.     val = (floatround(x, floatround_floor) * OBJECT_SECTOR_X_EDGE) + floatround(y, floatround_floor);
  1476.     return val;
  1477. }
  1478.  
  1479. /*----------------------------------------------------------------------------*-
  1480. Function:
  1481.     Object_AddToOOB
  1482. Params:
  1483.     pointer - Index of the object to add.
  1484. Return:
  1485.     -
  1486. Notes:
  1487.     Adds an object to the linked list for objects out of bounds of the grid
  1488.     system (i.e. stores objects out the +/-OBJECT_BOUNDS world limit).
  1489. -*----------------------------------------------------------------------------*/
  1490.  
  1491. static stock Object_AddToOOB(pointer)
  1492. {
  1493.     if (YSI_g_sOtherSector == NO_OBJECT)
  1494.     {
  1495.         YSI_g_sOtherSector = pointer;
  1496.         YSI_g_sObjects[pointer][E_OBJECT_NEXT] = pointer;
  1497.     }
  1498.     else
  1499.     {
  1500.         YSI_g_sObjects[pointer][E_OBJECT_NEXT] = YSI_g_sObjects[YSI_g_sOtherSector][E_OBJECT_NEXT];
  1501.         YSI_g_sObjects[YSI_g_sOtherSector][E_OBJECT_NEXT] = pointer;
  1502.     }
  1503.     YSI_g_sObjects[pointer][E_OBJECT_SECTOR] = OBJECT_NO_SECTOR;
  1504. }
  1505.  
  1506. /*----------------------------------------------------------------------------*-
  1507. Function:
  1508.     Object_AddToLOD
  1509. Params:
  1510.     pointer - Index of the object to add.
  1511. Return:
  1512.     -
  1513. Notes:
  1514.     Adds an object to the linked list for objects with views > OBJECT_MAX_VIEW
  1515. -*----------------------------------------------------------------------------*/
  1516.  
  1517. static stock Object_AddToLOD(pointer)
  1518. {
  1519.     if (YSI_g_sLODObjects == NO_OBJECT)
  1520.     {
  1521.         YSI_g_sLODObjects = pointer;
  1522.         YSI_g_sObjects[pointer][E_OBJECT_NEXT] = pointer;
  1523.     }
  1524.     else
  1525.     {
  1526.         YSI_g_sObjects[pointer][E_OBJECT_NEXT] = YSI_g_sObjects[YSI_g_sLODObjects][E_OBJECT_NEXT];
  1527.         YSI_g_sObjects[YSI_g_sLODObjects][E_OBJECT_NEXT] = pointer;
  1528.     }
  1529.     YSI_g_sObjects[pointer][E_OBJECT_SECTOR] = OBJECT_LOD_SECTOR;
  1530. }
  1531.  
  1532. /*----------------------------------------------------------------------------*-
  1533. Function:
  1534.     Object_AddToINT
  1535. Params:
  1536.     pointer - Index of the object to add.
  1537. Return:
  1538.     -
  1539. Notes:
  1540.     Adds an object to the linked list for objects in interiors.
  1541. -*----------------------------------------------------------------------------*/
  1542.  
  1543. static stock Object_AddToINT(pointer)
  1544. {
  1545.     if (YSI_g_sInteriorObjects == NO_OBJECT)
  1546.     {
  1547.         YSI_g_sInteriorObjects = pointer;
  1548.         YSI_g_sObjects[pointer][E_OBJECT_NEXT] = pointer;
  1549.     }
  1550.     else
  1551.     {
  1552.         YSI_g_sObjects[pointer][E_OBJECT_NEXT] = YSI_g_sObjects[YSI_g_sInteriorObjects][E_OBJECT_NEXT];
  1553.         YSI_g_sObjects[YSI_g_sInteriorObjects][E_OBJECT_NEXT] = pointer;
  1554.     }
  1555.     YSI_g_sObjects[pointer][E_OBJECT_SECTOR] = OBJECT_LOD_SECTOR;
  1556. }
  1557.  
  1558. /*----------------------------------------------------------------------------*-
  1559. Function:
  1560.     Object_AddToMovingList
  1561. Params:
  1562.     pointer - Index of the object to add.
  1563. Return:
  1564.     -
  1565. Notes:
  1566.     Adds an object to the linked list for dynamic objects.
  1567. -*----------------------------------------------------------------------------*/
  1568.  
  1569. static stock Object_AddToMovingList(pointer)
  1570. {
  1571.     if (YSI_g_sMovingObjects == NO_OBJECT)
  1572.     {
  1573.         YSI_g_sMovingObjects = pointer;
  1574.         YSI_g_sObjects[pointer][E_OBJECT_NEXT] = pointer;
  1575.     }
  1576.     else
  1577.     {
  1578.         YSI_g_sObjects[pointer][E_OBJECT_NEXT] = YSI_g_sObjects[YSI_g_sMovingObjects][E_OBJECT_NEXT];
  1579.         YSI_g_sObjects[YSI_g_sMovingObjects][E_OBJECT_NEXT] = pointer;
  1580.     }
  1581.     YSI_g_sObjects[pointer][E_OBJECT_SECTOR] = OBJECT_NO_SECTOR;
  1582. }
  1583.  
  1584. /*----------------------------------------------------------------------------*-
  1585. Function:
  1586.     Object_AddToSector
  1587. Params:
  1588.     sector - Sector of object.
  1589.     pointer - Index of object.
  1590.     Float:view - Distance the object can be seen from.
  1591. Return:
  1592.     -
  1593. Notes:
  1594.     Saves an object as being in a sector.
  1595. -*----------------------------------------------------------------------------*/
  1596.  
  1597. static stock Object_AddToSector(sector, pointer, Float:view)
  1598. {
  1599.     if (sector == OBJECT_NO_SECTOR) Object_AddToOOB(pointer);
  1600.     else if (sector == OBJECT_INT_SECTOR) Object_AddToINT(pointer);
  1601.     else if (view > (OBJECT_MAX_VIEW_DISTANCE * OBJECT_MAX_VIEW_DISTANCE)) Object_AddToLOD(pointer);
  1602.     else
  1603.     {
  1604.         new
  1605.             data = YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_POINTER];
  1606.         if (data == NO_OBJECT)
  1607.         {
  1608.             YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_POINTER] = pointer;
  1609.             YSI_g_sObjects[pointer][E_OBJECT_NEXT] = pointer;
  1610.         }
  1611.         else
  1612.         {
  1613.             YSI_g_sObjects[pointer][E_OBJECT_NEXT] = YSI_g_sObjects[data][E_OBJECT_NEXT];
  1614.             YSI_g_sObjects[data][E_OBJECT_NEXT] = pointer;
  1615.         }
  1616.         YSI_g_sObjects[pointer][E_OBJECT_SECTOR] = sector;
  1617.         if (view > YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_MAX_VIEW]) YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_MAX_VIEW] = view;
  1618.     }
  1619. }
  1620.  
  1621. /*----------------------------------------------------------------------------*-
  1622. Function:
  1623.     DestroyDynamicObject
  1624. Params:
  1625.     objectid - Object to destroy.
  1626. Return:
  1627.     -
  1628. Notes:
  1629.     Dynamic wrapper for DestroyObject.  Removes the object from it's list by
  1630.     using the cyclic property to find the previous object and repointing it to
  1631.     the object after the removed one.  This ay make it point to itself but
  1632.     this is a good thing.  The object is then added to the unassigned list in
  1633.     the same way as it's added to a normal list and finally the object flags
  1634.     are reset to destroy the data.
  1635. -*----------------------------------------------------------------------------*/
  1636.  
  1637. stock DestroyDynamicObject(objectid)
  1638. {
  1639. #if defined _YSI_SETUP_MASTER
  1640.     if (YSI_g_sIsMaster)
  1641.     {
  1642. #endif
  1643.         if (Object_IsValid(objectid))
  1644.         {
  1645.             return Object_Destroy(objectid);
  1646.         }
  1647.         return 0;
  1648. #if defined _YSI_SETUP_MASTER
  1649.     }
  1650.     else
  1651.     {
  1652.         CallRemoteFunction("Object_Remote", "iii", objectid, 0, E_OBJECT_REMOTE_DESTROY);
  1653.         return getproperty(0, "YSIReq");
  1654.     }
  1655. #endif
  1656. }
  1657.  
  1658. /*----------------------------------------------------------------------------*-
  1659. Function:
  1660.     Object_Destroy
  1661. Params:
  1662.     objectid - Object to destroy.
  1663.     remove - Wether to update client side objects.
  1664. Return:
  1665.     -
  1666. Notes:
  1667.     Does the hard work for DestroyDynamicObject.
  1668. -*----------------------------------------------------------------------------*/
  1669.  
  1670. static stock Object_Destroy(objectid, remove = 1)
  1671. {
  1672.     Object_RemoveFromSector(YSI_g_sObjects[objectid][E_OBJECT_SECTOR], objectid);
  1673.     if (YSI_g_sNoObjects == NO_OBJECT)
  1674.     {
  1675.         YSI_g_sNoObjects = objectid;
  1676.         YSI_g_sObjects[objectid][E_OBJECT_NEXT] = objectid;
  1677.     }
  1678.     else
  1679.     {
  1680.         YSI_g_sObjects[objectid][E_OBJECT_NEXT] = YSI_g_sObjects[YSI_g_sNoObjects][E_OBJECT_NEXT];
  1681.         YSI_g_sObjects[YSI_g_sNoObjects][E_OBJECT_NEXT] = objectid;
  1682.     }
  1683.     #if !defined NO_OBJECT_ATTACH
  1684.         new
  1685.             children = YSI_g_sObjects[objectid][E_OBJECT_CHILDREN],
  1686.             parent = YSI_g_sObjects[objectid][E_OBJECT_PARENT],
  1687.             old = NO_OBJECT,
  1688.             last = NO_OBJECT;
  1689.         while (children != NO_OBJECT)
  1690.         {
  1691.             last = children;
  1692.             YSI_g_sObjects[children][E_OBJECT_PARENT] = parent;
  1693.             children = YSI_g_sObjects[children][E_OBJECT_SIBLINGS];
  1694.         }
  1695.         if (parent != NO_OBJECT)
  1696.         {
  1697.             old = YSI_g_sObjects[parent][E_OBJECT_CHILDREN];
  1698.             if (old == objectid)
  1699.             {
  1700.                 old = YSI_g_sObjects[objectid][E_OBJECT_SIBLINGS];
  1701.             }
  1702.             else
  1703.             {
  1704.                 children = old;
  1705.                 new
  1706.                     obj;
  1707.                 do
  1708.                 {
  1709.                     obj = children;
  1710.                     children = YSI_g_sObjects[children][E_OBJECT_SIBLINGS];
  1711.                 }
  1712.                 while (children != objectid);
  1713.                 YSI_g_sObjects[obj][E_OBJECT_SIBLINGS] = YSI_g_sObjects[objectid][E_OBJECT_SIBLINGS];
  1714.             }
  1715.             if (last != NO_OBJECT)
  1716.             {
  1717.                 YSI_g_sObjects[last][E_OBJECT_SIBLINGS] = old;
  1718.             }
  1719.             YSI_g_sObjects[parent][E_OBJECT_CHILDREN] = YSI_g_sObjects[objectid][E_OBJECT_CHILDREN];
  1720.         }
  1721.     #endif
  1722.     YSI_g_sObjects[objectid][E_OBJECT_MODEL] = e_OBJ_FLAG:0;
  1723.     if (remove)
  1724.     {
  1725.         foreach (Player, playerid)
  1726.         {
  1727.             for (new i = 0; i < MAY_OBJECTS; i++)
  1728.             {
  1729.                 if (YSI_g_sPlayerObjects[playerid][i] == objectid)
  1730.                 {
  1731.                     DestroyPlayerObject(playerid, i + 1);
  1732.                     break;
  1733.                 }
  1734.             }
  1735.         }
  1736.     }
  1737.     return 1;
  1738. }
  1739.  
  1740. /*----------------------------------------------------------------------------*-
  1741. Function:
  1742.     Object_RemoveFromSector
  1743. Params:
  1744.     sector - Sector list to modify.
  1745.     objectid - Object to remove.
  1746. Return:
  1747.     -
  1748. Notes:
  1749.     Used to be part of DestroyDynamicObject but is needed by other API
  1750.     functions.
  1751. -*----------------------------------------------------------------------------*/
  1752.  
  1753. static stock Object_RemoveFromSector(sector, objectid)
  1754. {
  1755.     new
  1756.         pointer = objectid,
  1757.         last,
  1758.         Float:newview = OBJECT_SIGHT;
  1759.     do
  1760.     {
  1761.         last = pointer;
  1762.         pointer = YSI_g_sObjects[last][E_OBJECT_NEXT];
  1763.         if (last != objectid && YSI_g_sObjects[last][E_OBJECT_VIEW] > newview) newview = YSI_g_sObjects[last][E_OBJECT_VIEW];
  1764.     }
  1765.     while (pointer != objectid);
  1766.     if (last == objectid)
  1767.     {
  1768.         if (YSI_g_sObjects[objectid][E_OBJECT_MODEL] & e_OBJ_FLAG_MOVED) YSI_g_sMovingObjects = NO_OBJECT;
  1769.         else if (sector == OBJECT_NO_SECTOR) YSI_g_sOtherSector = NO_OBJECT;
  1770.         else if (sector == OBJECT_LOD_SECTOR) YSI_g_sLODObjects = NO_OBJECT;
  1771.         else if (sector == OBJECT_INT_SECTOR) YSI_g_sInteriorObjects = NO_OBJECT;
  1772.         else
  1773.         {
  1774.             YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_POINTER] = NO_OBJECT;
  1775.             YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_MAX_VIEW] = OBJECT_SIGHT;
  1776.         }
  1777.     }
  1778.     else
  1779.     {
  1780.         if (YSI_g_sObjects[objectid][E_OBJECT_MODEL] & e_OBJ_FLAG_MOVED)
  1781.         {
  1782.             if (YSI_g_sMovingObjects == objectid) YSI_g_sMovingObjects = last;
  1783.         }
  1784.         else if (sector == OBJECT_NO_SECTOR)
  1785.         {
  1786.             if (YSI_g_sOtherSector == objectid) YSI_g_sOtherSector = last;
  1787.         }
  1788.         else if (sector == OBJECT_LOD_SECTOR)
  1789.         {
  1790.             if (YSI_g_sLODObjects == objectid) YSI_g_sLODObjects = last;
  1791.         }
  1792.         else if (sector == OBJECT_INT_SECTOR)
  1793.         {
  1794.             if (YSI_g_sInteriorObjects == objectid) YSI_g_sInteriorObjects = last;
  1795.         }
  1796.         else if (YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_POINTER] == objectid)
  1797.         {
  1798.             YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_POINTER] = last;
  1799.             YSI_g_sObjectSectors[sector][E_OBJ_SECTOR_MAX_VIEW] = newview;
  1800.         }
  1801.         YSI_g_sObjects[last][E_OBJECT_NEXT] = YSI_g_sObjects[objectid][E_OBJECT_NEXT];
  1802.     }
  1803. }
  1804.  
  1805. /*----------------------------------------------------------------------------*-
  1806. Function:
  1807.     SetDynamicObjectPos
  1808. Params:
  1809.     objectid - Object to set new position of.
  1810.     Float:x - X co-ordinate.
  1811.     Float:y - Y co-ordintae.
  1812.     Float:z - Z co-ordinate.
  1813. Return:
  1814.     -
  1815. Notes:
  1816.     Updated to update child positions to (but NOT parent).
  1817. -*----------------------------------------------------------------------------*/
  1818.  
  1819. stock SetDynamicObjectPos(objectid, Float:x, Float:y, Float:z)
  1820. {
  1821.     #if defined _YSI_SETUP_MASTER
  1822.         if (YSI_g_sIsMaster)
  1823.         {
  1824.     #endif
  1825.             if (!Object_IsValid(objectid) || Object_IsAttached(YSI_g_sObjects[objectid][E_OBJECT_MODEL])) return 0;
  1826.             #if !defined NO_OBJECT_ATTACH
  1827.                 Object_UpdateChildSectors(YSI_g_sObjects[objectid][E_OBJECT_CHILDREN], x, y, z);
  1828.             #endif
  1829.             return Object_SetPos(objectid, x, y, z);
  1830.     #if defined _YSI_SETUP_MASTER
  1831.         }
  1832.         else
  1833.         {
  1834.             CallRemoteFunction("Object_CoOrdRemote", "iiffff", objectid, E_OBJECT_REMOTE_SETPOS, x, y, z, 0.0);
  1835.             return getproperty(0, "YSIReq");
  1836.         }
  1837.     #endif
  1838. }
  1839.  
  1840. /*----------------------------------------------------------------------------*-
  1841. Function:
  1842.     Object_SetPos
  1843. Params:
  1844.     objectid - Object to set new position of.
  1845.     Float:x - X co-ordinate.
  1846.     Float:y - Y co-ordintae.
  1847.     Float:z - Z co-ordinate.
  1848. Return:
  1849.     -
  1850. Notes:
  1851.     Does the actual relocation of an object.
  1852. -*----------------------------------------------------------------------------*/
  1853.  
  1854. static stock Object_SetPos(objectid, Float:x, Float:y, Float:z)
  1855. {
  1856.     new
  1857.         newsec = Object_FindSector(x, y, z),
  1858.         oldsec;
  1859.     if (newsec != (oldsec = YSI_g_sObjects[objectid][E_OBJECT_SECTOR]))
  1860.     {
  1861.         Object_RemoveFromSector(oldsec, objectid);
  1862.         Object_AddToSector(newsec, objectid, YSI_g_sObjects[objectid][E_OBJECT_VIEW]);
  1863.     }
  1864.     #if !defined NO_OBJECT_ATTACH
  1865.         new
  1866.             parent = YSI_g_sObjects[objectid][E_OBJECT_PARENT];
  1867.         if (parent != NO_OBJECT)
  1868.         {
  1869.             new
  1870.                 Float:nx,
  1871.                 Float:ny,
  1872.                 Float:nz;
  1873.             Object_GetPos(parent, nx, ny, nz);
  1874.             YSI_g_sObjects[objectid][E_OBJECT_X] = x - nx;
  1875.             YSI_g_sObjects[objectid][E_OBJECT_Y] = y - ny;
  1876.             YSI_g_sObjects[objectid][E_OBJECT_Z] = z - nz;
  1877.         }
  1878.         else
  1879.         {
  1880.     #endif
  1881.             YSI_g_sObjects[objectid][E_OBJECT_X] = x;
  1882.             YSI_g_sObjects[objectid][E_OBJECT_Y] = y;
  1883.             YSI_g_sObjects[objectid][E_OBJECT_Z] = z;
  1884.     #if !defined NO_OBJECT_ATTACH
  1885.         }
  1886.     #endif
  1887.     YSI_g_sObjects[objectid][E_OBJECT_MODEL] |= e_OBJ_FLAG_JUMPED;
  1888.     YSI_g_sObjects[objectid][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  1889.     YSI_g_sSomethingMoved = objectid;
  1890.     return 1;
  1891. }
  1892.  
  1893. /*----------------------------------------------------------------------------*-
  1894. Function:
  1895.     Object_UpdateChildSectors
  1896. Params:
  1897.     objectid - Object to update children of.
  1898.     Float:x - X co-ordinate of parent.
  1899.     Float:y - Y co-ordintae of parent.
  1900.     Float:z - Z co-ordinate of parent.
  1901. Return:
  1902.     -
  1903. Notes:
  1904.     Doesn't update the position parameter as that's relative to the parent for
  1905.     child objects.  Recursive function to update sectors of children of
  1906.     children.
  1907. -*----------------------------------------------------------------------------*/
  1908.  
  1909. #if !defined NO_OBJECT_ATTACH
  1910. static stock Object_UpdateChildSectors(objectid, Float:x, Float:y, Float:z)
  1911. {
  1912.     new
  1913.         Float:nx,
  1914.         Float:ny,
  1915.         Float:nz,
  1916.         newsec,
  1917.         oldsec;
  1918.     while (objectid != NO_OBJECT)
  1919.     {
  1920.         if (Object_IsAttached(objectid))
  1921.         {
  1922.             nx = x + YSI_g_sObjects[objectid][E_OBJECT_X];
  1923.             ny = y + YSI_g_sObjects[objectid][E_OBJECT_Y];
  1924.             nz = z + YSI_g_sObjects[objectid][E_OBJECT_Z];
  1925.             newsec = Object_FindSector(nx, ny, nz);
  1926.             if (newsec != (oldsec = YSI_g_sObjects[objectid][E_OBJECT_SECTOR]))
  1927.             {
  1928.                 Object_RemoveFromSector(oldsec, objectid);
  1929.                 Object_AddToSector(newsec, objectid, YSI_g_sObjects[objectid][E_OBJECT_VIEW]);
  1930.             }
  1931.             Object_UpdateChildSectors(YSI_g_sObjects[objectid][E_OBJECT_CHILDREN], nx, ny, nz);
  1932.             YSI_g_sObjects[objectid][E_OBJECT_MODEL] |= e_OBJ_FLAG_JUMPED;
  1933.         }
  1934.         objectid = YSI_g_sObjects[objectid][E_OBJECT_SIBLINGS];
  1935.     }
  1936. }
  1937. #endif
  1938.  
  1939. /*----------------------------------------------------------------------------*-
  1940. Function:
  1941.     SetDynamicObjectRot
  1942. Params:
  1943.     objectid - Object to set new rotation of.
  1944.     Float:x - X rotation.
  1945.     Float:y - Y rotation.
  1946.     Float:z - Z rotation.
  1947. Return:
  1948.     -
  1949. Notes:
  1950.     -
  1951. -*----------------------------------------------------------------------------*/
  1952.  
  1953. stock SetDynamicObjectRot(objectid, Float:x, Float:y, Float:z)
  1954. {
  1955.     #if defined _YSI_SETUP_MASTER
  1956.         if (YSI_g_sIsMaster)
  1957.         {
  1958.     #endif
  1959.             if (!Object_IsValid(objectid) || Object_IsAttached(YSI_g_sObjects[objectid][E_OBJECT_MODEL])) return 0;
  1960.             YSI_g_sObjects[objectid][E_OBJECT_RX] = x;
  1961.             YSI_g_sObjects[objectid][E_OBJECT_RY] = y;
  1962.             YSI_g_sObjects[objectid][E_OBJECT_RZ] = z;
  1963.             YSI_g_sObjects[objectid][E_OBJECT_MODEL] |= e_OBJ_FLAG_ROTATED;
  1964.             YSI_g_sObjects[objectid][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  1965.             YSI_g_sSomethingMoved = objectid;
  1966.             return 1;
  1967.     #if defined _YSI_SETUP_MASTER
  1968.         }
  1969.         else
  1970.         {
  1971.             CallRemoteFunction("Object_CoOrdRemote", "iiffff", objectid, E_OBJECT_REMOTE_SETROT, x, y, z, 0.0);
  1972.             return getproperty(0, "YSIReq");
  1973.         }
  1974.     #endif
  1975. }
  1976.  
  1977. /*----------------------------------------------------------------------------*-
  1978. Function:
  1979.     GetDynamicObjectRot
  1980. Params:
  1981.     objectid - Object to set new rotation of.
  1982.     &Float:x - X rotation store.
  1983.     &Float:y - Y rotation store.
  1984.     &Float:z - Z rotation store.
  1985. Return:
  1986.     -
  1987. Notes:
  1988.     -
  1989. -*----------------------------------------------------------------------------*/
  1990.  
  1991. stock GetDynamicObjectRot(objectid, &Float:x, &Float:y, &Float:z)
  1992. {
  1993.     #if defined _YSI_SETUP_MASTER
  1994.         if (YSI_g_sIsMaster)
  1995.         {
  1996.     #endif
  1997.             if (!Object_IsValid(objectid) || Object_IsAttached(YSI_g_sObjects[objectid][E_OBJECT_MODEL])) return 0;
  1998.             x = YSI_g_sObjects[objectid][E_OBJECT_RX];
  1999.             y = YSI_g_sObjects[objectid][E_OBJECT_RY];
  2000.             z = YSI_g_sObjects[objectid][E_OBJECT_RZ];
  2001.             return 1;
  2002.     #if defined _YSI_SETUP_MASTER
  2003.         }
  2004.         else
  2005.         {
  2006.             CallRemoteFunction("Object_Remote", "iii", objectid, 0, E_OBJECT_REMOTE_GETROT);
  2007.             x = Float:getproperty(0, "YSIReq");
  2008.             y = Float:getproperty(0, "YSIReq2");
  2009.             z = Float:getproperty(0, "YSIReq3");
  2010.             deleteproperty(0, "YSIReq2");
  2011.             deleteproperty(0, "YSIReq3");
  2012.         }
  2013.     #endif
  2014. }
  2015.  
  2016. /*----------------------------------------------------------------------------*-
  2017. Function:
  2018.     Object_AddToWorld
  2019. Params:
  2020.     object - Object to add.
  2021.     world - World to add to.
  2022. Return:
  2023.     -
  2024. Notes:
  2025.     Makes an object visible in a world.
  2026. -*----------------------------------------------------------------------------*/
  2027.  
  2028. stock Object_AddToWorld(object, world)
  2029. {
  2030.     #if OBJECT_WORLDS > 0
  2031.         #if defined _YSI_SETUP_MASTER
  2032.             if (YSI_g_sIsMaster)
  2033.             {
  2034.         #endif
  2035.                 if (Object_IsValid(object)) Bit_Set(YSI_g_sObjects[object][E_OBJECT_WORLDS], world, 1, OBJECT_WORLD_COUNT);
  2036.         #if defined _YSI_SETUP_MASTER
  2037.             }
  2038.             else
  2039.             {
  2040.                 CallRemoteFunction("Object_Remote", "iii", object, world, E_OBJECT_REMOTE_ADDW);
  2041.             }
  2042.         #endif
  2043.     #else
  2044.         #pragma unused object, world
  2045.     #endif
  2046. }
  2047.  
  2048. /*----------------------------------------------------------------------------*-
  2049. Function:
  2050.     Object_RemoveFromWorld
  2051. Params:
  2052.     object - Object to remove.
  2053.     world - World to remove from.
  2054. Return:
  2055.     -
  2056. Notes:
  2057.     Makes an object invisible in a world.
  2058. -*----------------------------------------------------------------------------*/
  2059.  
  2060. stock Object_RemoveFromWorld(object, world)
  2061. {
  2062.     #if OBJECT_WORLDS > 0
  2063.         #if defined _YSI_SETUP_MASTER
  2064.             if (YSI_g_sIsMaster)
  2065.             {
  2066.         #endif
  2067.                 if (Object_IsValid(object)) Bit_Set(YSI_g_sObjects[object][E_OBJECT_WORLDS], world, 0, OBJECT_WORLD_COUNT);
  2068.         #if defined _YSI_SETUP_MASTER
  2069.             }
  2070.             else
  2071.             {
  2072.                 CallRemoteFunction("Object_Remote", "iii", object, world, E_OBJECT_REMOTE_REMW);
  2073.             }
  2074.         #endif
  2075.     #else
  2076.         #pragma unused object, world
  2077.     #endif
  2078. }
  2079.  
  2080. /*----------------------------------------------------------------------------*-
  2081. Function:
  2082.     Object_AddToPlayer
  2083. Params:
  2084.     object - Object to add.
  2085.     playerid - Player to add to.
  2086. Return:
  2087.     -
  2088. Notes:
  2089.     Makes an object visible to a player.
  2090. -*----------------------------------------------------------------------------*/
  2091.  
  2092. stock Object_AddToPlayer(object, playerid)
  2093. {
  2094.     #if !defined NO_PERSONAL_OBJECTS
  2095.         #if defined _YSI_SETUP_MASTER
  2096.             if (YSI_g_sIsMaster)
  2097.             {
  2098.         #endif
  2099.                 if (Object_IsValid(object)) Bit_Set(YSI_g_sObjects[object][E_OBJECT_PLAYERS], playerid, 1, PLAYER_BIT_ARRAY);
  2100.         #if defined _YSI_SETUP_MASTER
  2101.             }
  2102.             else
  2103.             {
  2104.                 CallRemoteFunction("Object_Remote", "iii", object, playerid, E_OBJECT_REMOTE_ADDP);
  2105.             }
  2106.         #endif
  2107.     #else
  2108.         #pragma unused object, playerid
  2109.     #endif
  2110. }
  2111.  
  2112. /*----------------------------------------------------------------------------*-
  2113. Function:
  2114.     Object_RemoveFromWorld
  2115. Params:
  2116.     object - Object to remove.
  2117.     playerid - Player to remove from.
  2118. Return:
  2119.     -
  2120. Notes:
  2121.     Makes an object invisible to a player.
  2122. -*----------------------------------------------------------------------------*/
  2123.  
  2124. stock Object_RemoveFromPlayer(object, playerid)
  2125. {
  2126.     #if !defined NO_PERSONAL_OBJECTS
  2127.         #if defined _YSI_SETUP_MASTER
  2128.             if (YSI_g_sIsMaster)
  2129.             {
  2130.         #endif
  2131.                 if (Object_IsValid(object)) Bit_Set(YSI_g_sObjects[object][E_OBJECT_PLAYERS], playerid, 0, PLAYER_BIT_ARRAY);
  2132.         #if defined _YSI_SETUP_MASTER
  2133.             }
  2134.             else
  2135.             {
  2136.                 CallRemoteFunction("Object_Remote", "iii", object, playerid, E_OBJECT_REMOTE_REMP);
  2137.             }
  2138.         #endif
  2139.     #else
  2140.         #pragma unused object, playerid
  2141.     #endif
  2142. }
  2143.  
  2144. /*----------------------------------------------------------------------------*-
  2145. Function:
  2146.     Object_AddToAllWorlds
  2147. Params:
  2148.     object - Object to add.
  2149. Return:
  2150.     -
  2151. Notes:
  2152.     Makes an object visible in all worlds.
  2153. -*----------------------------------------------------------------------------*/
  2154.  
  2155. stock Object_AddToAllWorlds(object)
  2156. {
  2157.     #if OBJECT_WORLDS > 0
  2158.         #if defined _YSI_SETUP_MASTER
  2159.             if (YSI_g_sIsMaster)
  2160.             {
  2161.         #endif
  2162.                 if (Object_IsValid(object)) Bit_SetAll(YSI_g_sObjects[object][E_OBJECT_WORLDS], 1, OBJECT_WORLD_COUNT);
  2163.         #if defined _YSI_SETUP_MASTER
  2164.             }
  2165.             else
  2166.             {
  2167.                 CallRemoteFunction("Object_Remote", "iii", object, 0, E_OBJECT_REMOTE_ALLWA);
  2168.             }
  2169.         #endif
  2170.     #else
  2171.         #pragma unused object
  2172.     #endif
  2173. }
  2174.  
  2175. /*----------------------------------------------------------------------------*-
  2176. Function:
  2177.     Object_RemoveFromAllWorlds
  2178. Params:
  2179.     object - Object to remove.
  2180. Return:
  2181.     -
  2182. Notes:
  2183.     Makes an object invisible in all worlds.
  2184. -*----------------------------------------------------------------------------*/
  2185.  
  2186. stock Object_RemoveFromAllWorlds(object)
  2187. {
  2188.     #if OBJECT_WORLDS > 0
  2189.         #if defined _YSI_SETUP_MASTER
  2190.             if (YSI_g_sIsMaster)
  2191.             {
  2192.         #endif
  2193.                 if (Object_IsValid(object)) Bit_SetAll(YSI_g_sObjects[object][E_OBJECT_WORLDS], 0, OBJECT_WORLD_COUNT);
  2194.         #if defined _YSI_SETUP_MASTER
  2195.             }
  2196.             else
  2197.             {
  2198.                 CallRemoteFunction("Object_Remote", "iii", object, 0, E_OBJECT_REMOTE_ALLWR);
  2199.             }
  2200.         #endif
  2201.     #else
  2202.         #pragma unused object
  2203.     #endif
  2204. }
  2205.  
  2206. /*----------------------------------------------------------------------------*-
  2207. Function:
  2208.     Object_AddToAllPlayers
  2209. Params:
  2210.     object - Object to add.
  2211. Return:
  2212.     -
  2213. Notes:
  2214.     Makes an object visible to all players.
  2215. -*----------------------------------------------------------------------------*/
  2216.  
  2217. stock Object_AddToAllPlayers(object)
  2218. {
  2219.     #if !defined NO_PERSONAL_OBJECTS
  2220.         #if defined _YSI_SETUP_MASTER
  2221.             if (YSI_g_sIsMaster)
  2222.             {
  2223.         #endif
  2224.                 if (Object_IsValid(object))
  2225.                 {
  2226.                     Bit_SetAll(YSI_g_sObjects[object][E_OBJECT_PLAYERS], 1, PLAYER_BIT_ARRAY);
  2227.                 }
  2228.         #if defined _YSI_SETUP_MASTER
  2229.             }
  2230.             else
  2231.             {
  2232.                 CallRemoteFunction("Object_Remote", "iii", object, 0, E_OBJECT_REMOTE_ALLPA);
  2233.             }
  2234.         #endif
  2235.     #else
  2236.         #pragma unused object
  2237.     #endif
  2238. }
  2239.  
  2240. /*----------------------------------------------------------------------------*-
  2241. Function:
  2242.     Object_RemoveFromAllPlayers
  2243. Params:
  2244.     object - Object to remove.
  2245. Return:
  2246.     -
  2247. Notes:
  2248.     Makes an object invisible to all players.
  2249. -*----------------------------------------------------------------------------*/
  2250.  
  2251. stock Object_RemoveFromAllPlayers(object)
  2252. {
  2253.     #if !defined NO_PERSONAL_OBJECTS
  2254.         #if defined _YSI_SETUP_MASTER
  2255.             if (YSI_g_sIsMaster)
  2256.             {
  2257.         #endif
  2258.                 if (Object_IsValid(object))
  2259.                 {
  2260.                     Bit_SetAll(YSI_g_sObjects[object][E_OBJECT_PLAYERS], 0, PLAYER_BIT_ARRAY);
  2261.                 }
  2262.         #if defined _YSI_SETUP_MASTER
  2263.             }
  2264.             else
  2265.             {
  2266.                 CallRemoteFunction("Object_Remote", "iii", object, 0, E_OBJECT_REMOTE_ALLPR);
  2267.             }
  2268.         #endif
  2269.     #else
  2270.         #pragma unused object
  2271.     #endif
  2272. }
  2273.  
  2274. /*----------------------------------------------------------------------------*-
  2275. Function:
  2276.     Object_GetPos
  2277. Params:
  2278.     objectid - Object to get position of.
  2279.     &Float:x - X return.
  2280.     &Float:y - Y return.
  2281.     &Float:z - Z return.
  2282. Return:
  2283.     -
  2284. Notes:
  2285.     -
  2286. -*----------------------------------------------------------------------------*/
  2287.  
  2288. static stock Object_GetPos(objectid, &Float:x, &Float:y, &Float:z)
  2289. {
  2290.     new
  2291.         playerid = Object_GetAttach(YSI_g_sObjects[objectid][E_OBJECT_MODEL]);
  2292.     if (playerid != NO_ATTACH_PLAYER && IsPlayerConnected(playerid))
  2293.     {
  2294.         GetPlayerPos(playerid, x, y, z);
  2295.     }
  2296.     #if !defined NO_OBJECT_ATTACH
  2297.         else if ((playerid = YSI_g_sObjects[objectid][E_OBJECT_PARENT]) != NO_OBJECT)
  2298.         {
  2299.             Object_GetPos(playerid, x, y, z);
  2300.         }
  2301.     #endif
  2302.     #pragma tabsize 0
  2303.     else
  2304.     #pragma tabsize 4
  2305.     {
  2306.         x = YSI_g_sObjects[objectid][E_OBJECT_X];
  2307.         y = YSI_g_sObjects[objectid][E_OBJECT_Y];
  2308.         z = YSI_g_sObjects[objectid][E_OBJECT_Z];
  2309.         return;
  2310.     }
  2311.     x += YSI_g_sObjects[objectid][E_OBJECT_X];
  2312.     y += YSI_g_sObjects[objectid][E_OBJECT_Y];
  2313.     z += YSI_g_sObjects[objectid][E_OBJECT_Z];
  2314. }
  2315.  
  2316. /*----------------------------------------------------------------------------*-
  2317. Function:
  2318.     GetDynamicObjectPos
  2319. Params:
  2320.     objectid - Object to get position of.
  2321.     &Float:x - X return.
  2322.     &Float:y - Y return.
  2323.     &Float:z - Z return.
  2324. Return:
  2325.     -
  2326. Notes:
  2327.     API wrapper for Object_GetPos.
  2328. -*----------------------------------------------------------------------------*/
  2329.  
  2330. stock GetDynamicObjectPos(objectid, &Float:x, &Float:y, &Float:z)
  2331. {
  2332.     #if defined _YSI_SETUP_MASTER
  2333.         if (YSI_g_sIsMaster)
  2334.         {
  2335.     #endif
  2336.             if (!Object_IsValid(objectid)) return 0;
  2337.             Object_GetPos(objectid, x, y, z);
  2338.     #if defined _YSI_SETUP_MASTER
  2339.         }
  2340.         else
  2341.         {
  2342.             CallRemoteFunction("Object_Remote", "iii", objectid, 0, E_OBJECT_REMOTE_GETPOS);
  2343.             x = Float:getproperty(0, "YSIReq");
  2344.             y = Float:getproperty(0, "YSIReq2");
  2345.             z = Float:getproperty(0, "YSIReq3");
  2346.             deleteproperty(0, "YSIReq2");
  2347.             deleteproperty(0, "YSIReq3");
  2348.         }
  2349.     #endif
  2350.     return 1;
  2351. }
  2352.  
  2353. /*----------------------------------------------------------------------------*-
  2354. Function:
  2355.     Object_HasPlayer
  2356. Params:
  2357.     objectid - Object to check.
  2358.     playerid - Player to check.
  2359.     worldid - World to check.
  2360. Return:
  2361.     Whether the object is visible to that player in that world.
  2362. Notes:
  2363.     This is a variable function.  Depending on the compile time settings it may
  2364.     or may not use all the parameters (it may use none).
  2365. -*----------------------------------------------------------------------------*/
  2366.  
  2367. #if !defined NO_PERSONAL_OBJECTS
  2368.     #if OBJECT_WORLDS > 0
  2369.         #define Object_HasPlayer(%1,%2,%3) \
  2370.             (Bit_Get(YSI_g_sObjects[(%1)][E_OBJECT_WORLDS], (%3)) && Bit_Get(YSI_g_sObjects[(%1)][E_OBJECT_PLAYERS], (%2)))
  2371.     #else
  2372.         #define Object_HasPlayer(%1,%2,%3) \
  2373.             (Bit_Get(YSI_g_sObjects[(%1)][E_OBJECT_PLAYERS], (%2)))
  2374.     #endif
  2375. #else
  2376.     #if OBJECT_WORLDS > 0
  2377.         #define Object_HasPlayer(%1,%2,%3) \
  2378.             (Bit_Get(YSI_g_sObjects[(%1)][E_OBJECT_WORLDS], (%3)))
  2379.     #else
  2380.         #define Object_HasPlayer(%1,%2,%3) \
  2381.             (TRUE)
  2382.     #endif
  2383. #endif
  2384.  
  2385. /*----------------------------------------------------------------------------*-
  2386. Function:
  2387.     IsValidDynamicObject
  2388. Params:
  2389.     objectid - Object to check.
  2390. Return:
  2391.     Object_IsValid.
  2392. Notes:
  2393.     -
  2394. -*----------------------------------------------------------------------------*/
  2395.  
  2396. stock IsValidDynamicObject(objectid)
  2397. {
  2398.     #if defined _YSI_SETUP_MASTER
  2399.         if (YSI_g_sIsMaster)
  2400.         {
  2401.     #endif
  2402.             return Object_IsValid(objectid);
  2403.     #if defined _YSI_SETUP_MASTER
  2404.         }
  2405.         else
  2406.         {
  2407.             CallRemoteFunction("Object_Remote", "iii", objectid, 0, E_OBJECT_REMOTE_ISVALID);
  2408.             return getproperty(0, "YSIReq");
  2409.         }
  2410.     #endif
  2411. }
  2412.  
  2413. /*----------------------------------------------------------------------------*-
  2414. Function:
  2415.     AttachDynamicObjectToPlayer
  2416. Params:
  2417.     objectid - Object to attach.
  2418.     playerid - Player to attach to.
  2419.     Float:X - X offset.
  2420.     Float:Y - Y offset.
  2421.     Float:Z - Z offset.
  2422.     Float:RX - X rotation.
  2423.     Float:RY - Y rotation.
  2424.     Float:RZ - Z rotation.
  2425.     Float:S - Speed.
  2426. Return:
  2427.     -
  2428. Notes:
  2429.     Updated for children.
  2430. -*----------------------------------------------------------------------------*/
  2431.  
  2432. stock AttachDynamicObjectToPlayer(objectid, playerid, Float:X, Float:Y, Float:Z, Float:RX, Float:RY, Float:RZ)
  2433. {
  2434.     #if !defined NO_OBJECTS_MOVE
  2435.         #if defined _YSI_SETUP_MASTER
  2436.             if (YSI_g_sIsMaster)
  2437.             {
  2438.         #endif
  2439.                 if (Object_IsValid(objectid) && Object_IsAttached(YSI_g_sObjects[objectid][E_OBJECT_MODEL]))
  2440.                 {
  2441.                     return Object_AttachToPlayer(objectid, playerid, X, Y, Z, RX, RY, RZ);
  2442.                 }
  2443.         #if defined _YSI_SETUP_MASTER
  2444.             }
  2445.             else
  2446.             {
  2447.                 CallRemoteFunction("Object_AttachRemote", "iiffffff", objectid, playerid, X, Y, Z, RX, RY, RZ);
  2448.                 return getproperty(0, "YSIReq");
  2449.             }
  2450.         #endif
  2451.     #else
  2452.         #pragma unused objectid, X, Y, Z, S
  2453.     #endif
  2454.     return 0;
  2455. }
  2456.  
  2457. #if !defined NO_OBJECTS_MOVE
  2458.  
  2459.     #if defined _YSI_SETUP_MASTER
  2460.         /*----------------------------------------------------------------------------*-
  2461.         Function:
  2462.             Object_AttachRemote
  2463.         Params:
  2464.             objectid - Object to attach.
  2465.             playerid - Player to attach to.
  2466.             Float:X - X offset.
  2467.             Float:Y - Y offset.
  2468.             Float:Z - Z offset.
  2469.             Float:RX - X rotation.
  2470.             Float:RY - Y rotation.
  2471.             Float:RZ - Z rotation.
  2472.             Float:S - Speed.
  2473.         Return:
  2474.             -
  2475.         Notes:
  2476.             Remote call for AttachDynamicObjectToPlayer.
  2477.         -*----------------------------------------------------------------------------*/
  2478.        
  2479.         public Object_AttachRemote(objectid, playerid, Float:X, Float:Y, Float:Z, Float:RX, Float:RY, Float:RZ)
  2480.         {
  2481.             if (!YSI_g_sIsMaster) return 0;
  2482.             setproperty(0, "YSIReq", 0);
  2483.             if (Object_IsValid(objectid) && Object_IsAttached(YSI_g_sObjects[objectid][E_OBJECT_MODEL]))
  2484.             {
  2485.                 setproperty(0, "YSIReq", Object_AttachToPlayer(objectid, playerid, X, Y, Z, RX, RY, RZ));
  2486.                 return 1;
  2487.             }
  2488.             return 0;
  2489.         }
  2490.     #endif
  2491.  
  2492.     /*----------------------------------------------------------------------------*-
  2493.     Function:
  2494.         Object_AttachToPlayer
  2495.     Params:
  2496.         objectid - Object to attach.
  2497.         playerid - Player to attach to.
  2498.         Float:X - X offset.
  2499.         Float:Y - Y offset.
  2500.         Float:Z - Z offset.
  2501.         Float:RX - X rotation.
  2502.         Float:RY - Y rotation.
  2503.         Float:RZ - Z rotation.
  2504.         Float:S - Speed.
  2505.     Return:
  2506.         -
  2507.     Notes:
  2508.         Recursive call for AttachDynamicObjectToPlayer.
  2509.     -*----------------------------------------------------------------------------*/
  2510.  
  2511.     static stock Object_AttachToPlayer(objectid, playerid, Float:X, Float:Y, Float:Z, Float:RX, Float:RY, Float:RZ)
  2512.     {
  2513.         YSI_g_sObjects[objectid][E_OBJECT_MODEL] |= e_OBJ_FLAG_ATTACHED;
  2514.         YSI_g_sObjects[objectid][E_OBJECT_X] = X;
  2515.         YSI_g_sObjects[objectid][E_OBJECT_Y] = Y;
  2516.         YSI_g_sObjects[objectid][E_OBJECT_Z] = Z;
  2517.         YSI_g_sObjects[objectid][E_OBJECT_RX] = RX;
  2518.         YSI_g_sObjects[objectid][E_OBJECT_RY] = RY;
  2519.         YSI_g_sObjects[objectid][E_OBJECT_RZ] = RZ;
  2520.         Object_RemoveFromSector(YSI_g_sObjects[objectid][E_OBJECT_SECTOR], objectid);
  2521.         Object_AddToMovingList(objectid);
  2522.         YSI_g_sObjects[objectid][E_OBJECT_MODEL] = (YSI_g_sObjects[objectid][E_OBJECT_MODEL] & ~e_OBJ_FLAG_ATTACH) | Object_SetAttach(playerid);
  2523.         YSI_g_sObjects[objectid][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  2524.         YSI_g_sSomethingMoved = objectid;
  2525.         #if !defined NO_OBJECT_ATTACH
  2526.             new
  2527.                 child = YSI_g_sObjects[objectid][E_OBJECT_CHILDREN];
  2528.             while (child != NO_OBJECT)
  2529.             {
  2530.                 Object_AttachToPlayer(child, playerid, X + YSI_g_sObjects[child][E_OBJECT_X], Y + YSI_g_sObjects[child][E_OBJECT_Y], Z + YSI_g_sObjects[child][E_OBJECT_Z], RX, RY, RZ);
  2531.                 child = YSI_g_sObjects[child][E_OBJECT_SIBLINGS];
  2532.             }
  2533.         #endif
  2534.         return 1;
  2535.     }
  2536. #endif
  2537.  
  2538. /*----------------------------------------------------------------------------*-
  2539. Function:
  2540.     DetachDynamicObjectFromPlayer
  2541. Params:
  2542.     objectid - Object to detach.
  2543. Return:
  2544.     -
  2545. Notes:
  2546.     Detaches an object from a player.
  2547. -*----------------------------------------------------------------------------*/
  2548.  
  2549. stock DetachDynamicObjectFromPlayer(objectid)
  2550. {
  2551.     #if !defined NO_OBJECTS_MOVE
  2552.         #if defined _YSI_SETUP_MASTER
  2553.             if (YSI_g_sIsMaster)
  2554.             {
  2555.         #endif
  2556.                 if (!Object_IsValid(objectid)) return;
  2557.                 new
  2558.                     playerid = Object_GetAttach(YSI_g_sObjects[objectid][E_OBJECT_MODEL]);
  2559.                 if (playerid != NO_ATTACH_PLAYER)
  2560.                 {
  2561.                     Object_RemoveFromSector(OBJECT_NO_SECTOR, objectid);
  2562.                     new
  2563.                         Float:x,
  2564.                         Float:y,
  2565.                         Float:z;
  2566.                     GetPlayerPos(playerid, x, y, z);
  2567.                     new
  2568.                         Float:nx = YSI_g_sObjects[objectid][E_OBJECT_X],
  2569.                         Float:ny = YSI_g_sObjects[objectid][E_OBJECT_Y],
  2570.                         Float:nz = YSI_g_sObjects[objectid][E_OBJECT_Z];
  2571.                     Object_SetPos(objectid, x + nx, y + ny, z + nz);
  2572.                     #if !defined NO_OBJECT_ATTACH
  2573.                         Object_UpdateAttach(YSI_g_sObjects[objectid][E_OBJECT_CHILDREN], nx, ny, nz, x + nx, y + ny, z + nz, false);
  2574.                     #endif
  2575.                     YSI_g_sObjects[objectid][E_OBJECT_MODEL] |= e_OBJ_FLAG_ATTACHED | e_OBJ_FLAG_ATTACH | e_OBJ_FLAG_RECREATED;
  2576.                     YSI_g_sObjects[objectid][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  2577.                     YSI_g_sSomethingMoved = objectid;
  2578.                 }
  2579.                 return;
  2580.         #if defined _YSI_SETUP_MASTER
  2581.             }
  2582.             else
  2583.             {
  2584.                 CallRemoteFunction("Object_Remote", "iii", objectid, 0, E_OBJECT_REMOTE_DETATCH);
  2585.             }
  2586.         #endif
  2587.     #else
  2588.         #pragma unused objectid
  2589.     #endif
  2590. }
  2591.  
  2592. /*----------------------------------------------------------------------------*-
  2593. Function:
  2594.     Object_UpdateAttach
  2595. Params:
  2596.     child - Start of children list to positionally update.
  2597.     Float:x - x offset of parent.
  2598.     Float:y - y offset of parent.
  2599.     Float:z - z offset of parent.
  2600.     Float:rx - Real x location.
  2601.     Float:ry - Real y location.
  2602.     Float:rz - Real z location.
  2603.     moved - Wether the object was previously moving or attached.
  2604. Return:
  2605.     -
  2606. Notes:
  2607.     Restores the object sectors and offsets from parents based on positions
  2608.     relative to other items (origin or a player).
  2609. -*----------------------------------------------------------------------------*/
  2610.  
  2611. #if !defined NO_OBJECT_ATTACH
  2612. static stock Object_UpdateAttach(child, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, moving = true)
  2613. {
  2614.     while (child != NO_OBJECT)
  2615.     {
  2616.         new
  2617.             Float:nx = YSI_g_sObjects[child][E_OBJECT_X],
  2618.             Float:ny = YSI_g_sObjects[child][E_OBJECT_Y],
  2619.             Float:nz = YSI_g_sObjects[child][E_OBJECT_Z],
  2620.             Float:mx = nx - x,
  2621.             Float:my = ny - y,
  2622.             Float:mz = nz - z;
  2623.         Object_UpdateAttach(YSI_g_sObjects[child][E_OBJECT_CHILDREN], nx, ny, nz, rx + mx, ry + my, rz + mz);
  2624.         YSI_g_sObjects[child][E_OBJECT_X] = mx;
  2625.         YSI_g_sObjects[child][E_OBJECT_Y] = my;
  2626.         YSI_g_sObjects[child][E_OBJECT_Z] = mz;
  2627.         Object_RemoveFromSector(OBJECT_NO_SECTOR, child);
  2628.         Object_AddToSector(Object_FindSector(rx + mx, ry + my, rz + mz), child, YSI_g_sObjects[child][E_OBJECT_VIEW]);
  2629.         child = YSI_g_sObjects[child][E_OBJECT_SIBLINGS];
  2630.         if (moving)
  2631.         {
  2632.             YSI_g_sObjects[child][E_OBJECT_MODEL] = (YSI_g_sObjects[child][E_OBJECT_MODEL] & ~(e_OBJ_FLAG_MOVED)) | e_OBJ_FLAG_RECREATED;
  2633.         }
  2634.         else
  2635.         {
  2636.             YSI_g_sObjects[child][E_OBJECT_MODEL] |= e_OBJ_FLAG_ATTACHED | e_OBJ_FLAG_ATTACH | e_OBJ_FLAG_RECREATED;
  2637.         }
  2638.     }
  2639. }
  2640. #endif
  2641.  
  2642. /*----------------------------------------------------------------------------*-
  2643. Function:
  2644.     MoveDynamicObject
  2645. Params:
  2646.     objectid - Object to move.
  2647.     Float:X - X position of target.
  2648.     Float:Y - Y position of target.
  2649.     Float:Z - Z position of target.
  2650.     Float:S - Speed.
  2651. Return:
  2652.     -
  2653. Notes:
  2654.     -
  2655. -*----------------------------------------------------------------------------*/
  2656.  
  2657. stock MoveDynamicObject(objectid, Float:X, Float:Y, Float:Z, Float:S)
  2658. {
  2659.     #if !defined NO_OBJECTS_MOVE
  2660.         #if defined _YSI_SETUP_MASTER
  2661.             if (YSI_g_sIsMaster)
  2662.             {
  2663.         #endif
  2664.                 if (Object_IsValid(objectid))
  2665.                 {
  2666.                     Object_Move(objectid, X, Y, Z, S);
  2667.                     YSI_g_sObjects[objectid][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  2668.                     YSI_g_sSomethingMoved = objectid;
  2669.                     return 1;
  2670.                 }
  2671.         #if defined _YSI_SETUP_MASTER
  2672.             }
  2673.             else
  2674.             {
  2675.                 CallRemoteFunction("Object_CoOrdRemote", "iiffff", objectid, E_OBJECT_REMOTE_MOVETO, X, Y, Z, S);
  2676.                 return getproperty(0, "YSIReq");
  2677.             }
  2678.         #endif
  2679.     #else
  2680.         #pragma unused objectid, X, Y, Z, S
  2681.     #endif
  2682.     return 0;
  2683. }
  2684.  
  2685. #if !defined NO_OBJECTS_MOVE
  2686. /*----------------------------------------------------------------------------*-
  2687. Function:
  2688.     Object_Move
  2689. Params:
  2690.     objectid - Object to move.
  2691.     Float:X - X position of target.
  2692.     Float:Y - Y position of target.
  2693.     Float:Z - Z position of target.
  2694.     Float:S - Speed.
  2695. Return:
  2696.     -
  2697. Notes:
  2698.     Recursive function for MoveDynamicObject to move children.
  2699. -*----------------------------------------------------------------------------*/
  2700.  
  2701. static stock Object_Move(objectid, Float:X, Float:Y, Float:Z, Float:S)
  2702. {
  2703.     if (xor:(YSI_g_sObjects[objectid][E_OBJECT_MODEL] & e_OBJ_FLAG_MOVED1) == xor:(YSI_g_sObjects[objectid][E_OBJECT_MODEL] & e_OBJ_FLAG_MOVED2))
  2704.     {
  2705.         YSI_g_sObjects[objectid][E_OBJECT_MODEL] ^= e_OBJ_FLAG_MOVED;
  2706.     }
  2707.     else
  2708.     {
  2709.         YSI_g_sObjects[objectid][E_OBJECT_MODEL] = (YSI_g_sObjects[objectid][E_OBJECT_MODEL] & ~e_OBJ_FLAG_MOVED) | e_OBJ_FLAG_MOVED1;
  2710.     }
  2711.     YSI_g_sObjects[objectid][E_OBJECT_MX] = X;
  2712.     YSI_g_sObjects[objectid][E_OBJECT_MY] = Y;
  2713.     YSI_g_sObjects[objectid][E_OBJECT_MZ] = Z;
  2714.     YSI_g_sObjects[objectid][E_OBJECT_MS] = S;
  2715.     Object_RemoveFromSector(YSI_g_sObjects[objectid][E_OBJECT_SECTOR], objectid);
  2716.     Object_AddToMovingList(objectid);
  2717.     #if !defined NO_OBJECT_ATTACH
  2718.         new
  2719.             child = YSI_g_sObjects[objectid][E_OBJECT_CHILDREN];
  2720.         while (child != NO_OBJECT)
  2721.         {
  2722.             Object_Move(child, X + YSI_g_sObjects[child][E_OBJECT_X], Y + YSI_g_sObjects[child][E_OBJECT_Y], Z + YSI_g_sObjects[child][E_OBJECT_Z], S);
  2723.             child = YSI_g_sObjects[child][E_OBJECT_SIBLINGS];
  2724.         }
  2725.     #endif
  2726. }
  2727. #endif
  2728.  
  2729. /*----------------------------------------------------------------------------*-
  2730. Function:
  2731.     AttachObjectToObject
  2732. Params:
  2733.     attachobject - Object to attach.
  2734.     toobject - Object to attach to.
  2735. Return:
  2736.     -
  2737. Notes:
  2738.     Variables named to hopefully avoid confusion.  Now checks the parent is not
  2739.     a descendent of the child to avoid infinate loops.
  2740. -*----------------------------------------------------------------------------*/
  2741.  
  2742. stock AttachObjectToObject(attachobject, toobject)
  2743. {
  2744.     #if !defined NO_OBJECT_ATTACH
  2745.         #if defined _YSI_SETUP_MASTER
  2746.             if (YSI_g_sIsMaster)
  2747.             {
  2748.         #endif
  2749.                 if (Object_IsValid(attachobject) && Object_IsValid(toobject))
  2750.                 {
  2751.                     if (Object_CheckDescendant(toobject, attachobject)) return 0;
  2752.                     new
  2753.                         Float:px,
  2754.                         Float:py,
  2755.                         Float:pz,
  2756.                         Float:cx,
  2757.                         Float:cy,
  2758.                         Float:cz;
  2759.                     Object_GetPos(toobject, px, py, pz);
  2760.                     Object_GetPos(attachobject, cx, cy, cz);
  2761.                     new
  2762.                         parent = YSI_g_sObjects[attachobject][E_OBJECT_PARENT];
  2763.                     if (parent != NO_OBJECT) Object_RemoveFromParent(attachobject, parent);
  2764.                     Object_AddToParent(attachobject, toobject);
  2765.                     YSI_g_sObjects[attachobject][E_OBJECT_X] = cx - px;
  2766.                     YSI_g_sObjects[attachobject][E_OBJECT_Y] = cy - py;
  2767.                     YSI_g_sObjects[attachobject][E_OBJECT_Z] = cz - pz;
  2768.                     return 1;
  2769.                 }
  2770.         #if defined _YSI_SETUP_MASTER
  2771.             }
  2772.             else
  2773.             {
  2774.                 CallRemoteFunction("Object_Remote", "iii", attachobject, toobject, E_OBJECT_REMOTE_ATTACHOO);
  2775.                 return getproperty(0, "YSIReq");
  2776.             }
  2777.         #endif
  2778.     #else
  2779.         #pragma unused attachobject, toobject
  2780.     #endif
  2781.     return 0;
  2782. }
  2783.  
  2784. /*----------------------------------------------------------------------------*-
  2785. Function:
  2786.     Object_IsDesendant
  2787. Params:
  2788.     objectid - Object to check.
  2789.     ancestor - Object to check family tree of for objectid.
  2790. Return:
  2791.     -
  2792. Notes:
  2793.     Checks if objectid is a descendant of the ancestor object.
  2794. -*----------------------------------------------------------------------------*/
  2795.  
  2796. stock Object_IsDescendant(objectid, ancestor)
  2797. {
  2798.     #if !defined NO_OBJECT_ATTACH
  2799.         #if defined _YSI_SETUP_MASTER
  2800.             if (YSI_g_sIsMaster)
  2801.             {
  2802.         #endif
  2803.                 if (Object_IsValid(objectid) && Object_IsValid(ancestor))
  2804.                 {
  2805.                     return Object_CheckDescendant(objectid, ancestor);
  2806.                 }
  2807.         #if defined _YSI_SETUP_MASTER
  2808.             }
  2809.             else
  2810.             {
  2811.                 CallRemoteFunction("Object_Remote", "iii", objectid, ancestor, E_OBJECT_REMOTE_CHECKDESC);
  2812.                 return getproperty(0, "YSIReq");
  2813.             }
  2814.         #endif
  2815.     #else
  2816.         #pragma unused objectid, ancestor
  2817.     #endif
  2818.     return 0;
  2819. }
  2820.  
  2821. /*----------------------------------------------------------------------------*-
  2822. Function:
  2823.     Object_CheckDesendant
  2824. Params:
  2825.     objectid - Object to check.
  2826.     ancestor - Object to check family tree of for objectid.
  2827. Return:
  2828.     -
  2829. Notes:
  2830.     Recursive call for Object_IsDescendant.
  2831. -*----------------------------------------------------------------------------*/
  2832.  
  2833. static stock Object_CheckDescendant(objectid, ancestor)
  2834. {
  2835.     if (objectid == ancestor) return 1;
  2836.     new
  2837.         child = YSI_g_sObjects[ancestor][E_OBJECT_CHILDREN];
  2838.     while (child != NO_OBJECT)
  2839.     {
  2840.         if (Object_CheckDescendant(objectid, child)) return 1;
  2841.         child = YSI_g_sObjects[child][E_OBJECT_SIBLINGS];
  2842.     }
  2843.     return 0;
  2844. }
  2845.  
  2846. /*----------------------------------------------------------------------------*-
  2847. Function:
  2848.     RemoveObjectFromParent
  2849. Params:
  2850.     objectid - Object to remove from it's parent.
  2851. Return:
  2852.     -
  2853. Notes:
  2854.     -
  2855. -*----------------------------------------------------------------------------*/
  2856.  
  2857. stock RemoveObjectFromParent(objectid)
  2858. {
  2859.     #if !defined NO_OBJECT_ATTACH
  2860.         #if defined _YSI_SETUP_MASTER
  2861.             if (YSI_g_sIsMaster)
  2862.             {
  2863.         #endif
  2864.                 if (Object_IsValid(objectid))
  2865.                 {
  2866.                     new
  2867.                         parent = YSI_g_sObjects[objectid][E_OBJECT_PARENT];
  2868.                     if (parent != NO_OBJECT)
  2869.                     {
  2870.                         new
  2871.                             Float:x,
  2872.                             Float:y,
  2873.                             Float:z;
  2874.                         Object_GetPos(objectid, x, y, z);
  2875.                         Object_RemoveFromParent(objectid, parent);
  2876.                         YSI_g_sObjects[objectid][E_OBJECT_X] = x;
  2877.                         YSI_g_sObjects[objectid][E_OBJECT_Y] = y;
  2878.                         YSI_g_sObjects[objectid][E_OBJECT_Z] = z;
  2879.                     }
  2880.                 }
  2881.         #if defined _YSI_SETUP_MASTER
  2882.             }
  2883.             else
  2884.             {
  2885.                 CallRemoteFunction("Object_Remote", "iii", objectid, 0, E_OBJECT_REMOTE_REMOO);
  2886.             }
  2887.         #endif
  2888.     #else
  2889.         #pragma unused objectid
  2890.     #endif
  2891. }
  2892.  
  2893. #if !defined NO_OBJECT_ATTACH
  2894.  
  2895. /*----------------------------------------------------------------------------*-
  2896. Function:
  2897.     Object_RemoveFromParent
  2898. Params:
  2899.     objectid - Object to remove from an object.
  2900.     parent - Object to remove from.
  2901. Return:
  2902.     -
  2903. Notes:
  2904.     Removes an object from another object's children list.  Has parent passed
  2905.     as existance is checked in calling function so is already retrieved.
  2906. -*----------------------------------------------------------------------------*/
  2907.  
  2908. static stock Object_RemoveFromParent(objectid, parent)
  2909. {
  2910.     new
  2911.         children = YSI_g_sObjects[parent][E_OBJECT_CHILDREN],
  2912.         next;
  2913.     if (children == objectid)
  2914.     {
  2915.         YSI_g_sObjects[parent][E_OBJECT_CHILDREN] = YSI_g_sObjects[objectid][E_OBJECT_SIBLINGS];
  2916.     }
  2917.     else
  2918.     {
  2919.         while ((next = YSI_g_sObjects[children][E_OBJECT_SIBLINGS]) != objectid) children = next;
  2920.         YSI_g_sObjects[children][E_OBJECT_SIBLINGS] = YSI_g_sObjects[objectid][E_OBJECT_SIBLINGS];
  2921.     }
  2922.     YSI_g_sObjects[objectid][E_OBJECT_PARENT] = NO_OBJECT;
  2923.     YSI_g_sObjects[objectid][E_OBJECT_SIBLINGS] = NO_OBJECT;
  2924. }
  2925.  
  2926. /*----------------------------------------------------------------------------*-
  2927. Function:
  2928.     Object_AddToParent
  2929. Params:
  2930.     objectid - Object to attach.
  2931.     parentid - Object to attach to.
  2932. Return:
  2933.     -
  2934. Notes:
  2935.     Adds an object to another objects child list.
  2936. -*----------------------------------------------------------------------------*/
  2937.  
  2938. static stock Object_AddToParent(objectid, parentid)
  2939. {
  2940.     if (YSI_g_sObjects[objectid][E_OBJECT_PARENT] == NO_OBJECT)
  2941.     {
  2942.         YSI_g_sObjects[objectid][E_OBJECT_SIBLINGS] = YSI_g_sObjects[parentid][E_OBJECT_CHILDREN];
  2943.         YSI_g_sObjects[objectid][E_OBJECT_PARENT] = parentid;
  2944.         YSI_g_sObjects[parentid][E_OBJECT_CHILDREN] = objectid;
  2945.     }
  2946. }
  2947.  
  2948. #endif
  2949.  
  2950. /*----------------------------------------------------------------------------*-
  2951. Function:
  2952.     StopDynamicObject
  2953. Params:
  2954.     objectid - Object to stop.
  2955. Return:
  2956.     -
  2957. Notes:
  2958.     Stops an object and reassigns it's sector.
  2959. -*----------------------------------------------------------------------------*/
  2960.  
  2961. stock StopDynamicObject(objectid)
  2962. {
  2963.     #if defined _YSI_SETUP_MASTER
  2964.         if (YSI_g_sIsMaster)
  2965.         {
  2966.     #endif
  2967.             if (Object_IsValid(objectid))
  2968.             {
  2969.                 Object_RemoveFromSector(OBJECT_NO_SECTOR, objectid);
  2970.                 new
  2971.                     Float:x,
  2972.                     Float:y,
  2973.                     Float:z;
  2974.                 Object_GetPos(objectid, x, y, z);
  2975.                 Object_AddToSector(Object_FindSector(x, y, z), objectid, YSI_g_sObjects[objectid][E_OBJECT_VIEW]);
  2976.                 YSI_g_sObjects[objectid][E_OBJECT_MODEL] = (YSI_g_sObjects[objectid][E_OBJECT_MODEL] & ~(e_OBJ_FLAG_MOVED)) | e_OBJ_FLAG_RECREATED;
  2977.                 YSI_g_sObjects[objectid][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  2978.                 YSI_g_sSomethingMoved = objectid;
  2979.                 #if !defined NO_OBJECT_ATTACH
  2980.                     Object_UpdateAttach(YSI_g_sObjects[objectid][E_OBJECT_CHILDREN], x, y, z, x, y, z);
  2981.                 #endif
  2982.             }
  2983.     #if defined _YSI_SETUP_MASTER
  2984.         }
  2985.         else
  2986.         {
  2987.             CallRemoteFunction("Object_Remote", "iii", objectid, 0, E_OBJECT_REMOTE_STOP);
  2988.         }
  2989.     #endif
  2990. }
  2991.  
  2992. #if !defined NO_OBJECTS_MOVE
  2993.  
  2994. /*----------------------------------------------------------------------------*-
  2995. Function:
  2996.     Object_Update
  2997. Params:
  2998.     objectid - Object to process.
  2999.     Float:elapsedTime - Time since last update in seconds.
  3000. Return:
  3001.     -
  3002. Notes:
  3003.     Updates a moving object's position in our internal memory based on speed
  3004.     and time (d = s * t)
  3005. -*----------------------------------------------------------------------------*/
  3006.  
  3007. static Object_Update(objectid, Float:elapsedTime)
  3008. {
  3009.     new
  3010.         Float:x = YSI_g_sObjects[objectid][E_OBJECT_X],
  3011.         Float:y = YSI_g_sObjects[objectid][E_OBJECT_Y],
  3012.         Float:z = YSI_g_sObjects[objectid][E_OBJECT_Z],
  3013.         Float:mx = YSI_g_sObjects[objectid][E_OBJECT_MX],
  3014.         Float:my = YSI_g_sObjects[objectid][E_OBJECT_MY],
  3015.         Float:mz = YSI_g_sObjects[objectid][E_OBJECT_MZ],
  3016.         Float:distance = elapsedTime * YSI_g_sObjects[objectid][E_OBJECT_MS],
  3017.         Float:remaining = floatsqroot(((x - mx) * (x - mx)) + ((y - my) * (y - my)) + ((z - mz) * (z - mz)));
  3018.     if (distance >= remaining)
  3019.     {
  3020.         YSI_g_sObjects[objectid][E_OBJECT_X] = mx;
  3021.         YSI_g_sObjects[objectid][E_OBJECT_Y] = my;
  3022.         YSI_g_sObjects[objectid][E_OBJECT_Z] = mz;
  3023.         new
  3024.             e_OBJ_FLAG:oldmove = YSI_g_sObjects[objectid][E_OBJECT_MODEL] & e_OBJ_FLAG_MOVED;
  3025.         if (!Object_GateMoved(objectid)) CallRemoteFunction("OnDynamicObjectMoved", "i", objectid);
  3026.         if (oldmove == YSI_g_sObjects[objectid][E_OBJECT_MODEL] & e_OBJ_FLAG_MOVED)
  3027.         {
  3028.             StopDynamicObject(objectid);
  3029.         }
  3030.         return 1;
  3031.     }
  3032.     else
  3033.     {
  3034.         remaining /= distance;
  3035.         YSI_g_sObjects[objectid][E_OBJECT_X] += (mx - x) / remaining;
  3036.         YSI_g_sObjects[objectid][E_OBJECT_Y] += (my - y) / remaining;
  3037.         YSI_g_sObjects[objectid][E_OBJECT_Z] += (mz - z) / remaining;
  3038.     }
  3039.     return 0;
  3040. }
  3041.  
  3042. #endif
  3043.  
  3044. /*----------------------------------------------------------------------------*-
  3045. Function:
  3046.     Object_Loop
  3047. Params:
  3048.     -
  3049. Return:
  3050.     -
  3051. Notes:
  3052.     Checks what objects are in the player's range repeatedly to stream them
  3053.     as required.  Only checks objects near the player, based on sectors, and
  3054.     moving objects which are handled as their own 'sector'.  If the player is
  3055.     near the edge of the grid (+/-OBJECT_BOUNDS x/y) OOB objects are also checked, only
  3056.     one sector is used for all those regardless of location.  Moving objects
  3057.     and already visible objects are assumed higher priority.
  3058.    
  3059.     Now orders objects so only the closest are displayed.
  3060.    
  3061.     Fixed moving objects.
  3062. -*----------------------------------------------------------------------------*/
  3063.  
  3064. public Object_Loop()
  3065. {
  3066.     #if defined _YSI_SETUP_MASTER
  3067.         if (!YSI_g_sIsMaster) return;
  3068.     #endif
  3069.     #if !defined NO_OBJECTS_MOVE
  3070.         static
  3071.             Float:s_fTime;
  3072.         new
  3073.             Float:tick = float(GetTickCount()) / 1000.0;
  3074.         if (YSI_g_sMovingObjects != NO_OBJECT)
  3075.         {
  3076.             new
  3077.                 Float:fTime = tick - s_fTime,
  3078.                 objectid = YSI_g_sMovingObjects;
  3079.             do
  3080.             {
  3081.                 new
  3082.                     next = YSI_g_sObjects[objectid][E_OBJECT_NEXT];
  3083.                 if (YSI_g_sObjects[objectid][E_OBJECT_MODEL] & e_OBJ_FLAG_MOVED) Object_Update(objectid, fTime);
  3084.                 if (objectid == next) break;
  3085.                 objectid = next;
  3086.             }
  3087.             while (objectid != NO_OBJECT);
  3088.         }
  3089.         s_fTime = tick;
  3090.     #endif
  3091.     foreach (Player, playerid)
  3092.     {
  3093.         static
  3094.             sectors[MAX_PLAYERS][OBJECT_VIEW_SECTORS][E_OSEC_ITTER],
  3095.             secStart[MAX_PLAYERS] = {-1, ...},
  3096.             Bit:objects[OBJECT_BITS],
  3097.             sObjList[MAY_OBJECTS][E_OBJECT_ITTER];
  3098.         new
  3099.             Float:x,
  3100.             Float:y,
  3101.             Float:z,
  3102.             world = GetPlayerVirtualWorld(playerid),
  3103.             i,
  3104.             j,
  3105.             objStart = -1,
  3106.             objEnd = -1,
  3107.             objCount;
  3108.         GetPlayerPos(playerid, x, y, z);
  3109.         if (z < 800.0)
  3110.         {
  3111.             Object_FindSectors(playerid, x, y, sectors[playerid], secStart[playerid]);
  3112.             i = secStart[playerid];
  3113.             while (i != -1)
  3114.             {
  3115.                 if (objCount >= MAY_OBJECTS && sectors[playerid][i][E_OSEC_ITTER_DIFF] >= sObjList[objEnd][E_OBJECT_ITTER_DISTANCE]) break;
  3116.                 else
  3117.                 {
  3118.                     if ((j = sectors[playerid][i][E_OSEC_ITTER_SECTOR]) == OBJECT_NO_SECTOR) Object_ParseSet(playerid, YSI_g_sOtherSector, x, y, z, world, sObjList, objStart, objEnd, objCount, false);
  3119.                     else Object_ParseSet(playerid, YSI_g_sObjectSectors[j][E_OBJ_SECTOR_POINTER], x, y, z, world, sObjList, objStart, objEnd, objCount, false);
  3120.                 }
  3121.                 i = sectors[playerid][i][E_OSEC_ITTER_NEXT];
  3122.             }
  3123.         }
  3124.         else Object_ParseSet(playerid, YSI_g_sInteriorObjects, x, y, z, world, sObjList, objStart, objEnd, objCount, false);
  3125.         #if !defined NO_OBJECTS_MOVE
  3126.             Object_ParseSet(playerid, YSI_g_sMovingObjects, x, y, z, world, sObjList, objStart, objEnd, objCount, true);
  3127.         #endif
  3128.         Object_ParseSet(playerid, YSI_g_sLODObjects, x, y, z, world, sObjList, objStart, objEnd, objCount, false);
  3129.         for (j = objStart; j != -1; j = sObjList[j][E_OBJECT_ITTER_NEXT])
  3130.         {
  3131.             Bit_Let(objects, sObjList[j][E_OBJECT_ITTER_OBJ]);
  3132.         }
  3133.         new
  3134.             object;
  3135.         for (i = 0; i < MAY_OBJECTS; i++)
  3136.         {
  3137.             new
  3138.                 objectid = i + 1;
  3139.             if ((object = YSI_g_sPlayerObjects[playerid][i] & 0xFFFFFF) != (NO_OBJECT & 0xFFFFFF) && IsValidPlayerObject(playerid, objectid))
  3140.             {
  3141.                 if (YSI_g_sSomethingMoved != NO_OBJECT)
  3142.                 {
  3143.                     new
  3144.                         e_OBJ_FLAG:flag = YSI_g_sObjects[object][E_OBJECT_MODEL];
  3145.                     if (Bit_Get(objects, object) && !(flag & e_OBJ_FLAG_RECREATED))
  3146.                     {
  3147.                         #if !defined NO_OBJECTS_MOVE
  3148.                             if  (flag & e_OBJ_FLAG_ATTACHED)
  3149.                             {
  3150.                                 AttachPlayerObjectToPlayer(playerid, objectid, Object_GetAttach(object), YSI_g_sObjects[object][E_OBJECT_X], YSI_g_sObjects[object][E_OBJECT_Y], YSI_g_sObjects[object][E_OBJECT_Z], YSI_g_sObjects[object][E_OBJECT_RX], YSI_g_sObjects[object][E_OBJECT_RY], YSI_g_sObjects[object][E_OBJECT_RZ]);
  3151.                             }
  3152.                             if (flag & e_OBJ_FLAG_MOVED != e_OBJ_FLAG:YSI_g_sPlayerObjects[playerid][i] & e_OBJ_FLAG_MOVED)
  3153.                             {
  3154.                                 YSI_g_sPlayerObjects[playerid][i] = (YSI_g_sPlayerObjects[playerid][i] & 0xFFFFFF) | _:(flag & e_OBJ_FLAG_MOVED);
  3155.                                 MovePlayerObject(playerid, objectid, YSI_g_sObjects[object][E_OBJECT_MX], YSI_g_sObjects[object][E_OBJECT_MY], YSI_g_sObjects[object][E_OBJECT_MZ], YSI_g_sObjects[object][E_OBJECT_MS]);
  3156.                                 flag |= e_OBJ_FLAG_JUMPED;
  3157.                             }
  3158.                         #endif
  3159.                         if (flag & e_OBJ_FLAG_JUMPED)
  3160.                         {
  3161.                             Object_GetPos(object, x, y, z);
  3162.                             SetPlayerObjectPos(playerid, objectid, x, y, z);
  3163.                         }
  3164.                         if (flag & e_OBJ_FLAG_ROTATED)
  3165.                         {
  3166.                             SetPlayerObjectRot(playerid, objectid, YSI_g_sObjects[object][E_OBJECT_RX], YSI_g_sObjects[object][E_OBJECT_RY], YSI_g_sObjects[object][E_OBJECT_RZ]);
  3167.                         }
  3168.                         Bit_Set(objects, object, 0, OBJECT_BITS);
  3169.                     }
  3170.                     else
  3171.                     {
  3172.                         DestroyPlayerObject(playerid, objectid);
  3173.                         YSI_g_sPlayerObjects[playerid][i] = NO_OBJECT;
  3174.                     }
  3175.                 }
  3176.                 else
  3177.                 {
  3178.                     if (Bit_Get(objects, object))
  3179.                     {
  3180.                         Bit_Set(objects, object, 0, OBJECT_BITS);
  3181.                     }
  3182.                     else
  3183.                     {
  3184.                         DestroyPlayerObject(playerid, objectid);
  3185.                         YSI_g_sPlayerObjects[playerid][i] = NO_OBJECT;
  3186.                     }
  3187.                 }
  3188.             }
  3189.         }
  3190.         for (i = objStart; i != -1; i = sObjList[i][E_OBJECT_ITTER_NEXT])
  3191.         {
  3192.             new
  3193.                 set = sObjList[i][E_OBJECT_ITTER_OBJ];
  3194.             if (Bit_Get(objects, set))
  3195.             {
  3196.                 new
  3197.                     obj = CreatePlayerObject(playerid, YSI_g_sObjects[set][E_OBJECT_MODEL] & e_OBJ_FLAG_MODEL, sObjList[i][E_OBJECT_ITTER_X], sObjList[i][E_OBJECT_ITTER_Y], sObjList[i][E_OBJECT_ITTER_Z], YSI_g_sObjects[set][E_OBJECT_RX], YSI_g_sObjects[set][E_OBJECT_RY], YSI_g_sObjects[set][E_OBJECT_RZ]);
  3198.                 if (obj != 0xFF)
  3199.                 {
  3200.                     YSI_g_sPlayerObjects[playerid][obj - 1] = set;
  3201.                     Bit_Set(objects, set, 0, OBJECT_BITS);
  3202.                     #if !defined NO_OBJECTS_MOVE
  3203.                         if  (YSI_g_sObjects[set][E_OBJECT_MODEL] & e_OBJ_FLAG_MOVED)
  3204.                         {
  3205.                             MovePlayerObject(playerid, obj, YSI_g_sObjects[set][E_OBJECT_MX], YSI_g_sObjects[set][E_OBJECT_MY], YSI_g_sObjects[set][E_OBJECT_MZ], YSI_g_sObjects[set][E_OBJECT_MS]);
  3206.                             YSI_g_sPlayerObjects[playerid][obj - 1] |= _:(YSI_g_sObjects[set][E_OBJECT_MODEL] & e_OBJ_FLAG_MOVED);
  3207.                         }
  3208.                     #endif
  3209.                 }
  3210.             }
  3211.         }
  3212.     }
  3213.     if (YSI_g_sSomethingMoved != NO_OBJECT)
  3214.     {
  3215.         for (new objectid = YSI_g_sSomethingMoved; objectid != NO_OBJECT; objectid = YSI_g_sObjects[objectid][E_OBJECT_UPDATES]) YSI_g_sObjects[objectid][E_OBJECT_MODEL] &= ~(e_OBJ_FLAG_ATTACHED | e_OBJ_FLAG_JUMPED | e_OBJ_FLAG_ROTATED | e_OBJ_FLAG_RECREATED);
  3216.         YSI_g_sSomethingMoved = NO_OBJECT;
  3217.     }
  3218. }
  3219.  
  3220. /*----------------------------------------------------------------------------*-
  3221. Function:
  3222.     Object_ParseSet
  3223. Params:
  3224.     playerid - Player to check for.
  3225.     set - Pointer to first object in the list.
  3226.     Float:x - Player's x position.
  3227.     Float:y - Player's y position.
  3228.     Float:z - Player's z position.
  3229.     world - Player's world.
  3230.     objList[][E_OBJECT_ITTER] - List of closest objects.
  3231.     &objStart - Entrypoint to list.
  3232.     &objEnd - Last object in list.
  3233.     &objCount - Number of objects in list.
  3234.     bool:dynam - Is this the dynamic set.
  3235. Return:
  3236.     -
  3237. Notes:
  3238.     Itterates through the linked list for one sector of objects and checks
  3239.     their real location relative to the player, if in range displays them.
  3240. -*----------------------------------------------------------------------------*/
  3241.  
  3242. static Object_ParseSet(playerid, set, Float:x, Float:y, Float:z, world, objList[][E_OBJECT_ITTER], &objStart, &objEnd, &objCount, bool:dynam)
  3243. {
  3244.     if (set == NO_OBJECT) return;
  3245.     new
  3246.         #if !defined NO_OBJECTS_MOVE && defined NO_OBJECT_ATTACH
  3247.             attach,
  3248.         #endif
  3249.         start = set,
  3250.         Float:px,
  3251.         Float:py,
  3252.         Float:pz,
  3253.         Float:diff;
  3254.     do
  3255.     {
  3256.         new
  3257.             e_OBJ_FLAG:flag = YSI_g_sObjects[set][E_OBJECT_MODEL];
  3258.         if (flag & e_OBJ_FLAG_ACTIVE)
  3259.         {
  3260.             if (Object_HasPlayer(set, playerid, world))
  3261.             {
  3262.                 #if !defined NO_OBJECT_ATTACH
  3263.                     Object_GetPos(set, px, py, pz);
  3264.                     #pragma unused dynam
  3265.                 #else
  3266.                     #if !defined NO_OBJECTS_MOVE
  3267.                         if (!dynam || (attach = Object_GetAttach(YSI_g_sObjects[set][E_OBJECT_MODEL])) == NO_ATTACH_PLAYER || !IsPlayerConnected(attach))
  3268.                         {
  3269.                     #endif
  3270.                             px = YSI_g_sObjects[set][E_OBJECT_X];
  3271.                             py = YSI_g_sObjects[set][E_OBJECT_Y];
  3272.                             pz = YSI_g_sObjects[set][E_OBJECT_Z];
  3273.                     #if !defined NO_OBJECTS_MOVE
  3274.                         }
  3275.                         else
  3276.                         {
  3277.                             GetPlayerPos(attach, px, py, pz);
  3278.                             px += YSI_g_sObjects[set][E_OBJECT_X];
  3279.                             py += YSI_g_sObjects[set][E_OBJECT_Y];
  3280.                             pz += YSI_g_sObjects[set][E_OBJECT_Z];
  3281.                         }
  3282.                     #else
  3283.                         #pragma unused dynam
  3284.                     #endif
  3285.                 #endif
  3286.                 new
  3287.                     Float:ox = px - x,
  3288.                     Float:oy = py - y,
  3289.                     Float:oz = pz - z;
  3290.                 diff = ((ox * ox) + (oy * oy) + (oz * oz)) / YSI_g_sObjects[set][E_OBJECT_VIEW];
  3291.                 if (diff < 1.0)
  3292.                 {
  3293.                     if (objStart == -1)
  3294.                     {
  3295.                         objList[0][E_OBJECT_ITTER_NEXT] = -1;
  3296.                         objList[0][E_OBJECT_ITTER_LAST] = -1;
  3297.                         objList[0][E_OBJECT_ITTER_OBJ] = set;
  3298.                         objList[0][E_OBJECT_ITTER_DISTANCE] = diff;
  3299.                         objList[0][E_OBJECT_ITTER_X] = px;
  3300.                         objList[0][E_OBJECT_ITTER_Y] = py;
  3301.                         objList[0][E_OBJECT_ITTER_Z] = pz;
  3302.                         objStart = 0;
  3303.                         objEnd = 0;
  3304.                         objCount = 1;
  3305.                     }
  3306.                     else if (objCount < MAY_OBJECTS)
  3307.                     {
  3308.                         objList[objCount][E_OBJECT_ITTER_OBJ] = set;
  3309.                         objList[objCount][E_OBJECT_ITTER_DISTANCE] = diff;
  3310.                         objList[objCount][E_OBJECT_ITTER_X] = px;
  3311.                         objList[objCount][E_OBJECT_ITTER_Y] = py;
  3312.                         objList[objCount][E_OBJECT_ITTER_Z] = pz;
  3313.                         if (objList[objEnd][E_OBJECT_ITTER_DISTANCE] < diff)
  3314.                         {
  3315.                             objList[objCount][E_OBJECT_ITTER_LAST] = objEnd;
  3316.                             objList[objCount][E_OBJECT_ITTER_NEXT] = -1;
  3317.                             objList[objEnd][E_OBJECT_ITTER_NEXT] = objCount;
  3318.                             objEnd = objCount++;
  3319.                         }
  3320.                         else
  3321.                         {
  3322.                             new
  3323.                                 i = objStart,
  3324.                                 j = -1;
  3325.                             while (objList[i][E_OBJECT_ITTER_DISTANCE] < diff) i = objList[(j = i)][E_OBJECT_ITTER_NEXT];
  3326.                             objList[objCount][E_OBJECT_ITTER_NEXT] = i;
  3327.                             objList[objCount][E_OBJECT_ITTER_LAST] = j;
  3328.                             objList[i][E_OBJECT_ITTER_LAST] = objCount;
  3329.                             if (j == -1) objStart = objCount++;
  3330.                             else objList[j][E_OBJECT_ITTER_NEXT] = objCount++;
  3331.                         }
  3332.                     }
  3333.                     else if (objList[objEnd][E_OBJECT_ITTER_DISTANCE] > diff)
  3334.                     {
  3335.                         new
  3336.                             i = objStart,
  3337.                             j = -1,
  3338.                             newend = objList[objEnd][E_OBJECT_ITTER_LAST];
  3339.                         while (objList[i][E_OBJECT_ITTER_DISTANCE] < diff) i = objList[(j = i)][E_OBJECT_ITTER_NEXT];
  3340.                         objList[objEnd][E_OBJECT_ITTER_OBJ] = set;
  3341.                         objList[objEnd][E_OBJECT_ITTER_DISTANCE] = diff;
  3342.                         objList[objEnd][E_OBJECT_ITTER_X] = px;
  3343.                         objList[objEnd][E_OBJECT_ITTER_Y] = py;
  3344.                         objList[objEnd][E_OBJECT_ITTER_Z] = pz;
  3345.                         if (i != objEnd)
  3346.                         {
  3347.                             objList[objEnd][E_OBJECT_ITTER_NEXT] = i;
  3348.                             objList[objEnd][E_OBJECT_ITTER_LAST] = j;
  3349.                             objList[i][E_OBJECT_ITTER_LAST] = objEnd;
  3350.                             if (j == -1) objStart = objEnd;
  3351.                             else objList[j][E_OBJECT_ITTER_NEXT] = objEnd;
  3352.                             objEnd = newend;
  3353.                             objList[newend][E_OBJECT_ITTER_NEXT] = -1;
  3354.                         }
  3355.                     }
  3356.                 }
  3357.             }
  3358.         }
  3359.         set = YSI_g_sObjects[set][E_OBJECT_NEXT];
  3360.     }
  3361.     while (set != start);
  3362. }
  3363.  
  3364. /*----------------------------------------------------------------------------*-
  3365. Function:
  3366.     Object_FindSectors
  3367. Params:
  3368.     playerid - Player we're finding the sectors for.
  3369.     Float:x - X location to check.
  3370.     Float:y - Y location to check.
  3371.     sectors[OBJECT_VIEW_SECTORS][E_OSEC_ITTER] - Array to store all visible sectors.
  3372.     &secStart - Start point to itterator
  3373. Return:
  3374.     -
  3375. Notes:
  3376.     Finds all the sectors which encompas points within the sight range of the
  3377.     player.  Initial checks are done as a square so some returned sectors may
  3378.     not have points within a circular range of the player.
  3379.    
  3380.     The original version tested if the edges of each sector were visible and
  3381.     if not excluded them from the list.  This would have been faster in terms
  3382.     of objects checked but slower if there were no objects, which is likely to
  3383.     be more frequently the case.  The code also didn't actually work but that's
  3384.     a minor point as the theory was there.  This is also alot neater.
  3385.    
  3386.     Rewritten to not use Object_FindSector on a new area, just calculate the
  3387.     area from known initial area.
  3388.    
  3389.     Now also only returns the zones visible, not the zones theoretically
  3390.     visible (still assumes square vision though which the code doesn't use).
  3391. -*----------------------------------------------------------------------------*/
  3392.  
  3393. static Object_FindSectors(playerid, Float:x, Float:y, sectors[][E_OSEC_ITTER], &secStart)
  3394. {
  3395.     static
  3396.         sLastCheck[MAX_PLAYERS],
  3397.         sLX[MAX_PLAYERS] = {cellmin, ...},
  3398.         sLY[MAX_PLAYERS] = {cellmax, ...};
  3399.     new
  3400.         xsector = floatround(((x - OBJECT_BOUNDS_MINX) / YSI_g_sXSectorSize), floatround_floor),
  3401.         ysector = floatround(((y - OBJECT_BOUNDS_MINY) / YSI_g_sYSectorSize), floatround_floor);
  3402.     if (!sLastCheck[playerid] || sLX[playerid] != xsector || sLY[playerid] != ysector)
  3403.     {
  3404.         secStart = -1;
  3405.         new
  3406.             go = 0,
  3407.             Float:diff = 10.0,
  3408.             xstart = -OBJECT_VIEW_RATIO,
  3409.             xend = OBJECT_VIEW_RATIO,
  3410.             ystart = -OBJECT_VIEW_RATIO,
  3411.             yend = OBJECT_VIEW_RATIO,
  3412.             k;
  3413.         if (xsector < -OBJECT_VIEW_RATIO)
  3414.         {
  3415.             xstart = cellmax;
  3416.             go = 1;
  3417.             diff = 0.0;
  3418.         }
  3419.         else if (xsector < OBJECT_VIEW_RATIO)
  3420.         {
  3421.             xstart = 0 - xsector;
  3422.             go = 1;
  3423.             new
  3424.                 Float:nd = ((x - OBJECT_BOUNDS_MINX) * (x - OBJECT_BOUNDS_MINX)) / (OBJECT_MAX_VIEW_DISTANCE * OBJECT_MAX_VIEW_DISTANCE);
  3425.             if (nd < diff) diff = nd;
  3426.         }
  3427.         if (ysector < -OBJECT_VIEW_RATIO)
  3428.         {
  3429.             ystart = cellmax;
  3430.             go = 1;
  3431.             diff = 0.0;
  3432.         }
  3433.         else if (ysector < OBJECT_VIEW_RATIO)
  3434.         {
  3435.             ystart = 0 - ysector;
  3436.             go = 1;
  3437.             new
  3438.                 Float:nd = ((y - OBJECT_BOUNDS_MINY) * (y - OBJECT_BOUNDS_MINY)) / (OBJECT_MAX_VIEW_DISTANCE * OBJECT_MAX_VIEW_DISTANCE);
  3439.             if (nd < diff) diff = nd;
  3440.         }
  3441.         if (xsector >= OBJECT_SECTOR_X_EDGE + OBJECT_VIEW_RATIO)
  3442.         {
  3443.             xend = cellmin;
  3444.             go = 1;
  3445.             diff = 0.0;
  3446.         }
  3447.         else if (xsector >= OBJECT_SECTOR_X_EDGE - OBJECT_VIEW_RATIO)
  3448.         {
  3449.             xend = OBJECT_SECTOR_X_EDGE - (xsector + 1);
  3450.             if (xsector >= OBJECT_SECTOR_X_EDGE)
  3451.             {
  3452.                 go = 1;
  3453.                 diff = 0.0;
  3454.             }
  3455.             else if (go == -1 || go > xend + 1)
  3456.             {
  3457.                 go = 1;
  3458.                 new
  3459.                     Float:nd = ((x - OBJECT_BOUNDS_MAXX) * (x - OBJECT_BOUNDS_MAXX)) / (OBJECT_MAX_VIEW_DISTANCE * OBJECT_MAX_VIEW_DISTANCE);
  3460.                 if (nd < diff) diff = nd;
  3461.             }
  3462.         }
  3463.         if (ysector >= OBJECT_SECTOR_Y_EDGE + OBJECT_VIEW_RATIO)
  3464.         {
  3465.             yend = cellmin;
  3466.             go = 1;
  3467.             diff = 0.0;
  3468.         }
  3469.         else if (ysector >= OBJECT_SECTOR_Y_EDGE - OBJECT_VIEW_RATIO)
  3470.         {
  3471.             yend = OBJECT_SECTOR_Y_EDGE - (ysector + 1);
  3472.             if (ysector >= OBJECT_SECTOR_Y_EDGE)
  3473.             {
  3474.                 go = 1;
  3475.                 diff = 0.0;
  3476.             }
  3477.             else if (go == -1 || go > yend + 1)
  3478.             {
  3479.                 go = 1;
  3480.                 new
  3481.                     Float:nd = ((y - OBJECT_BOUNDS_MAXY) * (y - OBJECT_BOUNDS_MAXY)) / (OBJECT_MAX_VIEW_DISTANCE * OBJECT_MAX_VIEW_DISTANCE);
  3482.                 if (nd < diff) diff = nd;
  3483.             }
  3484.         }
  3485.         if (go)
  3486.         {
  3487.             go = 0;
  3488.             sectors[0][E_OSEC_ITTER_SECTOR] = OBJECT_NO_SECTOR;
  3489.             sectors[0][E_OSEC_ITTER_DIFF] = diff;
  3490.             sectors[0][E_OSEC_ITTER_NEXT] = -1;
  3491.             secStart = 0;
  3492.             k = 1;
  3493.         }
  3494.         else secStart = -1;
  3495.         for (new i = xstart; i <= xend; i++)
  3496.         {
  3497.             new
  3498.                 xsec = xsector + i;
  3499.             new
  3500.                 Float:xsmin = x - YSI_g_sXSectorLocations[xsec + 1],
  3501.                 Float:xsmax = YSI_g_sXSectorLocations[xsec] - x;
  3502.             if (i > 0)
  3503.             {
  3504.                 if (xsmax < OBJECT_MAX_VIEW_DISTANCE) go = 1;
  3505.                 else break;
  3506.             }
  3507.             else if (i < 0)
  3508.             {
  3509.                 if (xsmin < OBJECT_MAX_VIEW_DISTANCE) go = 1;
  3510.             }
  3511.             else go = 1;
  3512.             if (go)
  3513.             {
  3514.                 go = 0;
  3515.                 for (new j = ystart; j <= yend; j++)
  3516.                 {
  3517.                     new
  3518.                         ysec = ysector + j,
  3519.                         cursec = (xsec * OBJECT_SECTOR_X_EDGE) + ysec;
  3520.                     diff = 10.0;
  3521.                     if (i || j)
  3522.                     {
  3523.                         new
  3524.                             Float:ysmin = y - YSI_g_sYSectorLocations[ysec + 1],
  3525.                             Float:ysmax = YSI_g_sYSectorLocations[ysec] - y;
  3526.                         if (j > 0)
  3527.                         {
  3528.                             if (ysmax < OBJECT_MAX_VIEW_DISTANCE) go = 1;
  3529.                             else
  3530.                             {
  3531.                                 yend--;
  3532.                                 break;
  3533.                             }
  3534.                         }
  3535.                         else if (j < 0)
  3536.                         {
  3537.                             if (ysmin < OBJECT_MAX_VIEW_DISTANCE) go = 1;
  3538.                             else ystart++;
  3539.                         }
  3540.                         else go = 1;
  3541.                         if (go)
  3542.                         {
  3543.                             go = 0;
  3544.                             if (!i) diff = (j < 0) ? (ysmin * ysmin) : (ysmax * ysmax);
  3545.                             else if (!j) diff = (i < 0) ? (xsmin * xsmin) : (xsmax * xsmax);
  3546.                             else if (i < 0) diff = (j < 0) ? ((ysmin * ysmin) + (xsmin * xsmin)) : ((ysmax * ysmax) + (xsmin * xsmin));
  3547.                             else if (i > 0) diff = (j < 0) ? ((ysmin * ysmin) + (xsmax * xsmax)) : ((ysmax * ysmax) + (xsmax * xsmax));
  3548.                             diff /= YSI_g_sObjectSectors[cursec][E_OBJ_SECTOR_MAX_VIEW];
  3549.                         }
  3550.                     }
  3551.                     else diff = 0.0;
  3552.                     if (diff < 1.0)
  3553.                     {
  3554.                         new
  3555.                             itterCur = secStart,
  3556.                             itterLast = -1;
  3557.                         while (itterCur != -1 && sectors[itterCur][E_OSEC_ITTER_DIFF] < diff) itterCur = sectors[(itterLast = itterCur)][E_OSEC_ITTER_NEXT];
  3558.                         if (itterLast == -1) secStart = k;
  3559.                         else sectors[itterLast][E_OSEC_ITTER_NEXT] = k;
  3560.                         sectors[k][E_OSEC_ITTER_NEXT] = itterCur;
  3561.                         sectors[k][E_OSEC_ITTER_SECTOR] = cursec;
  3562.                         sectors[k][E_OSEC_ITTER_DIFF] = diff;
  3563.                         k++;
  3564.                     }
  3565.                 }
  3566.             }
  3567.         }
  3568.         sLastCheck[playerid] = SECTOR_CHECK_FREQUENCY;
  3569.         sLX[playerid] = xsector;
  3570.         sLY[playerid] = ysector;
  3571.     }
  3572.     sLastCheck[playerid]--;
  3573.     return 1;
  3574. }
  3575.  
  3576. /*----------------------------------------------------------------------------*-
  3577. Function:
  3578.     Object_IsValidModel
  3579. Params:
  3580.     modelid - Model to check won't crash SA.
  3581. Return:
  3582.     -
  3583. Notes:
  3584.     I wrote this function a long time ago and have barely updated it at all.
  3585.     The only changes are the formatting and the use of the Bit class now,
  3586.     despite the fact this was the first large bit array I did and is thus
  3587.     the founding array of the whole idea behind the bit class.
  3588. -*----------------------------------------------------------------------------*/
  3589.  
  3590. stock Object_IsValidModel(modelid)
  3591. {
  3592.     static
  3593.         modeldat[] =
  3594.         {
  3595.             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128,
  3596.             -515899393, -134217729, -1, -1, 33554431, -1, -1, -1, -14337, -1, -33,
  3597.             127, 0, 0, 0, 0, 0, -8388608, -1, -1, -1, -16385, -1, -1, -1, -1, -1,
  3598.             -1, -1, -33, -1, -771751937, -1, -9, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  3599.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  3600.             -1, -1, -1, -1, -1, -1, -1, -1, 33554431, -25, -1, -1, -1, -1, -1, -1,
  3601.             -1073676289, -2147483648, 34079999, 2113536, -4825600, -5, -1, -3145729,
  3602.             -1, -16777217, -63, -1, -1, -1, -1, -201326593, -1, -1, -1, -1, -1,
  3603.             -257, -1, 1073741823, -133122, -1, -1, -65, -1, -1, -1, -1, -1, -1,
  3604.             -2146435073, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1073741823, -64, -1,
  3605.             -1, -1, -1, -2635777, 134086663, 0, -64, -1, -1, -1, -1, -1, -1, -1,
  3606.             -536870927, -131069, -1, -1, -1, -1, -1, -1, -1, -1, -16384, -1,
  3607.             -33554433, -1, -1, -1, -1, -1, -1610612737, 524285, -128, -1,
  3608.             2080309247, -1, -1, -1114113, -1, -1, -1, 66977343, -524288, -1, -1, -1,
  3609.             -1, -2031617, -1, 114687, -256, -1, -4097, -1, -4097, -1, -1,
  3610.             1010827263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -32768, -1, -1, -1, -1, -1,
  3611.             2147483647, -33554434, -1, -1, -49153, -1148191169, 2147483647,
  3612.             -100781080, -262145, -57, 134217727, -8388608, -1, -1, -1, -1, -1, -1,
  3613.             -1, -1, -1, -1, -1, -1, -1, -1, -1048577, -1, -449, -1017, -1, -1, -1,
  3614.             -1, -1, -1, -1, -1, -1, -1, -1, -1835009, -2049, -1, -1, -1, -1, -1, -1,
  3615.             -8193, -1, -536870913, -1, -1, -1, -1, -1, -87041, -1, -1, -1, -1, -1,
  3616.             -1, -209860, -1023, -8388609, -2096897, -1, -1048577, -1, -1, -1, -1,
  3617.             -1, -1, -897, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1610612737,
  3618.             -3073, -28673, -1, -1, -1, -1537, -1, -1, -13, -1, -1, -1, -1, -1985,
  3619.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1056964609, -1, -1, -1,
  3620.             -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  3621.             -236716037, -1, -1, -1, -1, -1, -1, -1, -536870913, 3, 0, 0, 0, 0, 0, 0,
  3622.             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  3623.             0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  3624.             -1, -1, -1, -1, -1, -2097153, -2109441, -1, 201326591, -4194304, -1, -1,
  3625.             -241, -1, -1, -1, -1, -1, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  3626.             0, -32768, -1, -1, -1, -2, -671096835, -1, -8388609, -66323585, -13,
  3627.             -1793, -32257, -247809, -1, -1, -513, 16252911, 0, 0, 0, -131072,
  3628.             33554383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  3629.             0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  3630.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8356095, 0, 0, 0, 0, 0,
  3631.             0, -256, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  3632.             -268435449, -1, -1, -2049, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  3633.             92274627, -65536, -2097153, -268435457, 591191935, 1, 0, -16777216, -1,
  3634.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 127
  3635.         };
  3636.     return Bit_Get(Bit:modeldat, modelid);
  3637. }
  3638.  
  3639. /*----------------------------------------------------------------------------*-
  3640. Function:
  3641.     Object_OnPlayerDisconnect
  3642. Params:
  3643.     playerid - Player who left.
  3644.     reason - Why they left.
  3645. Return:
  3646.     -
  3647. Notes:
  3648.     Just to automatically disconnect attached objects from players.
  3649. -*----------------------------------------------------------------------------*/
  3650.  
  3651. Object_OnPlayerDisconnect(playerid, reason)
  3652. {
  3653.     #if defined _YSI_SETUP_MASTER
  3654.         if (!YSI_g_sIsMaster) return 0;
  3655.     #endif
  3656.     for (new objectid = 0; objectid < MAY_OBJECTS; objectid++)
  3657.     {
  3658.         YSI_g_sPlayerObjects[playerid][objectid] = NO_OBJECT;
  3659.     }
  3660.     #if !defined NO_OBJECTS_MOVE
  3661.         new
  3662.             sets = YSI_g_sMovingObjects;
  3663.         if (sets == NO_OBJECT) return 0;
  3664.         new
  3665.             start = sets;
  3666.         do
  3667.         {
  3668.             new
  3669.                 e_OBJ_FLAG:flag = YSI_g_sObjects[sets][E_OBJECT_MODEL];
  3670.             if (flag & e_OBJ_FLAG_ACTIVE)
  3671.             {
  3672.                 if (Object_GetAttach(flag) == playerid) DetachDynamicObjectFromPlayer(sets);
  3673.             }
  3674.             sets = YSI_g_sObjects[sets][E_OBJECT_NEXT];
  3675.         }
  3676.         while (sets != start);
  3677.     #endif
  3678.     return 1;
  3679.     #pragma unused reason
  3680. }
  3681.  
  3682. /*----------------------------------------------------------------------------*-
  3683. Function:
  3684.     Object_SetGateTarget
  3685. Params:
  3686.     gate - Gate to set target for.
  3687.     Float:tx - X point to open to.
  3688.     Float:ty - Y point to open to.
  3689.     Float:tz - Z point to open to.
  3690.     Float:ts - Speed to open at.
  3691. Return:
  3692.     -
  3693. Notes:
  3694.     Stores a location into the two variables provided for targets.  Uses
  3695.     complex bit shifting to fit the floats nicely into 2 cells.  Assumes a max
  3696.     of +/-13107.2 for x, y and z and a max of 102.4 for the speed to compress.
  3697. -*----------------------------------------------------------------------------*/
  3698.  
  3699. #define Object_SetGateTarget(%1,%2,%3,%4,%5) \
  3700.     new \
  3701.         _o_sgt_y = floatround((%3) * 10); \
  3702.     YSI_g_sGateInfo[(%1)][E_GATE_INFO_XY] = ((floatround((%2) * 10) & 0x3FFFF) << 14) | (_o_sgt_y & 0x3FFF); \
  3703.     YSI_g_sGateInfo[(%1)][E_GATE_INFO_ZA] = ((_o_sgt_y & 0x3C000) << 14) | ((floatround((%4) * 10) & 0x3FFFF) << 10) | (floatround((%5) * 10) & 0x3FF)
  3704.  
  3705. /*----------------------------------------------------------------------------*-
  3706. Function:
  3707.     Object_SetAreaGate
  3708. Params:
  3709.     objectid - Object to make into a gate.
  3710.     areaid - Area to trigger gate in.
  3711.     Float:tx - X point to open to.
  3712.     Float:ty - Y point to open to.
  3713.     Float:tz - Z point to open to.
  3714.     Float:ts - Speed to open at.
  3715. Return:
  3716.     -
  3717. Notes:
  3718.     Just to automatically disconnect attached objects from players.
  3719. -*----------------------------------------------------------------------------*/
  3720.  
  3721. stock Object_SetAreaGate(objectid, areaid, Float:tx, Float:ty, Float:tz, Float:ts, time = 10000)
  3722. {
  3723.     #if defined _YSI_SETUP_MASTER
  3724.         if (YSI_g_sIsMaster)
  3725.         {
  3726.     #endif
  3727.             #if !defined NO_OBJECTS_MOVE
  3728.                 #if defined _YSI_VISUAL_AREAS
  3729.                     if (Object_IsValid(objectid) && !Object_IsAttached(YSI_g_sObjects[objectid][E_OBJECT_MODEL]) && Area_IsValid(areaid))
  3730.                     {
  3731.                         new
  3732.                             gate;
  3733.                         while (gate < MAX_GATE_OBJECTS)
  3734.                         {
  3735.                             if (!YSI_g_sGateInfo[gate][E_GATE_INFO_OBJECT]) break;
  3736.                             gate++;
  3737.                         }
  3738.                         if (gate == MAX_GATE_OBJECTS) return NO_GATE;
  3739.                        
  3740.                         YSI_g_sGateInfo[gate][E_GATE_INFO_OBJECT] = objectid | GATE_AREA_TRIGGER;
  3741.                         YSI_g_sGateInfo[gate][E_GATE_INFO_TIME] = time;
  3742.                         YSI_g_sGateInfo[gate][E_GATE_INFO_TRIGGER] = areaid;
  3743.                         YSI_g_sObjects[objectid][E_OBJECT_MODEL] |= e_OBJ_FLAG_GATE;
  3744.                         Object_SetGateTarget(gate, tx, ty, tz, ts);
  3745.                         #if !defined NO_GATE_AREA_LOOKUP
  3746.                             new
  3747.                                 slot = areaid / 2,
  3748.                                 shift = (areaid % 2) * 16;
  3749.                             YSI_g_sGateAreas[slot] = (YSI_g_sGateAreas[slot] & (0xFFFF0000 >> shift)) | (gate << shift);
  3750.                         #endif
  3751.                         return gate;
  3752.                     }
  3753.                 #endif
  3754.             #endif
  3755.             return NO_GATE;
  3756.     #if defined _YSI_SETUP_MASTER
  3757.         }
  3758.         else
  3759.         {
  3760.             CallRemoteFunction("Object_Remote", "iii", objectid, 0, E_OBJECT_REMOTE_GATE | areaid);
  3761.             return getproperty(0, "YSIReq");
  3762.         }
  3763.     #endif
  3764. }
  3765.  
  3766. #if defined _YSI_VISUAL_AREAS
  3767. /*----------------------------------------------------------------------------*-
  3768. Function:
  3769.     Object_OnPlayerEnterArea
  3770. Params:
  3771.     playerid - Player who entered an area.
  3772.     areaid - Area they entered.
  3773. Return:
  3774.     -
  3775. Notes:
  3776.     Internal callback from YSI_areas.
  3777. -*----------------------------------------------------------------------------*/
  3778.  
  3779. #if defined _YSI_SETUP_MASTER
  3780.     public Object_OnPlayerEnterArea(playerid, areaid)
  3781.     if (!YSI_g_sIsMaster) return 0;
  3782.     else
  3783. #else
  3784.     Object_OnPlayerEnterArea(playerid, areaid)
  3785. #endif
  3786. {
  3787.     #if defined _YSI_SETUP_MASTER
  3788.         setproperty(0, "YSIReq", 0);
  3789.     #endif
  3790.     #if defined NO_OBJECTS_MOVE
  3791.         return 0;
  3792.     #else
  3793.         new
  3794.             gate;
  3795.         #if defined NO_GATE_AREA_LOOKUP
  3796.             while (gate < MAX_GATE_OBJECTS)
  3797.             {
  3798.                 if (YSI_g_sGateInfo[gate][E_GATE_INFO_OBJECT] & GATE_AREA_TRIGGER && YSI_g_sGateInfo[gate][E_GATE_INFO_TRIGGER] == areaid) break;
  3799.             }
  3800.             if (gate == MAX_GATE_OBJECTS) return 0;
  3801.         #else
  3802.             gate = (YSI_g_sGateAreas[areaid / 2] >> ((areaid % 2) * 16)) & 0xFFFF;
  3803.             if (gate == 0xFFFF) return 0;
  3804.         #endif
  3805.         #if defined _YSI_SETUP_MASTER
  3806.             setproperty(0, "YSIReq", 1);
  3807.         #endif
  3808.         new
  3809.             objectid = YSI_g_sGateInfo[gate][E_GATE_INFO_OBJECT] & (~(GATE_AREA_TRIGGER | GATE_OPENING));
  3810.         if (Object_IsValid(objectid))
  3811.         {
  3812.             if (YSI_g_sObjects[objectid][E_OBJECT_MODEL] & e_OBJ_FLAG_MOVED || YSI_g_sGateInfo[gate][E_GATE_INFO_OBJECT] & GATE_OPENING) return 1;
  3813.             new
  3814.                 Float:x,
  3815.                 Float:y,
  3816.                 Float:z,
  3817.                 Float:tx = (float((YSI_g_sGateInfo[gate][E_GATE_INFO_XY] >> 14) & 0x1FFFF) * ((YSI_g_sGateInfo[gate][E_GATE_INFO_XY] & 0x80000000) ? (-1.0) : (1.0)) / 10.0),
  3818.                 Float:ty = (float((YSI_g_sGateInfo[gate][E_GATE_INFO_XY] & 0x03FFF) | ((YSI_g_sGateInfo[gate][E_GATE_INFO_ZA] >> 14) & 0x1C000)) * ((YSI_g_sGateInfo[gate][E_GATE_INFO_ZA] & 0x80000000) ? (-1.0) : (1.0)) / 10.0),
  3819.                 Float:tz = (float((YSI_g_sGateInfo[gate][E_GATE_INFO_ZA] >> 10) & 0x1FFFF) * ((YSI_g_sGateInfo[gate][E_GATE_INFO_ZA] & 0x08000000) ? (-1.0) : (1.0)) / 10.0),
  3820.                 Float:s = (float(YSI_g_sGateInfo[gate][E_GATE_INFO_ZA] & 0x3FF) / 10.0);
  3821.             Object_GetPos(objectid, x, y, z);
  3822.             YSI_g_sGateInfo[gate][E_GATE_INFO_OBJECT] |= GATE_OPENING;
  3823.             Object_SetGateTarget(gate, x, y, z, s);
  3824.             Object_Move(objectid, tx, ty, tz, s);
  3825.             YSI_g_sObjects[objectid][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  3826.             YSI_g_sSomethingMoved = objectid;
  3827.         }
  3828.         else
  3829.         {
  3830.             YSI_g_sGateInfo[gate][E_GATE_INFO_TRIGGER] = NO_GATE;
  3831.             #if !defined NO_GATE_AREA_LOOKUP
  3832.                 YSI_g_sGateAreas[areaid / 2] |= 0xFFFF << ((areaid % 2) * 16);
  3833.             #endif
  3834.             Area_Delete(areaid);
  3835.         }
  3836.         return 1;
  3837.     #endif
  3838. }
  3839. #endif
  3840.  
  3841. #if !defined NO_OBJECTS_MOVE
  3842. /*----------------------------------------------------------------------------*-
  3843. Function:
  3844.     Object_GateMoved
  3845. Params:
  3846.     objectid - Object that moved.
  3847. Return:
  3848.     -
  3849. Notes:
  3850.     Checks if the object which moved is a gate.
  3851. -*----------------------------------------------------------------------------*/
  3852.  
  3853. static stock Object_GateMoved(objectid)
  3854. {
  3855.     #if defined _YSI_VISUAL_AREAS
  3856.         if (YSI_g_sObjects[objectid][E_OBJECT_MODEL] & e_OBJ_FLAG_GATE)
  3857.         {
  3858.             new
  3859.                 gate = 0;
  3860.             while (gate < MAX_GATE_OBJECTS)
  3861.             {
  3862.                 if (objectid == (YSI_g_sGateInfo[gate][E_GATE_INFO_OBJECT] & (~(GATE_AREA_TRIGGER | GATE_OPENING)))) break;
  3863.                 gate++;
  3864.             }
  3865.             if (gate == MAX_GATE_OBJECTS)
  3866.             {
  3867.                 YSI_g_sObjects[objectid][E_OBJECT_MODEL] &= ~e_OBJ_FLAG_GATE;
  3868.                 return 0;
  3869.             }
  3870.             if (YSI_g_sGateInfo[gate][E_GATE_INFO_OBJECT] & (GATE_AREA_TRIGGER | GATE_OPENING) == (GATE_AREA_TRIGGER | GATE_OPENING))
  3871.             {
  3872.                 SetTimerEx("Object_GateClose", 5000, 0, "i", gate);
  3873.             }
  3874.             return 1;
  3875.         }
  3876.     #else
  3877.         #pragma unused objectid
  3878.     #endif
  3879.     return 0;
  3880. }
  3881. #endif
  3882.  
  3883. #if defined _YSI_VISUAL_AREAS
  3884. /*----------------------------------------------------------------------------*-
  3885. Function:
  3886.     Object_GateClose
  3887. Params:
  3888.     gate - Gate to close.
  3889. Return:
  3890.     -
  3891. Notes:
  3892.     Closes an area triggered gate after a delay.
  3893. -*----------------------------------------------------------------------------*/
  3894.  
  3895. public Object_GateClose(gate)
  3896. {
  3897.     if (Area_IsEmpty(YSI_g_sGateInfo[gate][E_GATE_INFO_TRIGGER]))
  3898.     {
  3899.         new
  3900.             objectid = YSI_g_sGateInfo[gate][E_GATE_INFO_OBJECT] & ~(GATE_AREA_TRIGGER | GATE_OPENING);
  3901.         if (Object_IsValid(objectid))
  3902.         {
  3903.             new
  3904.                 Float:x,
  3905.                 Float:y,
  3906.                 Float:z,
  3907.                 Float:tx = (float((YSI_g_sGateInfo[gate][E_GATE_INFO_XY] >> 14) & 0x1FFFF) * ((YSI_g_sGateInfo[gate][E_GATE_INFO_XY] & 0x80000000) ? (-0.1) : (0.1))),
  3908.                 Float:ty = (float((YSI_g_sGateInfo[gate][E_GATE_INFO_XY] & 0x03FFF) | ((YSI_g_sGateInfo[gate][E_GATE_INFO_ZA] >> 14) & 0x1C000)) * ((YSI_g_sGateInfo[gate][E_GATE_INFO_ZA] & 0x80000000) ? (-0.1) : (0.1))),
  3909.                 Float:tz = (float((YSI_g_sGateInfo[gate][E_GATE_INFO_ZA] >> 10) & 0x1FFFF) * ((YSI_g_sGateInfo[gate][E_GATE_INFO_ZA] & 0x08000000) ? (-0.1) : (0.1))),
  3910.                 Float:s = (float(YSI_g_sGateInfo[gate][E_GATE_INFO_ZA] & 0x3FF) / 10.0);
  3911.             Object_GetPos(objectid, x, y, z);
  3912.             Object_SetGateTarget(gate, x, y, z, s);
  3913.             Object_Move(objectid, tx, ty, tz, s);
  3914.             YSI_g_sObjects[objectid][E_OBJECT_UPDATES] = YSI_g_sSomethingMoved;
  3915.             YSI_g_sSomethingMoved = objectid;
  3916.         }
  3917.         else
  3918.         {
  3919.             new
  3920.                 areaid = YSI_g_sGateInfo[gate][E_GATE_INFO_TRIGGER];
  3921.             YSI_g_sGateInfo[gate][E_GATE_INFO_TRIGGER] = NO_GATE;
  3922.             #if !defined NO_GATE_AREA_LOOKUP
  3923.                 YSI_g_sGateAreas[areaid / 2] |= 0xFFFF << ((areaid % 2) * 16);
  3924.             #endif
  3925.             Area_Delete(areaid);
  3926.         }
  3927.     }
  3928.     else
  3929.     {
  3930.         SetTimerEx("Object_GateClose", 1000, 0, "i", gate);
  3931.     }
  3932. }
  3933. #endif
  3934.  
  3935. /*----------------------------------------------------------------------------*-
  3936. Function:
  3937.     CreateGate
  3938. Params:
  3939.     modelid - Model of the gate.
  3940.     Float:x - X start location.
  3941.     Float:y - Y start location.
  3942.     Float:z - Z start location.
  3943.     Float:tx - X target location.
  3944.     Float:ty - Y target location.
  3945.     Float:tz - Z target location.
  3946.     Float:rx - X rotation.
  3947.     Float:ry - Y rotation.
  3948.     Float:rz - Z rotation.
  3949.     Float:speed - Speed the gate will move at.
  3950. Return:
  3951.     -
  3952. Notes:
  3953.     Creates a gate.
  3954. -*----------------------------------------------------------------------------*/
  3955.  
  3956. stock CreateGate(modelid, Float:x, Float:y, Float:z, Float:tx, Float:ty, Float:tz, Float:rx = 0.0, Float:ry = 0.0, Float:rz = 0.0, Float:speed = 2.0)
  3957. {
  3958.     #if defined _YSI_VISUAL_AREAS
  3959.         new
  3960.             obj = CreateDynamicObject(modelid, x, y, z, rx, ry, rz);
  3961.         if (obj == NO_OBJECT) return NO_GATE;
  3962.         new
  3963.             Float:xx = floatabs(x - tx),
  3964.             Float:yy = floatabs(y - ty),
  3965.             area = Area_AddCircle(x, y, (yy > xx) ? (yy) : (xx), z + 20.0);
  3966.         if (area == NO_AREA)
  3967.         {
  3968.             DestroyDynamicObject(obj);
  3969.             return NO_GATE;
  3970.         }
  3971.         return Object_SetAreaGate(obj, area, tx, ty, tz, speed, 10000);
  3972.     #else
  3973.         #pragma unused modelid, x, y, z, tx, ty, tz, rx, ry, rz, speed
  3974.         return NO_GATE;
  3975.     #endif
  3976. }
  3977.  
  3978. /*----------------------------------------------------------------------------*-
  3979. Function:
  3980.     Object_GetGateArea
  3981. Params:
  3982.     gate - Gate to get the area of for permissions.
  3983. Return:
  3984.     -
  3985. Notes:
  3986.     Returns the areaid used by the gate for detection.
  3987. -*----------------------------------------------------------------------------*/
  3988.  
  3989. stock Object_GetGateArea(gate)
  3990. {
  3991.     #if defined _YSI_SETUP_MASTER
  3992.         if (YSI_g_sIsMaster)
  3993.         {
  3994.     #endif
  3995.             #if defined _YSI_VISUAL_AREAS
  3996.                 if (gate >= 0 && gate < MAX_GATE_OBJECTS)
  3997.                 {
  3998.                     return YSI_g_sGateInfo[gate][E_GATE_INFO_TRIGGER];
  3999.                 }
  4000.             #else
  4001.                 #pragma unused gate
  4002.             #endif
  4003.             return -1;
  4004.     #if defined _YSI_SETUP_MASTER
  4005.         }
  4006.         else
  4007.         {
  4008.             CallRemoteFunction("Object_Remote", "iii", gate, 0, E_OBJECT_REMOTE_GET_AREA);
  4009.             return getproperty(0, "YSIReq");
  4010.         }
  4011.     #endif
  4012. }
  4013.  
Advertisement
Add Comment
Please, Sign In to add comment