y_objects.inc 122 KB

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