Script_Thread.cpp 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "../Game_local.h"
  23. const idEventDef EV_Thread_Execute( "<execute>", NULL );
  24. const idEventDef EV_Thread_SetCallback( "<script_setcallback>", NULL );
  25. // script callable events
  26. const idEventDef EV_Thread_TerminateThread( "terminate", "d" );
  27. const idEventDef EV_Thread_Pause( "pause", NULL );
  28. const idEventDef EV_Thread_Wait( "wait", "f" );
  29. const idEventDef EV_Thread_WaitFrame( "waitFrame" );
  30. const idEventDef EV_Thread_WaitFor( "waitFor", "e" );
  31. const idEventDef EV_Thread_WaitForThread( "waitForThread", "d" );
  32. const idEventDef EV_Thread_Print( "print", "s" );
  33. const idEventDef EV_Thread_PrintLn( "println", "s" );
  34. const idEventDef EV_Thread_Say( "say", "s" );
  35. const idEventDef EV_Thread_Assert( "assert", "f" );
  36. const idEventDef EV_Thread_Trigger( "trigger", "e" );
  37. const idEventDef EV_Thread_SetCvar( "setcvar", "ss" );
  38. const idEventDef EV_Thread_GetCvar( "getcvar", "s", 's' );
  39. const idEventDef EV_Thread_Random( "random", "f", 'f' );
  40. //bc
  41. const idEventDef EV_Thread_getClassEntity( "getClassEntity", "sd", 'e' );
  42. const idEventDef EV_Thread_deck_split( "deck_split", "fs", 's' );
  43. const idEventDef EV_Thread_deck_split2( "deck_split2", "fss", 's' );
  44. const idEventDef EV_Thread_deck_split3( "deck_split3", "fss", 's' );
  45. const idEventDef EV_Thread_deck_getArg( "deck_getArg", "s", 's' );
  46. const idEventDef EV_Thread_deck_hasArg( "deck_hasArg", "ss", 'd' );
  47. const idEventDef EV_Thread_callMap( "callMap", "s", 'd' );
  48. const idEventDef EV_Thread_getMapname( "getMapname", NULL, 's' );
  49. const idEventDef EV_Thread_getworldspawnint( "getworldspawnint", "s", 'd' );
  50. const idEventDef EV_Thread_setcutscene( "setcutscene", "d" );
  51. const idEventDef EV_Thread_SpawnDecal("spawndecal", "vvfs");
  52. const idEventDef EV_Thread_callsavegame("callsavegame", "d" );
  53. const idEventDef EV_Thread_killcctvs("killcctvs");
  54. const idEventDef EV_Thread_getMapIndex( "getMapIndex", NULL, 's' );
  55. #ifdef _D3XP
  56. const idEventDef EV_Thread_RandomInt( "randomInt", "d", 'd' );
  57. #endif
  58. const idEventDef EV_Thread_GetTime( "getTime", NULL, 'f' );
  59. const idEventDef EV_Thread_KillThread( "killthread", "s" );
  60. const idEventDef EV_Thread_SetThreadName( "threadname", "s" );
  61. const idEventDef EV_Thread_GetEntity( "getEntity", "s", 'e' );
  62. const idEventDef EV_Thread_Spawn( "spawn", "s", 'e' );
  63. const idEventDef EV_Thread_CopySpawnArgs( "copySpawnArgs", "e" );
  64. const idEventDef EV_Thread_SetSpawnArg( "setSpawnArg", "ss" );
  65. const idEventDef EV_Thread_SpawnString( "SpawnString", "ss", 's' );
  66. const idEventDef EV_Thread_SpawnFloat( "SpawnFloat", "sf", 'f' );
  67. const idEventDef EV_Thread_SpawnVector( "SpawnVector", "sv", 'v' );
  68. const idEventDef EV_Thread_ClearPersistantArgs( "clearPersistantArgs" );
  69. const idEventDef EV_Thread_SetPersistantArg( "setPersistantArg", "ss" );
  70. const idEventDef EV_Thread_GetPersistantString( "getPersistantString", "s", 's' );
  71. const idEventDef EV_Thread_GetPersistantFloat( "getPersistantFloat", "s", 'f' );
  72. const idEventDef EV_Thread_GetPersistantVector( "getPersistantVector", "s", 'v' );
  73. const idEventDef EV_Thread_AngToForward( "angToForward", "v", 'v' );
  74. const idEventDef EV_Thread_AngToRight( "angToRight", "v", 'v' );
  75. const idEventDef EV_Thread_AngToUp( "angToUp", "v", 'v' );
  76. const idEventDef EV_Thread_Sine( "sin", "f", 'f' );
  77. const idEventDef EV_Thread_Cosine( "cos", "f", 'f' );
  78. const idEventDef EV_Thread_lerp( "lerp", "fff", 'f' );
  79. const idEventDef EV_Thread_floatRound( "floatRound", "ff", 's' );
  80. const idEventDef EV_Thread_parseTime( "parseTime", "f", 's' );
  81. const idEventDef EV_Thread_parseTime2( "parseTime2", "f", 's' );
  82. const idEventDef EV_Thread_parseTimeMS( "parseTimeMS", "d", 's' );
  83. const idEventDef EV_Thread_getString( "getString", "s", 's' );
  84. const idEventDef EV_Thread_rundeckcommand( "rundeckcommand", "s" );
  85. #ifdef _D3XP
  86. const idEventDef EV_Thread_ArcSine( "asin", "f", 'f' );
  87. const idEventDef EV_Thread_ArcCosine( "acos", "f", 'f' );
  88. #endif
  89. const idEventDef EV_Thread_SquareRoot( "sqrt", "f", 'f' );
  90. const idEventDef EV_Thread_Normalize( "vecNormalize", "v", 'v' );
  91. const idEventDef EV_Thread_VecLength( "vecLength", "v", 'f' );
  92. const idEventDef EV_Thread_VecDotProduct( "DotProduct", "vv", 'f' );
  93. const idEventDef EV_Thread_VecCrossProduct( "CrossProduct", "vv", 'v' );
  94. const idEventDef EV_Thread_VecToAngles( "VecToAngles", "v", 'v' );
  95. #ifdef _D3XP
  96. const idEventDef EV_Thread_VecToOrthoBasisAngles( "VecToOrthoBasisAngles", "v", 'v' );
  97. const idEventDef EV_Thread_RotateVector("rotateVector", "vv", 'v');
  98. #endif
  99. const idEventDef EV_Thread_OnSignal( "onSignal", "des" );
  100. const idEventDef EV_Thread_ClearSignal( "clearSignalThread", "de" );
  101. const idEventDef EV_Thread_SetCamera( "setCamera", "e" );
  102. const idEventDef EV_Thread_FirstPerson( "firstPerson", NULL );
  103. const idEventDef EV_Thread_Trace( "trace", "vvvvde", 'f' );
  104. const idEventDef EV_Thread_TracePoint( "tracePoint", "vvde", 'f' );
  105. const idEventDef EV_Thread_GetTraceFraction( "getTraceFraction", NULL, 'f' );
  106. const idEventDef EV_Thread_GetTraceEndPos( "getTraceEndPos", NULL, 'v' );
  107. const idEventDef EV_Thread_GetTraceNormal( "getTraceNormal", NULL, 'v' );
  108. const idEventDef EV_Thread_GetTraceEntity( "getTraceEntity", NULL, 'e' );
  109. const idEventDef EV_Thread_GetTraceJoint( "getTraceJoint", NULL, 's' );
  110. const idEventDef EV_Thread_GetTraceBody( "getTraceBody", NULL, 's' );
  111. const idEventDef EV_Thread_GetTraceSky( "getTraceSky", NULL, 'd' ); //bc
  112. const idEventDef EV_Thread_FadeIn( "fadeIn", "vf" );
  113. const idEventDef EV_Thread_FadeOut( "fadeOut", "vf" );
  114. const idEventDef EV_Thread_FadeTo( "fadeTo", "vff" );
  115. const idEventDef EV_Thread_StartMusic( "music", "s" );
  116. const idEventDef EV_Thread_Error( "error", "s" );
  117. const idEventDef EV_Thread_Warning( "warning", "s" );
  118. const idEventDef EV_Thread_StrLen( "strLength", "s", 'd' );
  119. const idEventDef EV_Thread_StrLeft( "strLeft", "sd", 's' );
  120. const idEventDef EV_Thread_StrRight( "strRight", "sd", 's' );
  121. const idEventDef EV_Thread_StrSkip( "strSkip", "sd", 's' );
  122. const idEventDef EV_Thread_StrMid( "strMid", "sdd", 's' );
  123. const idEventDef EV_Thread_StrToFloat( "strToFloat", "s", 'f' );
  124. const idEventDef EV_Thread_RadiusDamage( "radiusDamage", "vEEEsf" );
  125. const idEventDef EV_Thread_IsClient( "isClient", NULL, 'f' );
  126. const idEventDef EV_Thread_IsMultiplayer( "isMultiplayer", NULL, 'f' );
  127. const idEventDef EV_Thread_GetFrameTime( "getFrameTime", NULL, 'f' );
  128. const idEventDef EV_Thread_GetTicsPerSecond( "getTicsPerSecond", NULL, 'f' );
  129. const idEventDef EV_Thread_DebugLine( "debugLine", "vvvf" );
  130. const idEventDef EV_Thread_DebugArrow( "debugArrow", "vvvdf" );
  131. const idEventDef EV_Thread_DebugCircle( "debugCircle", "vvvfdf" );
  132. const idEventDef EV_Thread_DebugBounds( "debugBounds", "vvvf" );
  133. const idEventDef EV_Thread_DrawText( "drawText", "svfvdf" );
  134. const idEventDef EV_Thread_InfluenceActive( "influenceActive", NULL, 'd' );
  135. CLASS_DECLARATION( idClass, idThread )
  136. EVENT( EV_Thread_Execute, idThread::Event_Execute )
  137. EVENT( EV_Thread_TerminateThread, idThread::Event_TerminateThread )
  138. EVENT( EV_Thread_Pause, idThread::Event_Pause )
  139. EVENT( EV_Thread_Wait, idThread::Event_Wait )
  140. EVENT( EV_Thread_WaitFrame, idThread::Event_WaitFrame )
  141. EVENT( EV_Thread_getClassEntity, idThread::Event_getClassEntity)
  142. EVENT( EV_Thread_deck_split, idThread::Event_deck_split)
  143. EVENT( EV_Thread_deck_split2, idThread::Event_deck_split2)
  144. EVENT( EV_Thread_deck_split3, idThread::Event_deck_split3)
  145. EVENT( EV_Thread_deck_getArg, idThread::Event_deck_getArg)
  146. EVENT( EV_Thread_deck_hasArg, idThread::Event_deck_hasArg)
  147. EVENT( EV_Thread_callMap, idThread::Event_callMap)
  148. EVENT( EV_Thread_getMapname, idThread::Event_getMapname)
  149. EVENT( EV_Thread_getworldspawnint, idThread::Event_getworldspawnint)
  150. EVENT( EV_Thread_setcutscene, idThread::Event_setcutscene)
  151. EVENT( EV_Thread_SpawnDecal, idThread::Event_SpawnDecal)
  152. EVENT( EV_Thread_callsavegame, idThread::Event_callsavegame)
  153. EVENT( EV_Thread_killcctvs, idThread::Event_killcctvs)
  154. EVENT( EV_Thread_getMapIndex, idThread::Event_getMapIndex)
  155. EVENT( EV_Thread_WaitFor, idThread::Event_WaitFor )
  156. EVENT( EV_Thread_WaitForThread, idThread::Event_WaitForThread )
  157. EVENT( EV_Thread_Print, idThread::Event_Print )
  158. EVENT( EV_Thread_PrintLn, idThread::Event_PrintLn )
  159. EVENT( EV_Thread_Say, idThread::Event_Say )
  160. EVENT( EV_Thread_Assert, idThread::Event_Assert )
  161. EVENT( EV_Thread_Trigger, idThread::Event_Trigger )
  162. EVENT( EV_Thread_SetCvar, idThread::Event_SetCvar )
  163. EVENT( EV_Thread_GetCvar, idThread::Event_GetCvar )
  164. EVENT( EV_Thread_Random, idThread::Event_Random )
  165. #ifdef _D3XP
  166. EVENT( EV_Thread_RandomInt, idThread::Event_RandomInt )
  167. #endif
  168. EVENT( EV_Thread_GetTime, idThread::Event_GetTime )
  169. EVENT( EV_Thread_KillThread, idThread::Event_KillThread )
  170. EVENT( EV_Thread_SetThreadName, idThread::Event_SetThreadName )
  171. EVENT( EV_Thread_GetEntity, idThread::Event_GetEntity )
  172. EVENT( EV_Thread_Spawn, idThread::Event_Spawn )
  173. EVENT( EV_Thread_CopySpawnArgs, idThread::Event_CopySpawnArgs )
  174. EVENT( EV_Thread_SetSpawnArg, idThread::Event_SetSpawnArg )
  175. EVENT( EV_Thread_SpawnString, idThread::Event_SpawnString )
  176. EVENT( EV_Thread_SpawnFloat, idThread::Event_SpawnFloat )
  177. EVENT( EV_Thread_SpawnVector, idThread::Event_SpawnVector )
  178. EVENT( EV_Thread_ClearPersistantArgs, idThread::Event_ClearPersistantArgs )
  179. EVENT( EV_Thread_SetPersistantArg, idThread::Event_SetPersistantArg )
  180. EVENT( EV_Thread_GetPersistantString, idThread::Event_GetPersistantString )
  181. EVENT( EV_Thread_GetPersistantFloat, idThread::Event_GetPersistantFloat )
  182. EVENT( EV_Thread_GetPersistantVector, idThread::Event_GetPersistantVector )
  183. EVENT( EV_Thread_AngToForward, idThread::Event_AngToForward )
  184. EVENT( EV_Thread_AngToRight, idThread::Event_AngToRight )
  185. EVENT( EV_Thread_AngToUp, idThread::Event_AngToUp )
  186. EVENT( EV_Thread_Sine, idThread::Event_GetSine )
  187. EVENT( EV_Thread_Cosine, idThread::Event_GetCosine )
  188. EVENT( EV_Thread_lerp, idThread::Event_lerp)
  189. EVENT( EV_Thread_rundeckcommand, idThread::Event_rundeckcommand)
  190. EVENT( EV_Thread_floatRound, idThread::Event_floatRound)
  191. EVENT( EV_Thread_parseTime, idThread::Event_parseTime)
  192. EVENT( EV_Thread_parseTime2, idThread::Event_parseTime2)
  193. EVENT( EV_Thread_parseTimeMS, idThread::Event_parseTimeMS)
  194. EVENT( EV_Thread_getString, idThread::Event_getString)
  195. #ifdef _D3XP
  196. EVENT( EV_Thread_ArcSine, idThread::Event_GetArcSine )
  197. EVENT( EV_Thread_ArcCosine, idThread::Event_GetArcCosine )
  198. #endif
  199. EVENT( EV_Thread_SquareRoot, idThread::Event_GetSquareRoot )
  200. EVENT( EV_Thread_Normalize, idThread::Event_VecNormalize )
  201. EVENT( EV_Thread_VecLength, idThread::Event_VecLength )
  202. EVENT( EV_Thread_VecDotProduct, idThread::Event_VecDotProduct )
  203. EVENT( EV_Thread_VecCrossProduct, idThread::Event_VecCrossProduct )
  204. EVENT( EV_Thread_VecToAngles, idThread::Event_VecToAngles )
  205. #ifdef _D3XP
  206. EVENT( EV_Thread_VecToOrthoBasisAngles, idThread::Event_VecToOrthoBasisAngles )
  207. EVENT( EV_Thread_RotateVector, idThread::Event_RotateVector )
  208. #endif
  209. EVENT( EV_Thread_OnSignal, idThread::Event_OnSignal )
  210. EVENT( EV_Thread_ClearSignal, idThread::Event_ClearSignalThread )
  211. EVENT( EV_Thread_SetCamera, idThread::Event_SetCamera )
  212. EVENT( EV_Thread_FirstPerson, idThread::Event_FirstPerson )
  213. EVENT( EV_Thread_Trace, idThread::Event_Trace )
  214. EVENT( EV_Thread_TracePoint, idThread::Event_TracePoint )
  215. EVENT( EV_Thread_GetTraceFraction, idThread::Event_GetTraceFraction )
  216. EVENT( EV_Thread_GetTraceEndPos, idThread::Event_GetTraceEndPos )
  217. EVENT( EV_Thread_GetTraceNormal, idThread::Event_GetTraceNormal )
  218. EVENT( EV_Thread_GetTraceEntity, idThread::Event_GetTraceEntity )
  219. EVENT( EV_Thread_GetTraceJoint, idThread::Event_GetTraceJoint )
  220. EVENT( EV_Thread_GetTraceBody, idThread::Event_GetTraceBody )
  221. EVENT( EV_Thread_GetTraceSky, idThread::Event_GetTraceSky) //bc
  222. EVENT( EV_Thread_FadeIn, idThread::Event_FadeIn )
  223. EVENT( EV_Thread_FadeOut, idThread::Event_FadeOut )
  224. EVENT( EV_Thread_FadeTo, idThread::Event_FadeTo )
  225. EVENT( EV_SetShaderParm, idThread::Event_SetShaderParm )
  226. EVENT( EV_Thread_StartMusic, idThread::Event_StartMusic )
  227. EVENT( EV_Thread_Warning, idThread::Event_Warning )
  228. EVENT( EV_Thread_Error, idThread::Event_Error )
  229. EVENT( EV_Thread_StrLen, idThread::Event_StrLen )
  230. EVENT( EV_Thread_StrLeft, idThread::Event_StrLeft )
  231. EVENT( EV_Thread_StrRight, idThread::Event_StrRight )
  232. EVENT( EV_Thread_StrSkip, idThread::Event_StrSkip )
  233. EVENT( EV_Thread_StrMid, idThread::Event_StrMid )
  234. EVENT( EV_Thread_StrToFloat, idThread::Event_StrToFloat )
  235. EVENT( EV_Thread_RadiusDamage, idThread::Event_RadiusDamage )
  236. EVENT( EV_Thread_IsClient, idThread::Event_IsClient )
  237. EVENT( EV_Thread_IsMultiplayer, idThread::Event_IsMultiplayer )
  238. EVENT( EV_Thread_GetFrameTime, idThread::Event_GetFrameTime )
  239. EVENT( EV_Thread_GetTicsPerSecond, idThread::Event_GetTicsPerSecond )
  240. EVENT( EV_CacheSoundShader, idThread::Event_CacheSoundShader )
  241. EVENT( EV_Thread_DebugLine, idThread::Event_DebugLine )
  242. EVENT( EV_Thread_DebugArrow, idThread::Event_DebugArrow )
  243. EVENT( EV_Thread_DebugCircle, idThread::Event_DebugCircle )
  244. EVENT( EV_Thread_DebugBounds, idThread::Event_DebugBounds )
  245. EVENT( EV_Thread_DrawText, idThread::Event_DrawText )
  246. EVENT( EV_Thread_InfluenceActive, idThread::Event_InfluenceActive )
  247. END_CLASS
  248. idThread *idThread::currentThread = NULL;
  249. int idThread::threadIndex = 0;
  250. idList<idThread *> idThread::threadList;
  251. trace_t idThread::trace;
  252. /*
  253. ================
  254. idThread::CurrentThread
  255. ================
  256. */
  257. idThread *idThread::CurrentThread( void ) {
  258. return currentThread;
  259. }
  260. /*
  261. ================
  262. idThread::CurrentThreadNum
  263. ================
  264. */
  265. int idThread::CurrentThreadNum( void ) {
  266. if ( currentThread ) {
  267. return currentThread->GetThreadNum();
  268. } else {
  269. return 0;
  270. }
  271. }
  272. /*
  273. ================
  274. idThread::BeginMultiFrameEvent
  275. ================
  276. */
  277. bool idThread::BeginMultiFrameEvent( idEntity *ent, const idEventDef *event ) {
  278. if ( !currentThread ) {
  279. gameLocal.Error( "idThread::BeginMultiFrameEvent called without a current thread" );
  280. }
  281. return currentThread->interpreter.BeginMultiFrameEvent( ent, event );
  282. }
  283. /*
  284. ================
  285. idThread::EndMultiFrameEvent
  286. ================
  287. */
  288. void idThread::EndMultiFrameEvent( idEntity *ent, const idEventDef *event ) {
  289. if ( !currentThread ) {
  290. gameLocal.Error( "idThread::EndMultiFrameEvent called without a current thread" );
  291. }
  292. currentThread->interpreter.EndMultiFrameEvent( ent, event );
  293. }
  294. /*
  295. ================
  296. idThread::idThread
  297. ================
  298. */
  299. idThread::idThread() {
  300. Init();
  301. SetThreadName( va( "thread_%d", threadIndex ) );
  302. if ( g_debugScript.GetBool() ) {
  303. gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  304. }
  305. }
  306. /*
  307. ================
  308. idThread::idThread
  309. ================
  310. */
  311. idThread::idThread( idEntity *self, const function_t *func ) {
  312. assert( self );
  313. Init();
  314. SetThreadName( self->name );
  315. interpreter.EnterObjectFunction( self, func, false );
  316. if ( g_debugScript.GetBool() ) {
  317. gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  318. }
  319. }
  320. /*
  321. ================
  322. idThread::idThread
  323. ================
  324. */
  325. idThread::idThread( const function_t *func ) {
  326. assert( func );
  327. Init();
  328. SetThreadName( func->Name() );
  329. interpreter.EnterFunction( func, false );
  330. if ( g_debugScript.GetBool() ) {
  331. gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  332. }
  333. }
  334. /*
  335. ================
  336. idThread::idThread
  337. ================
  338. */
  339. idThread::idThread( idInterpreter *source, const function_t *func, int args ) {
  340. Init();
  341. interpreter.ThreadCall( source, func, args );
  342. if ( g_debugScript.GetBool() ) {
  343. gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  344. }
  345. }
  346. /*
  347. ================
  348. idThread::idThread
  349. ================
  350. */
  351. idThread::idThread( idInterpreter *source, idEntity *self, const function_t *func, int args ) {
  352. assert( self );
  353. Init();
  354. SetThreadName( self->name );
  355. interpreter.ThreadCall( source, func, args );
  356. if ( g_debugScript.GetBool() ) {
  357. gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  358. }
  359. }
  360. /*
  361. ================
  362. idThread::~idThread
  363. ================
  364. */
  365. idThread::~idThread() {
  366. idThread *thread;
  367. int i;
  368. int n;
  369. if ( g_debugScript.GetBool() ) {
  370. gameLocal.Printf( "%d: end thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  371. }
  372. threadList.Remove( this );
  373. n = threadList.Num();
  374. for( i = 0; i < n; i++ ) {
  375. thread = threadList[ i ];
  376. if ( thread->WaitingOnThread() == this ) {
  377. thread->ThreadCallback( this );
  378. }
  379. }
  380. if ( currentThread == this ) {
  381. currentThread = NULL;
  382. }
  383. }
  384. /*
  385. ================
  386. idThread::ManualDelete
  387. ================
  388. */
  389. void idThread::ManualDelete( void ) {
  390. interpreter.terminateOnExit = false;
  391. }
  392. /*
  393. ================
  394. idThread::Save
  395. ================
  396. */
  397. void idThread::Save( idSaveGame *savefile ) const {
  398. // We will check on restore that threadNum is still the same,
  399. // threads should have been restored in the same order.
  400. savefile->WriteInt( threadNum );
  401. savefile->WriteObject( waitingForThread );
  402. savefile->WriteInt( waitingFor );
  403. savefile->WriteInt( waitingUntil );
  404. interpreter.Save( savefile );
  405. savefile->WriteDict( &spawnArgs );
  406. savefile->WriteString( threadName );
  407. savefile->WriteInt( lastExecuteTime );
  408. savefile->WriteInt( creationTime );
  409. savefile->WriteBool( manualControl );
  410. }
  411. /*
  412. ================
  413. idThread::Restore
  414. ================
  415. */
  416. void idThread::Restore( idRestoreGame *savefile ) {
  417. savefile->ReadInt( threadNum );
  418. savefile->ReadObject( reinterpret_cast<idClass *&>( waitingForThread ) );
  419. savefile->ReadInt( waitingFor );
  420. savefile->ReadInt( waitingUntil );
  421. interpreter.Restore( savefile );
  422. savefile->ReadDict( &spawnArgs );
  423. savefile->ReadString( threadName );
  424. savefile->ReadInt( lastExecuteTime );
  425. savefile->ReadInt( creationTime );
  426. savefile->ReadBool( manualControl );
  427. }
  428. /*
  429. ================
  430. idThread::Init
  431. ================
  432. */
  433. void idThread::Init( void ) {
  434. // create a unique threadNum
  435. do {
  436. threadIndex++;
  437. if ( threadIndex == 0 ) {
  438. threadIndex = 1;
  439. }
  440. } while( GetThread( threadIndex ) );
  441. threadNum = threadIndex;
  442. threadList.Append( this );
  443. creationTime = gameLocal.time;
  444. lastExecuteTime = 0;
  445. manualControl = false;
  446. ClearWaitFor();
  447. interpreter.SetThread( this );
  448. }
  449. /*
  450. ================
  451. idThread::GetThread
  452. ================
  453. */
  454. idThread *idThread::GetThread( int num ) {
  455. int i;
  456. int n;
  457. idThread *thread;
  458. n = threadList.Num();
  459. for( i = 0; i < n; i++ ) {
  460. thread = threadList[ i ];
  461. if ( thread->GetThreadNum() == num ) {
  462. return thread;
  463. }
  464. }
  465. return NULL;
  466. }
  467. /*
  468. ================
  469. idThread::DisplayInfo
  470. ================
  471. */
  472. void idThread::DisplayInfo( void ) {
  473. gameLocal.Printf(
  474. "%12i: '%s'\n"
  475. " File: %s(%d)\n"
  476. " Created: %d (%d ms ago)\n"
  477. " Status: ",
  478. threadNum, threadName.c_str(),
  479. interpreter.CurrentFile(), interpreter.CurrentLine(),
  480. creationTime, gameLocal.time - creationTime );
  481. if ( interpreter.threadDying ) {
  482. gameLocal.Printf( "Dying\n" );
  483. } else if ( interpreter.doneProcessing ) {
  484. gameLocal.Printf(
  485. "Paused since %d (%d ms)\n"
  486. " Reason: ", lastExecuteTime, gameLocal.time - lastExecuteTime );
  487. if ( waitingForThread ) {
  488. gameLocal.Printf( "Waiting for thread #%3i '%s'\n", waitingForThread->GetThreadNum(), waitingForThread->GetThreadName() );
  489. } else if ( ( waitingFor != ENTITYNUM_NONE ) && ( gameLocal.entities[ waitingFor ] ) ) {
  490. gameLocal.Printf( "Waiting for entity #%3i '%s'\n", waitingFor, gameLocal.entities[ waitingFor ]->name.c_str() );
  491. } else if ( waitingUntil ) {
  492. gameLocal.Printf( "Waiting until %d (%d ms total wait time)\n", waitingUntil, waitingUntil - lastExecuteTime );
  493. } else {
  494. gameLocal.Printf( "None\n" );
  495. }
  496. } else {
  497. gameLocal.Printf( "Processing\n" );
  498. }
  499. interpreter.DisplayInfo();
  500. gameLocal.Printf( "\n" );
  501. }
  502. /*
  503. ================
  504. idThread::ListThreads_f
  505. ================
  506. */
  507. void idThread::ListThreads_f( const idCmdArgs &args ) {
  508. int i;
  509. int n;
  510. n = threadList.Num();
  511. for( i = 0; i < n; i++ ) {
  512. //threadList[ i ]->DisplayInfo();
  513. gameLocal.Printf( "%3i: %-20s : %s(%d)\n", threadList[ i ]->threadNum, threadList[ i ]->threadName.c_str(), threadList[ i ]->interpreter.CurrentFile(), threadList[ i ]->interpreter.CurrentLine() );
  514. }
  515. gameLocal.Printf( "%d active threads\n\n", n );
  516. }
  517. /*
  518. ================
  519. idThread::Restart
  520. ================
  521. */
  522. void idThread::Restart( void ) {
  523. int i;
  524. int n;
  525. // reset the threadIndex
  526. threadIndex = 0;
  527. currentThread = NULL;
  528. n = threadList.Num();
  529. for( i = n - 1; i >= 0; i-- ) {
  530. delete threadList[ i ];
  531. }
  532. threadList.Clear();
  533. memset( &trace, 0, sizeof( trace ) );
  534. trace.c.entityNum = ENTITYNUM_NONE;
  535. }
  536. /*
  537. ================
  538. idThread::DelayedStart
  539. ================
  540. */
  541. void idThread::DelayedStart( int delay ) {
  542. CancelEvents( &EV_Thread_Execute );
  543. if ( gameLocal.time <= 0 ) {
  544. delay++;
  545. }
  546. PostEventMS( &EV_Thread_Execute, delay );
  547. }
  548. /*
  549. ================
  550. idThread::Start
  551. ================
  552. */
  553. bool idThread::Start( void ) {
  554. bool result;
  555. CancelEvents( &EV_Thread_Execute );
  556. result = Execute();
  557. return result;
  558. }
  559. /*
  560. ================
  561. idThread::SetThreadName
  562. ================
  563. */
  564. void idThread::SetThreadName( const char *name ) {
  565. threadName = name;
  566. }
  567. /*
  568. ================
  569. idThread::ObjectMoveDone
  570. ================
  571. */
  572. void idThread::ObjectMoveDone( int threadnum, idEntity *obj ) {
  573. idThread *thread;
  574. if ( !threadnum ) {
  575. return;
  576. }
  577. thread = GetThread( threadnum );
  578. if ( thread ) {
  579. thread->ObjectMoveDone( obj );
  580. }
  581. }
  582. /*
  583. ================
  584. idThread::End
  585. ================
  586. */
  587. void idThread::End( void ) {
  588. // Tell thread to die. It will exit on its own.
  589. Pause();
  590. interpreter.threadDying = true;
  591. }
  592. /*
  593. ================
  594. idThread::KillThread
  595. ================
  596. */
  597. void idThread::KillThread( const char *name ) {
  598. int i;
  599. int num;
  600. int len;
  601. const char *ptr;
  602. idThread *thread;
  603. // see if the name uses a wild card
  604. ptr = strchr( name, '*' );
  605. if ( ptr ) {
  606. len = ptr - name;
  607. } else {
  608. len = strlen( name );
  609. }
  610. // kill only those threads whose name matches name
  611. num = threadList.Num();
  612. for( i = 0; i < num; i++ ) {
  613. thread = threadList[ i ];
  614. if ( !idStr::Cmpn( thread->GetThreadName(), name, len ) ) {
  615. thread->End();
  616. }
  617. }
  618. }
  619. /*
  620. ================
  621. idThread::KillThread
  622. ================
  623. */
  624. void idThread::KillThread( int num ) {
  625. idThread *thread;
  626. thread = GetThread( num );
  627. if ( thread ) {
  628. // Tell thread to die. It will delete itself on it's own.
  629. thread->End();
  630. }
  631. }
  632. /*
  633. ================
  634. idThread::Execute
  635. ================
  636. */
  637. bool idThread::Execute( void ) {
  638. idThread *oldThread;
  639. bool done;
  640. if ( manualControl && ( waitingUntil > gameLocal.time ) ) {
  641. return false;
  642. }
  643. oldThread = currentThread;
  644. currentThread = this;
  645. lastExecuteTime = gameLocal.time;
  646. ClearWaitFor();
  647. done = interpreter.Execute();
  648. if ( done ) {
  649. End();
  650. if ( interpreter.terminateOnExit ) {
  651. PostEventMS( &EV_Remove, 0 );
  652. }
  653. } else if ( !manualControl ) {
  654. if ( waitingUntil > lastExecuteTime ) {
  655. PostEventMS( &EV_Thread_Execute, waitingUntil - lastExecuteTime );
  656. } else if ( interpreter.MultiFrameEventInProgress() ) {
  657. PostEventMS( &EV_Thread_Execute, gameLocal.msec );
  658. }
  659. }
  660. currentThread = oldThread;
  661. return done;
  662. }
  663. /*
  664. ================
  665. idThread::IsWaiting
  666. Checks if thread is still waiting for some event to occur.
  667. ================
  668. */
  669. bool idThread::IsWaiting( void ) {
  670. if ( waitingForThread || ( waitingFor != ENTITYNUM_NONE ) ) {
  671. return true;
  672. }
  673. if ( waitingUntil && ( waitingUntil > gameLocal.time ) ) {
  674. return true;
  675. }
  676. return false;
  677. }
  678. /*
  679. ================
  680. idThread::CallFunction
  681. NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function.
  682. ================
  683. */
  684. void idThread::CallFunction( const function_t *func, bool clearStack ) {
  685. ClearWaitFor();
  686. interpreter.EnterFunction( func, clearStack );
  687. }
  688. /*
  689. ================
  690. idThread::CallFunction
  691. NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function.
  692. ================
  693. */
  694. void idThread::CallFunction( idEntity *self, const function_t *func, bool clearStack ) {
  695. assert( self );
  696. ClearWaitFor();
  697. interpreter.EnterObjectFunction( self, func, clearStack );
  698. }
  699. /*
  700. ================
  701. idThread::ClearWaitFor
  702. ================
  703. */
  704. void idThread::ClearWaitFor( void ) {
  705. waitingFor = ENTITYNUM_NONE;
  706. waitingForThread = NULL;
  707. waitingUntil = 0;
  708. }
  709. /*
  710. ================
  711. idThread::IsWaitingFor
  712. ================
  713. */
  714. bool idThread::IsWaitingFor( idEntity *obj ) {
  715. assert( obj );
  716. return waitingFor == obj->entityNumber;
  717. }
  718. /*
  719. ================
  720. idThread::ObjectMoveDone
  721. ================
  722. */
  723. void idThread::ObjectMoveDone( idEntity *obj ) {
  724. assert( obj );
  725. if ( IsWaitingFor( obj ) ) {
  726. ClearWaitFor();
  727. DelayedStart( 0 );
  728. }
  729. }
  730. /*
  731. ================
  732. idThread::ThreadCallback
  733. ================
  734. */
  735. void idThread::ThreadCallback( idThread *thread ) {
  736. if ( interpreter.threadDying ) {
  737. return;
  738. }
  739. if ( thread == waitingForThread ) {
  740. ClearWaitFor();
  741. DelayedStart( 0 );
  742. }
  743. }
  744. /*
  745. ================
  746. idThread::Event_SetThreadName
  747. ================
  748. */
  749. void idThread::Event_SetThreadName( const char *name ) {
  750. SetThreadName( name );
  751. }
  752. /*
  753. ================
  754. idThread::Error
  755. ================
  756. */
  757. void idThread::Error( const char *fmt, ... ) const {
  758. va_list argptr;
  759. char text[ 1024 ];
  760. va_start( argptr, fmt );
  761. vsprintf( text, fmt, argptr );
  762. va_end( argptr );
  763. interpreter.Error( text );
  764. }
  765. /*
  766. ================
  767. idThread::Warning
  768. ================
  769. */
  770. void idThread::Warning( const char *fmt, ... ) const {
  771. va_list argptr;
  772. char text[ 1024 ];
  773. va_start( argptr, fmt );
  774. vsprintf( text, fmt, argptr );
  775. va_end( argptr );
  776. interpreter.Warning( text );
  777. }
  778. /*
  779. ================
  780. idThread::ReturnString
  781. ================
  782. */
  783. void idThread::ReturnString( const char *text ) {
  784. gameLocal.program.ReturnString( text );
  785. }
  786. /*
  787. ================
  788. idThread::ReturnFloat
  789. ================
  790. */
  791. void idThread::ReturnFloat( float value ) {
  792. gameLocal.program.ReturnFloat( value );
  793. }
  794. /*
  795. ================
  796. idThread::ReturnInt
  797. ================
  798. */
  799. void idThread::ReturnInt( int value ) {
  800. // true integers aren't supported in the compiler,
  801. // so int values are stored as floats
  802. gameLocal.program.ReturnFloat( value );
  803. }
  804. /*
  805. ================
  806. idThread::ReturnVector
  807. ================
  808. */
  809. void idThread::ReturnVector( idVec3 const &vec ) {
  810. gameLocal.program.ReturnVector( vec );
  811. }
  812. /*
  813. ================
  814. idThread::ReturnEntity
  815. ================
  816. */
  817. void idThread::ReturnEntity( idEntity *ent ) {
  818. gameLocal.program.ReturnEntity( ent );
  819. }
  820. /*
  821. ================
  822. idThread::Event_Execute
  823. ================
  824. */
  825. void idThread::Event_Execute( void ) {
  826. Execute();
  827. }
  828. /*
  829. ================
  830. idThread::Pause
  831. ================
  832. */
  833. void idThread::Pause( void ) {
  834. ClearWaitFor();
  835. interpreter.doneProcessing = true;
  836. }
  837. /*
  838. ================
  839. idThread::WaitMS
  840. ================
  841. */
  842. void idThread::WaitMS( int time ) {
  843. Pause();
  844. waitingUntil = gameLocal.time + time;
  845. }
  846. /*
  847. ================
  848. idThread::WaitSec
  849. ================
  850. */
  851. void idThread::WaitSec( float time ) {
  852. WaitMS( SEC2MS( time ) );
  853. }
  854. /*
  855. ================
  856. idThread::WaitFrame
  857. ================
  858. */
  859. void idThread::WaitFrame( void ) {
  860. Pause();
  861. // manual control threads don't set waitingUntil so that they can be run again
  862. // that frame if necessary.
  863. if ( !manualControl ) {
  864. waitingUntil = gameLocal.time + gameLocal.msec;
  865. }
  866. }
  867. /***********************************************************************
  868. Script callable events
  869. ***********************************************************************/
  870. /*
  871. ================
  872. idThread::Event_TerminateThread
  873. ================
  874. */
  875. void idThread::Event_TerminateThread( int num ) {
  876. idThread *thread;
  877. thread = GetThread( num );
  878. KillThread( num );
  879. }
  880. /*
  881. ================
  882. idThread::Event_Pause
  883. ================
  884. */
  885. void idThread::Event_Pause( void ) {
  886. Pause();
  887. }
  888. /*
  889. ================
  890. idThread::Event_Wait
  891. ================
  892. */
  893. void idThread::Event_Wait( float time ) {
  894. WaitSec( time );
  895. }
  896. /*
  897. ================
  898. idThread::Event_WaitFrame
  899. ================
  900. */
  901. void idThread::Event_WaitFrame( void ) {
  902. WaitFrame();
  903. }
  904. void idThread::Event_deck_split2( float index, const char* text, const char* divider )
  905. {
  906. int i;
  907. idStr rawtext = text;
  908. for (i = 0; i <= index; i++)
  909. {
  910. if (i >= index )
  911. {
  912. //This is the string we want to return.
  913. int subIndex = rawtext.Find(divider, false, 0, -1);
  914. if (subIndex < 0)
  915. {
  916. //no more semicolons. just return what we have.
  917. rawtext.StripTrailingWhitespace();
  918. rawtext.StripLeading( ' ' );
  919. idThread::ReturnString( rawtext );
  920. return;
  921. }
  922. else
  923. {
  924. //strip out any successive semicolons.
  925. idStr textChunk = rawtext.Mid(0, subIndex);
  926. textChunk.StripTrailingWhitespace();
  927. textChunk.StripLeading( ' ' );
  928. idThread::ReturnString( textChunk );
  929. return;
  930. }
  931. }
  932. int index = rawtext.Find(divider, false, 0, -1);
  933. if (index < 0)
  934. {
  935. //couldn't find any more instances of the divider. Return blank.
  936. idThread::ReturnString( "" );
  937. return;
  938. }
  939. //idStr textChunk = rawtext.Mid(0, index);
  940. rawtext = rawtext.Mid(index + 1, rawtext.Length() - index - 1);
  941. continue;
  942. }
  943. idThread::ReturnString( "" );
  944. }
  945. void idThread::Event_deck_split3( float index, const char* text, const char* divider )
  946. {
  947. int i;
  948. idStr rawtext = text;
  949. int subIndex = 0;
  950. //common->Printf("raw: %s\n", text);
  951. for (i = 0; i <= index; i++)
  952. {
  953. subIndex = rawtext.Find(divider, false, subIndex, -1);
  954. if (i >= index)
  955. {
  956. idStr textChunk = rawtext.Mid(subIndex + 1, rawtext.Length() - 1);
  957. textChunk.StripTrailingWhitespace();
  958. textChunk.StripLeading( ' ' );
  959. idThread::ReturnString( textChunk );
  960. return;
  961. }
  962. subIndex++;
  963. }
  964. idThread::ReturnString( "" );
  965. return;
  966. }
  967. //Separates a string by whitespaces.
  968. //Index = returns word at that slot. If no word is there, returns blank "" string.
  969. void idThread::Event_deck_split( float index, const char* text )
  970. {
  971. idStr rawtext = text;
  972. int wordIndex = 0;
  973. int idx = 0;
  974. while (idx > -1)
  975. {
  976. idx = rawtext.Find(" ", false, 0, rawtext.Length());
  977. //get a chunk of text.
  978. idStr textChunk = rawtext.Mid(0, idx);
  979. if (textChunk.IsEmpty())
  980. textChunk = rawtext;
  981. if (!textChunk.IsEmpty())
  982. {
  983. if (wordIndex == (int)index)
  984. {
  985. idThread::ReturnString( textChunk.c_str() );
  986. return;
  987. }
  988. wordIndex++;
  989. }
  990. rawtext = rawtext.Mid(idx + 1, rawtext.Length() - idx - 1);
  991. rawtext.StripLeading( ' ' );
  992. }
  993. idThread::ReturnString( "" );
  994. }
  995. void idThread::Event_getMapname( void )
  996. {
  997. idStr callfunc;
  998. callfunc = gameLocal.GetMapName();
  999. callfunc.StripPath();
  1000. callfunc.StripFileExtension();
  1001. callfunc.ToLower();
  1002. idThread::ReturnString( callfunc );
  1003. }
  1004. void idThread::Event_getMapIndex( void )
  1005. {
  1006. idThread::ReturnString( gameLocal.GetMapIndex() );
  1007. }
  1008. void idThread::Event_setcutscene( int value )
  1009. {
  1010. gameLocal.inCutscene = value;
  1011. }
  1012. void idThread::Event_SpawnDecal( idVec3 const &pos, idVec3 const &endpos, float size, const char* material )
  1013. {
  1014. //gameRenderWorld->DebugLine(idVec4(1,1,1,1), pos, pos + idVec3(0,0,16), 2000);
  1015. gameLocal.ProjectDecal(
  1016. pos,
  1017. -endpos,
  1018. 8.0f,
  1019. true,
  1020. size,
  1021. material);
  1022. }
  1023. void idThread::Event_killcctvs()
  1024. {
  1025. gameLocal.KillCCTVs();
  1026. }
  1027. //savetypes: 0 = quicksave, 1 = savestation, 2 = autosave
  1028. void idThread::Event_callsavegame( int savetype )
  1029. {
  1030. //bc this is a bit of an ugly hack... buffercommandtext doesnt work so instead a sessioncommand is
  1031. //sent to RunGameTic() in session.cpp.
  1032. cvarSystem->SetCVarBool("savedone", false);
  1033. if (savetype == 0)
  1034. {
  1035. gameLocal.sessionCommand = "doquicksave";
  1036. }
  1037. else if (savetype == 1)
  1038. {
  1039. gameLocal.sessionCommand = "dosavestation";
  1040. }
  1041. else
  1042. {
  1043. gameLocal.sessionCommand = "domapsave";
  1044. }
  1045. }
  1046. void idThread::Event_getworldspawnint( const char *keyname )
  1047. {
  1048. if (!gameLocal.world)
  1049. {
  1050. idThread::ReturnInt(0);
  1051. return;
  1052. }
  1053. idThread::ReturnInt(gameLocal.world->spawnArgs.GetInt(keyname, "0"));
  1054. return;
  1055. }
  1056. void idThread::Event_callMap( const char *funcname )
  1057. {
  1058. gameLocal.CallMap(funcname);
  1059. }
  1060. void idThread::Event_deck_hasArg( const char *text, const char *functionName )
  1061. {
  1062. idStr rawText;
  1063. idStr rawFunction;
  1064. int functionIndex;
  1065. int firstParentheses;
  1066. int secondParentheses;
  1067. int periodIndex;
  1068. rawText = text;
  1069. firstParentheses = rawText.Find("(", false, 0, -1);
  1070. secondParentheses = rawText.Find(")", false, 0, -1);
  1071. //check if there are opening and closing parentheses
  1072. if (firstParentheses < 0 || secondParentheses < 0)
  1073. {
  1074. idThread::ReturnInt(0);
  1075. return;
  1076. }
  1077. //ensure the second parentheses is the last character.
  1078. int len = rawText.Length();
  1079. if (secondParentheses < len - 1)
  1080. {
  1081. idThread::ReturnInt(0);
  1082. return;
  1083. }
  1084. //strip off the parentheses
  1085. rawText = rawText.Mid(0, firstParentheses);
  1086. rawText.StripTrailing(' ');
  1087. //if this is a "." call, then strip out everything preceding the "."
  1088. periodIndex = rawText.Find(".", false, 0, -1);
  1089. if (periodIndex >= 0)
  1090. {
  1091. rawText = rawText.Mid(periodIndex + 1, rawText.Length() - periodIndex - 1);
  1092. }
  1093. //check whether the strings are identical.
  1094. if (idStr::Icmp( rawText, functionName) != 0)
  1095. {
  1096. idThread::ReturnInt(0);
  1097. return;
  1098. }
  1099. idThread::ReturnInt(1);
  1100. }
  1101. void idThread::Event_deck_getArg( const char *text )
  1102. {
  1103. idStr rawText;
  1104. int firstParentheses;
  1105. int secondParentheses;
  1106. rawText = text;
  1107. firstParentheses = rawText.Find("(", false, 0, rawText.Length());
  1108. if (firstParentheses < 0)
  1109. {
  1110. idThread::ReturnString("");
  1111. return;
  1112. }
  1113. rawText = rawText.Mid(firstParentheses + 1, rawText.Length() - firstParentheses - 1);
  1114. secondParentheses = rawText.Find(")", false, 0, rawText.Length());
  1115. if (secondParentheses < 0)
  1116. {
  1117. idThread::ReturnString("");
  1118. return;
  1119. }
  1120. rawText = rawText.Mid(0, secondParentheses);
  1121. idThread::ReturnString( rawText );
  1122. }
  1123. void idThread::Event_getClassEntity( const char *classname, int lastFound )
  1124. {
  1125. int i;
  1126. lastFound++;
  1127. if (lastFound >= gameLocal.num_entities || lastFound < 0)
  1128. {
  1129. idThread::ReturnEntity( NULL );
  1130. return;
  1131. }
  1132. for ( i = lastFound; i < gameLocal.num_entities; i++ )
  1133. {
  1134. if ( !gameLocal.entities[ i ] )
  1135. continue;
  1136. //check if the classname matches.
  1137. //BC 12-18-2013 wildcard support.
  1138. idStr strClassname = classname;
  1139. int subIndex = strClassname.Find("*", false, 0, -1);
  1140. if (subIndex >= 0)
  1141. {
  1142. //Has a wildcard.
  1143. idStr classnameChunk = strClassname.Mid(0, subIndex);
  1144. idStr entityClassname = gameLocal.entities[ i ]->spawnArgs.GetString( "classname" );
  1145. if (idStr::Icmpn(classnameChunk, entityClassname, subIndex) != 0)
  1146. {
  1147. continue;
  1148. }
  1149. }
  1150. else if (idStr::Icmp( classname, gameLocal.entities[ i ]->spawnArgs.GetString( "classname" )) != 0) //No wildcard. Do normal check.
  1151. {
  1152. continue;
  1153. }
  1154. idThread::ReturnEntity( gameLocal.entities[ i ] );
  1155. return;
  1156. }
  1157. idThread::ReturnEntity( NULL );
  1158. }
  1159. /*
  1160. ================
  1161. idThread::Event_WaitFor
  1162. ================
  1163. */
  1164. void idThread::Event_WaitFor( idEntity *ent ) {
  1165. if ( ent && ent->RespondsTo( EV_Thread_SetCallback ) ) {
  1166. ent->ProcessEvent( &EV_Thread_SetCallback );
  1167. if ( gameLocal.program.GetReturnedInteger() ) {
  1168. Pause();
  1169. waitingFor = ent->entityNumber;
  1170. }
  1171. }
  1172. }
  1173. /*
  1174. ================
  1175. idThread::Event_WaitForThread
  1176. ================
  1177. */
  1178. void idThread::Event_WaitForThread( int num ) {
  1179. idThread *thread;
  1180. thread = GetThread( num );
  1181. if ( !thread ) {
  1182. if ( g_debugScript.GetBool() ) {
  1183. // just print a warning and continue executing
  1184. Warning( "Thread %d not running", num );
  1185. }
  1186. } else {
  1187. Pause();
  1188. waitingForThread = thread;
  1189. }
  1190. }
  1191. /*
  1192. ================
  1193. idThread::Event_Print
  1194. ================
  1195. */
  1196. void idThread::Event_Print( const char *text ) {
  1197. gameLocal.Printf( "%s", text );
  1198. }
  1199. /*
  1200. ================
  1201. idThread::Event_PrintLn
  1202. ================
  1203. */
  1204. void idThread::Event_PrintLn( const char *text ) {
  1205. gameLocal.Printf( "%s\n", text );
  1206. }
  1207. /*
  1208. ================
  1209. idThread::Event_Say
  1210. ================
  1211. */
  1212. void idThread::Event_Say( const char *text ) {
  1213. cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say \"%s\"", text ) );
  1214. }
  1215. /*
  1216. ================
  1217. idThread::Event_Assert
  1218. ================
  1219. */
  1220. void idThread::Event_Assert( float value ) {
  1221. assert( value );
  1222. }
  1223. /*
  1224. ================
  1225. idThread::Event_Trigger
  1226. ================
  1227. */
  1228. void idThread::Event_Trigger( idEntity *ent ) {
  1229. if ( ent ) {
  1230. ent->Signal( SIG_TRIGGER );
  1231. ent->ProcessEvent( &EV_Activate, gameLocal.GetLocalPlayer() );
  1232. ent->TriggerGuis();
  1233. }
  1234. }
  1235. /*
  1236. ================
  1237. idThread::Event_SetCvar
  1238. ================
  1239. */
  1240. void idThread::Event_SetCvar( const char *name, const char *value ) const {
  1241. cvarSystem->SetCVarString( name, value );
  1242. }
  1243. /*
  1244. ================
  1245. idThread::Event_GetCvar
  1246. ================
  1247. */
  1248. void idThread::Event_GetCvar( const char *name ) const {
  1249. ReturnString( cvarSystem->GetCVarString( name ) );
  1250. }
  1251. /*
  1252. ================
  1253. idThread::Event_Random
  1254. ================
  1255. */
  1256. void idThread::Event_Random( float range ) const {
  1257. float result;
  1258. result = gameLocal.random.RandomFloat();
  1259. ReturnFloat( range * result );
  1260. }
  1261. #ifdef _D3XP
  1262. void idThread::Event_RandomInt( int range ) const {
  1263. int result;
  1264. result = gameLocal.random.RandomInt(range);
  1265. ReturnFloat(result);
  1266. }
  1267. #endif
  1268. /*
  1269. ================
  1270. idThread::Event_GetTime
  1271. ================
  1272. */
  1273. void idThread::Event_GetTime( void ) {
  1274. ReturnFloat( MS2SEC( gameLocal.realClientTime ) );
  1275. }
  1276. /*
  1277. ================
  1278. idThread::Event_KillThread
  1279. ================
  1280. */
  1281. void idThread::Event_KillThread( const char *name ) {
  1282. KillThread( name );
  1283. }
  1284. /*
  1285. ================
  1286. idThread::Event_GetEntity
  1287. ================
  1288. */
  1289. void idThread::Event_GetEntity( const char *name ) {
  1290. int entnum;
  1291. idEntity *ent;
  1292. assert( name );
  1293. if ( name[ 0 ] == '*' ) {
  1294. entnum = atoi( &name[ 1 ] );
  1295. if ( ( entnum < 0 ) || ( entnum >= MAX_GENTITIES ) ) {
  1296. Error( "Entity number in string out of range." );
  1297. }
  1298. ReturnEntity( gameLocal.entities[ entnum ] );
  1299. } else {
  1300. ent = gameLocal.FindEntity( name );
  1301. ReturnEntity( ent );
  1302. }
  1303. }
  1304. /*
  1305. ================
  1306. idThread::Event_Spawn
  1307. ================
  1308. */
  1309. void idThread::Event_Spawn( const char *classname ) {
  1310. idEntity *ent;
  1311. spawnArgs.Set( "classname", classname );
  1312. gameLocal.SpawnEntityDef( spawnArgs, &ent );
  1313. ReturnEntity( ent );
  1314. spawnArgs.Clear();
  1315. }
  1316. /*
  1317. ================
  1318. idThread::Event_CopySpawnArgs
  1319. ================
  1320. */
  1321. void idThread::Event_CopySpawnArgs( idEntity *ent ) {
  1322. spawnArgs.Copy( ent->spawnArgs );
  1323. }
  1324. /*
  1325. ================
  1326. idThread::Event_SetSpawnArg
  1327. ================
  1328. */
  1329. void idThread::Event_SetSpawnArg( const char *key, const char *value ) {
  1330. spawnArgs.Set( key, value );
  1331. }
  1332. /*
  1333. ================
  1334. idThread::Event_SpawnString
  1335. ================
  1336. */
  1337. void idThread::Event_SpawnString( const char *key, const char *defaultvalue ) {
  1338. const char *result;
  1339. spawnArgs.GetString( key, defaultvalue, &result );
  1340. ReturnString( result );
  1341. }
  1342. /*
  1343. ================
  1344. idThread::Event_SpawnFloat
  1345. ================
  1346. */
  1347. void idThread::Event_SpawnFloat( const char *key, float defaultvalue ) {
  1348. float result;
  1349. spawnArgs.GetFloat( key, va( "%f", defaultvalue ), result );
  1350. ReturnFloat( result );
  1351. }
  1352. /*
  1353. ================
  1354. idThread::Event_SpawnVector
  1355. ================
  1356. */
  1357. void idThread::Event_SpawnVector( const char *key, idVec3 &defaultvalue ) {
  1358. idVec3 result;
  1359. spawnArgs.GetVector( key, va( "%f %f %f", defaultvalue.x, defaultvalue.y, defaultvalue.z ), result );
  1360. ReturnVector( result );
  1361. }
  1362. /*
  1363. ================
  1364. idThread::Event_ClearPersistantArgs
  1365. ================
  1366. */
  1367. void idThread::Event_ClearPersistantArgs( void ) {
  1368. gameLocal.persistentLevelInfo.Clear();
  1369. }
  1370. /*
  1371. ================
  1372. idThread::Event_SetPersistantArg
  1373. ================
  1374. */
  1375. void idThread::Event_SetPersistantArg( const char *key, const char *value ) {
  1376. gameLocal.persistentLevelInfo.Set( key, value );
  1377. }
  1378. /*
  1379. ================
  1380. idThread::Event_GetPersistantString
  1381. ================
  1382. */
  1383. void idThread::Event_GetPersistantString( const char *key ) {
  1384. const char *result;
  1385. gameLocal.persistentLevelInfo.GetString( key, "", &result );
  1386. ReturnString( result );
  1387. }
  1388. /*
  1389. ================
  1390. idThread::Event_GetPersistantFloat
  1391. ================
  1392. */
  1393. void idThread::Event_GetPersistantFloat( const char *key ) {
  1394. float result;
  1395. gameLocal.persistentLevelInfo.GetFloat( key, "0", result );
  1396. ReturnFloat( result );
  1397. }
  1398. /*
  1399. ================
  1400. idThread::Event_GetPersistantVector
  1401. ================
  1402. */
  1403. void idThread::Event_GetPersistantVector( const char *key ) {
  1404. idVec3 result;
  1405. gameLocal.persistentLevelInfo.GetVector( key, "0 0 0", result );
  1406. ReturnVector( result );
  1407. }
  1408. /*
  1409. ================
  1410. idThread::Event_AngToForward
  1411. ================
  1412. */
  1413. void idThread::Event_AngToForward( idAngles &ang ) {
  1414. ReturnVector( ang.ToForward() );
  1415. }
  1416. /*
  1417. ================
  1418. idThread::Event_AngToRight
  1419. ================
  1420. */
  1421. void idThread::Event_AngToRight( idAngles &ang ) {
  1422. idVec3 vec;
  1423. ang.ToVectors( NULL, &vec );
  1424. ReturnVector( vec );
  1425. }
  1426. /*
  1427. ================
  1428. idThread::Event_AngToUp
  1429. ================
  1430. */
  1431. void idThread::Event_AngToUp( idAngles &ang ) {
  1432. idVec3 vec;
  1433. ang.ToVectors( NULL, NULL, &vec );
  1434. ReturnVector( vec );
  1435. }
  1436. /*
  1437. ================
  1438. idThread::Event_GetSine
  1439. ================
  1440. */
  1441. void idThread::Event_GetSine( float angle ) {
  1442. ReturnFloat( idMath::Sin( DEG2RAD( angle ) ) );
  1443. }
  1444. /*
  1445. ================
  1446. idThread::Event_GetCosine
  1447. ================
  1448. */
  1449. void idThread::Event_GetCosine( float angle ) {
  1450. ReturnFloat( idMath::Cos( DEG2RAD( angle ) ) );
  1451. }
  1452. void idThread::Event_rundeckcommand( const char *command )
  1453. {
  1454. gameLocal.RunDeckCommand( command );
  1455. }
  1456. void idThread::Event_lerp( float value1, float value2, float amount )
  1457. {
  1458. ReturnFloat( idMath::LerpShort(value1, value2, amount) );
  1459. }
  1460. //BC return a localized string.
  1461. void idThread::Event_getString( const char *value )
  1462. {
  1463. ReturnString(common->GetLanguageDict()->GetString( value ));
  1464. }
  1465. const char * idThread::Event_parseTimeMS( int value )
  1466. {
  1467. const char *output = gameLocal.ParseTimeMS(value);
  1468. ReturnString( output);
  1469. return output;
  1470. }
  1471. //BC dump in seconds, return it as human readable min/sec/ms string
  1472. const char * idThread::Event_parseTime( float value )
  1473. {
  1474. const char *output = gameLocal.ParseTime(value);
  1475. ReturnString( output);
  1476. return output;
  1477. }
  1478. const char * idThread::Event_parseTime2( float value )
  1479. {
  1480. int minutes = value / 60.0f;
  1481. float seconds = value - (minutes * 60);
  1482. const char *output = va("%d:%02d", minutes, (int)(seconds + 1) );
  1483. ReturnString( output);
  1484. return output;
  1485. }
  1486. void idThread::Event_floatRound( float value, float decimals )
  1487. {
  1488. if (decimals <= 0)
  1489. ReturnString( va( "%.0f", value ) );
  1490. else if (decimals == 1)
  1491. ReturnString( va( "%.1f", value ) );
  1492. else if (decimals == 2)
  1493. ReturnString( va( "%.2f", value ) );
  1494. else if (decimals == 3)
  1495. ReturnString( va( "%.3f", value ) );
  1496. else if (decimals == 4)
  1497. ReturnString( va( "%.4f", value ) );
  1498. else if (decimals == 5)
  1499. ReturnString( va( "%.5f", value ) );
  1500. else
  1501. ReturnString( va( "%.6f", value ) );
  1502. }
  1503. #ifdef _D3XP
  1504. /*
  1505. ================
  1506. idThread::Event_GetArcSine
  1507. ================
  1508. */
  1509. void idThread::Event_GetArcSine( float a ) {
  1510. ReturnFloat(RAD2DEG(idMath::ASin(a)));
  1511. }
  1512. /*
  1513. ================
  1514. idThread::Event_GetArcCosine
  1515. ================
  1516. */
  1517. void idThread::Event_GetArcCosine( float a ) {
  1518. ReturnFloat(RAD2DEG(idMath::ACos(a)));
  1519. }
  1520. #endif
  1521. /*
  1522. ================
  1523. idThread::Event_GetSquareRoot
  1524. ================
  1525. */
  1526. void idThread::Event_GetSquareRoot( float theSquare ) {
  1527. ReturnFloat( idMath::Sqrt( theSquare ) );
  1528. }
  1529. /*
  1530. ================
  1531. idThread::Event_VecNormalize
  1532. ================
  1533. */
  1534. void idThread::Event_VecNormalize( idVec3 &vec ) {
  1535. idVec3 n;
  1536. n = vec;
  1537. n.Normalize();
  1538. ReturnVector( n );
  1539. }
  1540. /*
  1541. ================
  1542. idThread::Event_VecLength
  1543. ================
  1544. */
  1545. void idThread::Event_VecLength( idVec3 &vec ) {
  1546. ReturnFloat( vec.Length() );
  1547. }
  1548. /*
  1549. ================
  1550. idThread::Event_VecDotProduct
  1551. ================
  1552. */
  1553. void idThread::Event_VecDotProduct( idVec3 &vec1, idVec3 &vec2 ) {
  1554. ReturnFloat( vec1 * vec2 );
  1555. }
  1556. /*
  1557. ================
  1558. idThread::Event_VecCrossProduct
  1559. ================
  1560. */
  1561. void idThread::Event_VecCrossProduct( idVec3 &vec1, idVec3 &vec2 ) {
  1562. ReturnVector( vec1.Cross( vec2 ) );
  1563. }
  1564. /*
  1565. ================
  1566. idThread::Event_VecToAngles
  1567. ================
  1568. */
  1569. void idThread::Event_VecToAngles( idVec3 &vec ) {
  1570. idAngles ang = vec.ToAngles();
  1571. ReturnVector( idVec3( ang[0], ang[1], ang[2] ) );
  1572. }
  1573. #ifdef _D3XP
  1574. /*
  1575. ================
  1576. idThread::Event_VecToOrthoBasisAngles
  1577. ================
  1578. */
  1579. void idThread::Event_VecToOrthoBasisAngles( idVec3 &vec ) {
  1580. idVec3 left, up;
  1581. idAngles ang;
  1582. vec.OrthogonalBasis( left, up );
  1583. idMat3 axis( left, up, vec );
  1584. ang = axis.ToAngles();
  1585. ReturnVector( idVec3( ang[0], ang[1], ang[2] ) );
  1586. }
  1587. void idThread::Event_RotateVector( idVec3 &vec, idVec3 &ang ) {
  1588. idAngles tempAng(ang);
  1589. idMat3 axis = tempAng.ToMat3();
  1590. idVec3 ret = vec * axis;
  1591. ReturnVector(ret);
  1592. }
  1593. #endif
  1594. /*
  1595. ================
  1596. idThread::Event_OnSignal
  1597. ================
  1598. */
  1599. void idThread::Event_OnSignal( int signal, idEntity *ent, const char *func ) {
  1600. const function_t *function;
  1601. assert( func );
  1602. if ( !ent ) {
  1603. Error( "Entity not found" );
  1604. }
  1605. if ( ( signal < 0 ) || ( signal >= NUM_SIGNALS ) ) {
  1606. Error( "Signal out of range" );
  1607. }
  1608. function = gameLocal.program.FindFunction( func );
  1609. if ( !function ) {
  1610. Error( "Function '%s' not found", func );
  1611. }
  1612. ent->SetSignal( ( signalNum_t )signal, this, function );
  1613. }
  1614. /*
  1615. ================
  1616. idThread::Event_ClearSignalThread
  1617. ================
  1618. */
  1619. void idThread::Event_ClearSignalThread( int signal, idEntity *ent ) {
  1620. if ( !ent ) {
  1621. Error( "Entity not found" );
  1622. }
  1623. if ( ( signal < 0 ) || ( signal >= NUM_SIGNALS ) ) {
  1624. Error( "Signal out of range" );
  1625. }
  1626. ent->ClearSignalThread( ( signalNum_t )signal, this );
  1627. }
  1628. /*
  1629. ================
  1630. idThread::Event_SetCamera
  1631. ================
  1632. */
  1633. void idThread::Event_SetCamera( idEntity *ent ) {
  1634. if ( !ent ) {
  1635. Error( "Entity not found" );
  1636. return;
  1637. }
  1638. if ( !ent->IsType( idCamera::Type ) ) {
  1639. Error( "Entity is not a camera" );
  1640. return;
  1641. }
  1642. gameLocal.SetCamera( ( idCamera * )ent );
  1643. }
  1644. /*
  1645. ================
  1646. idThread::Event_FirstPerson
  1647. ================
  1648. */
  1649. void idThread::Event_FirstPerson( void ) {
  1650. gameLocal.SetCamera( NULL );
  1651. }
  1652. /*
  1653. ================
  1654. idThread::Event_Trace
  1655. ================
  1656. */
  1657. void idThread::Event_Trace( const idVec3 &start, const idVec3 &end, const idVec3 &mins, const idVec3 &maxs, int contents_mask, idEntity *passEntity ) {
  1658. if ( mins == vec3_origin && maxs == vec3_origin ) {
  1659. gameLocal.clip.TracePoint( trace, start, end, contents_mask, passEntity );
  1660. } else {
  1661. gameLocal.clip.TraceBounds( trace, start, end, idBounds( mins, maxs ), contents_mask, passEntity );
  1662. }
  1663. ReturnFloat( trace.fraction );
  1664. }
  1665. /*
  1666. ================
  1667. idThread::Event_TracePoint
  1668. ================
  1669. */
  1670. void idThread::Event_TracePoint( const idVec3 &start, const idVec3 &end, int contents_mask, idEntity *passEntity ) {
  1671. gameLocal.clip.TracePoint( trace, start, end, contents_mask, passEntity );
  1672. ReturnFloat( trace.fraction );
  1673. }
  1674. void idThread::Event_GetTraceSky( void )
  1675. {
  1676. //bc hack
  1677. if ( trace.c.material->GetSurfaceFlags() >= 256 )
  1678. {
  1679. ReturnInt( 1 );
  1680. return;
  1681. }
  1682. ReturnInt( 0 );
  1683. }
  1684. /*
  1685. ================
  1686. idThread::Event_GetTraceFraction
  1687. ================
  1688. */
  1689. void idThread::Event_GetTraceFraction( void ) {
  1690. ReturnFloat( trace.fraction );
  1691. }
  1692. /*
  1693. ================
  1694. idThread::Event_GetTraceEndPos
  1695. ================
  1696. */
  1697. void idThread::Event_GetTraceEndPos( void ) {
  1698. ReturnVector( trace.endpos );
  1699. }
  1700. /*
  1701. ================
  1702. idThread::Event_GetTraceNormal
  1703. ================
  1704. */
  1705. void idThread::Event_GetTraceNormal( void ) {
  1706. if ( trace.fraction < 1.0f ) {
  1707. ReturnVector( trace.c.normal );
  1708. } else {
  1709. ReturnVector( vec3_origin );
  1710. }
  1711. }
  1712. /*
  1713. ================
  1714. idThread::Event_GetTraceEntity
  1715. ================
  1716. */
  1717. void idThread::Event_GetTraceEntity( void ) {
  1718. if ( trace.fraction < 1.0f ) {
  1719. ReturnEntity( gameLocal.entities[ trace.c.entityNum ] );
  1720. } else {
  1721. ReturnEntity( ( idEntity * )NULL );
  1722. }
  1723. }
  1724. /*
  1725. ================
  1726. idThread::Event_GetTraceJoint
  1727. ================
  1728. */
  1729. void idThread::Event_GetTraceJoint( void ) {
  1730. if ( trace.fraction < 1.0f && trace.c.id < 0 ) {
  1731. idAFEntity_Base *af = static_cast<idAFEntity_Base *>( gameLocal.entities[ trace.c.entityNum ] );
  1732. if ( af && af->IsType( idAFEntity_Base::Type ) && af->IsActiveAF() ) {
  1733. ReturnString( af->GetAnimator()->GetJointName( CLIPMODEL_ID_TO_JOINT_HANDLE( trace.c.id ) ) );
  1734. return;
  1735. }
  1736. }
  1737. ReturnString( "" );
  1738. }
  1739. /*
  1740. ================
  1741. idThread::Event_GetTraceBody
  1742. ================
  1743. */
  1744. void idThread::Event_GetTraceBody( void ) {
  1745. if ( trace.fraction < 1.0f && trace.c.id < 0 ) {
  1746. idAFEntity_Base *af = static_cast<idAFEntity_Base *>( gameLocal.entities[ trace.c.entityNum ] );
  1747. if ( af && af->IsType( idAFEntity_Base::Type ) && af->IsActiveAF() ) {
  1748. int bodyId = af->BodyForClipModelId( trace.c.id );
  1749. idAFBody *body = af->GetAFPhysics()->GetBody( bodyId );
  1750. if ( body ) {
  1751. ReturnString( body->GetName() );
  1752. return;
  1753. }
  1754. }
  1755. }
  1756. ReturnString( "" );
  1757. }
  1758. /*
  1759. ================
  1760. idThread::Event_FadeIn
  1761. ================
  1762. */
  1763. void idThread::Event_FadeIn( idVec3 &color, float time ) {
  1764. idVec4 fadeColor;
  1765. idPlayer *player;
  1766. player = gameLocal.GetLocalPlayer();
  1767. if ( player ) {
  1768. fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], 0.0f );
  1769. player->playerView.Fade(fadeColor, SEC2MS( time ) );
  1770. }
  1771. }
  1772. /*
  1773. ================
  1774. idThread::Event_FadeOut
  1775. ================
  1776. */
  1777. void idThread::Event_FadeOut( idVec3 &color, float time ) {
  1778. idVec4 fadeColor;
  1779. idPlayer *player;
  1780. player = gameLocal.GetLocalPlayer();
  1781. if ( player ) {
  1782. fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], 1.0f );
  1783. player->playerView.Fade(fadeColor, SEC2MS( time ) );
  1784. }
  1785. }
  1786. /*
  1787. ================
  1788. idThread::Event_FadeTo
  1789. ================
  1790. */
  1791. void idThread::Event_FadeTo( idVec3 &color, float alpha, float time ) {
  1792. idVec4 fadeColor;
  1793. idPlayer *player;
  1794. player = gameLocal.GetLocalPlayer();
  1795. if ( player ) {
  1796. fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], alpha );
  1797. player->playerView.Fade(fadeColor, SEC2MS( time ) );
  1798. }
  1799. }
  1800. /*
  1801. ================
  1802. idThread::Event_SetShaderParm
  1803. ================
  1804. */
  1805. void idThread::Event_SetShaderParm( int parmnum, float value ) {
  1806. if ( ( parmnum < 0 ) || ( parmnum >= MAX_GLOBAL_SHADER_PARMS ) ) {
  1807. Error( "shader parm index (%d) out of range", parmnum );
  1808. }
  1809. gameLocal.globalShaderParms[ parmnum ] = value;
  1810. }
  1811. /*
  1812. ================
  1813. idThread::Event_StartMusic
  1814. ================
  1815. */
  1816. void idThread::Event_StartMusic( const char *text ) {
  1817. gameSoundWorld->PlayShaderDirectly( text );
  1818. }
  1819. /*
  1820. ================
  1821. idThread::Event_Warning
  1822. ================
  1823. */
  1824. void idThread::Event_Warning( const char *text ) {
  1825. Warning( "%s", text );
  1826. }
  1827. /*
  1828. ================
  1829. idThread::Event_Error
  1830. ================
  1831. */
  1832. void idThread::Event_Error( const char *text ) {
  1833. Error( "%s", text );
  1834. }
  1835. /*
  1836. ================
  1837. idThread::Event_StrLen
  1838. ================
  1839. */
  1840. void idThread::Event_StrLen( const char *string ) {
  1841. int len;
  1842. len = strlen( string );
  1843. idThread::ReturnInt( len );
  1844. }
  1845. /*
  1846. ================
  1847. idThread::Event_StrLeft
  1848. ================
  1849. */
  1850. void idThread::Event_StrLeft( const char *string, int num ) {
  1851. int len;
  1852. if ( num < 0 ) {
  1853. idThread::ReturnString( "" );
  1854. return;
  1855. }
  1856. len = strlen( string );
  1857. if ( len < num ) {
  1858. idThread::ReturnString( string );
  1859. return;
  1860. }
  1861. idStr result( string, 0, num );
  1862. idThread::ReturnString( result );
  1863. }
  1864. /*
  1865. ================
  1866. idThread::Event_StrRight
  1867. ================
  1868. */
  1869. void idThread::Event_StrRight( const char *string, int num ) {
  1870. int len;
  1871. if ( num < 0 ) {
  1872. idThread::ReturnString( "" );
  1873. return;
  1874. }
  1875. len = strlen( string );
  1876. if ( len < num ) {
  1877. idThread::ReturnString( string );
  1878. return;
  1879. }
  1880. idThread::ReturnString( string + len - num );
  1881. }
  1882. /*
  1883. ================
  1884. idThread::Event_StrSkip
  1885. ================
  1886. */
  1887. void idThread::Event_StrSkip( const char *string, int num ) {
  1888. int len;
  1889. if ( num < 0 ) {
  1890. idThread::ReturnString( string );
  1891. return;
  1892. }
  1893. len = strlen( string );
  1894. if ( len < num ) {
  1895. idThread::ReturnString( "" );
  1896. return;
  1897. }
  1898. idThread::ReturnString( string + num );
  1899. }
  1900. /*
  1901. ================
  1902. idThread::Event_StrMid
  1903. ================
  1904. */
  1905. void idThread::Event_StrMid( const char *string, int start, int num ) {
  1906. int len;
  1907. if ( num < 0 ) {
  1908. idThread::ReturnString( "" );
  1909. return;
  1910. }
  1911. if ( start < 0 ) {
  1912. start = 0;
  1913. }
  1914. len = strlen( string );
  1915. if ( start > len ) {
  1916. start = len;
  1917. }
  1918. if ( start + num > len ) {
  1919. num = len - start;
  1920. }
  1921. idStr result( string, start, start + num );
  1922. idThread::ReturnString( result );
  1923. }
  1924. /*
  1925. ================
  1926. idThread::Event_StrToFloat( const char *string )
  1927. ================
  1928. */
  1929. void idThread::Event_StrToFloat( const char *string ) {
  1930. float result;
  1931. result = atof( string );
  1932. if (result > 2000000000)
  1933. result = 2000000000;
  1934. else if (result < -2000000000)
  1935. result = -2000000000;
  1936. idThread::ReturnFloat( result );
  1937. }
  1938. /*
  1939. ================
  1940. idThread::Event_RadiusDamage
  1941. ================
  1942. */
  1943. void idThread::Event_RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignore, const char *damageDefName, float dmgPower ) {
  1944. gameLocal.RadiusDamage( origin, inflictor, attacker, ignore, ignore, damageDefName, dmgPower );
  1945. }
  1946. /*
  1947. ================
  1948. idThread::Event_IsClient
  1949. ================
  1950. */
  1951. void idThread::Event_IsClient( void ) {
  1952. idThread::ReturnFloat( gameLocal.isClient );
  1953. }
  1954. /*
  1955. ================
  1956. idThread::Event_IsMultiplayer
  1957. ================
  1958. */
  1959. void idThread::Event_IsMultiplayer( void ) {
  1960. idThread::ReturnFloat( gameLocal.isMultiplayer );
  1961. }
  1962. /*
  1963. ================
  1964. idThread::Event_GetFrameTime
  1965. ================
  1966. */
  1967. void idThread::Event_GetFrameTime( void ) {
  1968. idThread::ReturnFloat( MS2SEC( gameLocal.msec ) );
  1969. }
  1970. /*
  1971. ================
  1972. idThread::Event_GetTicsPerSecond
  1973. ================
  1974. */
  1975. void idThread::Event_GetTicsPerSecond( void ) {
  1976. idThread::ReturnFloat( USERCMD_HZ );
  1977. }
  1978. /*
  1979. ================
  1980. idThread::Event_CacheSoundShader
  1981. ================
  1982. */
  1983. void idThread::Event_CacheSoundShader( const char *soundName ) {
  1984. declManager->FindSound( soundName );
  1985. }
  1986. /*
  1987. ================
  1988. idThread::Event_DebugLine
  1989. ================
  1990. */
  1991. void idThread::Event_DebugLine( const idVec3 &color, const idVec3 &start, const idVec3 &end, const float lifetime ) {
  1992. gameRenderWorld->DebugLine( idVec4( color.x, color.y, color.z, 0.0f ), start, end, SEC2MS( lifetime ) );
  1993. }
  1994. /*
  1995. ================
  1996. idThread::Event_DebugArrow
  1997. ================
  1998. */
  1999. void idThread::Event_DebugArrow( const idVec3 &color, const idVec3 &start, const idVec3 &end, const int size, const float lifetime ) {
  2000. gameRenderWorld->DebugArrow( idVec4( color.x, color.y, color.z, 0.0f ), start, end, size, SEC2MS( lifetime ) );
  2001. }
  2002. /*
  2003. ================
  2004. idThread::Event_DebugCircle
  2005. ================
  2006. */
  2007. void idThread::Event_DebugCircle( const idVec3 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const float lifetime ) {
  2008. gameRenderWorld->DebugCircle( idVec4( color.x, color.y, color.z, 0.0f ), origin, dir, radius, numSteps, SEC2MS( lifetime ) );
  2009. }
  2010. /*
  2011. ================
  2012. idThread::Event_DebugBounds
  2013. ================
  2014. */
  2015. void idThread::Event_DebugBounds( const idVec3 &color, const idVec3 &mins, const idVec3 &maxs, const float lifetime ) {
  2016. gameRenderWorld->DebugBounds( idVec4( color.x, color.y, color.z, 0.0f ), idBounds( mins, maxs ), vec3_origin, SEC2MS( lifetime ) );
  2017. }
  2018. /*
  2019. ================
  2020. idThread::Event_DrawText
  2021. ================
  2022. */
  2023. void idThread::Event_DrawText( const char *text, const idVec3 &origin, float scale, const idVec3 &color, const int align, const float lifetime ) {
  2024. gameRenderWorld->DrawText( text, origin, scale, idVec4( color.x, color.y, color.z, 0.0f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), align, SEC2MS( lifetime ) );
  2025. }
  2026. /*
  2027. ================
  2028. idThread::Event_InfluenceActive
  2029. ================
  2030. */
  2031. void idThread::Event_InfluenceActive( void ) {
  2032. idPlayer *player;
  2033. player = gameLocal.GetLocalPlayer();
  2034. if ( player && player->GetInfluenceLevel() ) {
  2035. idThread::ReturnInt( true );
  2036. } else {
  2037. idThread::ReturnInt( false );
  2038. }
  2039. }
  2040. //BC
  2041. //from DarkMod
  2042. /*
  2043. e = entity
  2044. s = string (char *)
  2045. f = float
  2046. v = vector
  2047. b = boolean
  2048. */
  2049. bool idThread::CallFunctionArgs(const function_t *func, bool clearStack, const char *fmt, ...)
  2050. {
  2051. bool rc = false;
  2052. va_list argptr;
  2053. ClearWaitFor();
  2054. va_start(argptr, fmt);
  2055. rc = interpreter.EnterFunctionVarArgVN(func, clearStack, fmt, argptr);
  2056. va_end(argptr);
  2057. return rc;
  2058. }