Script_Thread.cpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924
  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. #ifdef _D3XP
  41. const idEventDef EV_Thread_RandomInt( "randomInt", "d", 'd' );
  42. #endif
  43. const idEventDef EV_Thread_GetTime( "getTime", NULL, 'f' );
  44. const idEventDef EV_Thread_KillThread( "killthread", "s" );
  45. const idEventDef EV_Thread_SetThreadName( "threadname", "s" );
  46. const idEventDef EV_Thread_GetEntity( "getEntity", "s", 'e' );
  47. const idEventDef EV_Thread_Spawn( "spawn", "s", 'e' );
  48. const idEventDef EV_Thread_CopySpawnArgs( "copySpawnArgs", "e" );
  49. const idEventDef EV_Thread_SetSpawnArg( "setSpawnArg", "ss" );
  50. const idEventDef EV_Thread_SpawnString( "SpawnString", "ss", 's' );
  51. const idEventDef EV_Thread_SpawnFloat( "SpawnFloat", "sf", 'f' );
  52. const idEventDef EV_Thread_SpawnVector( "SpawnVector", "sv", 'v' );
  53. const idEventDef EV_Thread_ClearPersistantArgs( "clearPersistantArgs" );
  54. const idEventDef EV_Thread_SetPersistantArg( "setPersistantArg", "ss" );
  55. const idEventDef EV_Thread_GetPersistantString( "getPersistantString", "s", 's' );
  56. const idEventDef EV_Thread_GetPersistantFloat( "getPersistantFloat", "s", 'f' );
  57. const idEventDef EV_Thread_GetPersistantVector( "getPersistantVector", "s", 'v' );
  58. const idEventDef EV_Thread_AngToForward( "angToForward", "v", 'v' );
  59. const idEventDef EV_Thread_AngToRight( "angToRight", "v", 'v' );
  60. const idEventDef EV_Thread_AngToUp( "angToUp", "v", 'v' );
  61. const idEventDef EV_Thread_Sine( "sin", "f", 'f' );
  62. const idEventDef EV_Thread_Cosine( "cos", "f", 'f' );
  63. #ifdef _D3XP
  64. const idEventDef EV_Thread_ArcSine( "asin", "f", 'f' );
  65. const idEventDef EV_Thread_ArcCosine( "acos", "f", 'f' );
  66. #endif
  67. const idEventDef EV_Thread_SquareRoot( "sqrt", "f", 'f' );
  68. const idEventDef EV_Thread_Normalize( "vecNormalize", "v", 'v' );
  69. const idEventDef EV_Thread_VecLength( "vecLength", "v", 'f' );
  70. const idEventDef EV_Thread_VecDotProduct( "DotProduct", "vv", 'f' );
  71. const idEventDef EV_Thread_VecCrossProduct( "CrossProduct", "vv", 'v' );
  72. const idEventDef EV_Thread_VecToAngles( "VecToAngles", "v", 'v' );
  73. #ifdef _D3XP
  74. const idEventDef EV_Thread_VecToOrthoBasisAngles( "VecToOrthoBasisAngles", "v", 'v' );
  75. const idEventDef EV_Thread_RotateVector("rotateVector", "vv", 'v');
  76. #endif
  77. const idEventDef EV_Thread_OnSignal( "onSignal", "des" );
  78. const idEventDef EV_Thread_ClearSignal( "clearSignalThread", "de" );
  79. const idEventDef EV_Thread_SetCamera( "setCamera", "e" );
  80. const idEventDef EV_Thread_FirstPerson( "firstPerson", NULL );
  81. const idEventDef EV_Thread_Trace( "trace", "vvvvde", 'f' );
  82. const idEventDef EV_Thread_TracePoint( "tracePoint", "vvde", 'f' );
  83. const idEventDef EV_Thread_GetTraceFraction( "getTraceFraction", NULL, 'f' );
  84. const idEventDef EV_Thread_GetTraceEndPos( "getTraceEndPos", NULL, 'v' );
  85. const idEventDef EV_Thread_GetTraceNormal( "getTraceNormal", NULL, 'v' );
  86. const idEventDef EV_Thread_GetTraceEntity( "getTraceEntity", NULL, 'e' );
  87. const idEventDef EV_Thread_GetTraceJoint( "getTraceJoint", NULL, 's' );
  88. const idEventDef EV_Thread_GetTraceBody( "getTraceBody", NULL, 's' );
  89. const idEventDef EV_Thread_FadeIn( "fadeIn", "vf" );
  90. const idEventDef EV_Thread_FadeOut( "fadeOut", "vf" );
  91. const idEventDef EV_Thread_FadeTo( "fadeTo", "vff" );
  92. const idEventDef EV_Thread_StartMusic( "music", "s" );
  93. const idEventDef EV_Thread_Error( "error", "s" );
  94. const idEventDef EV_Thread_Warning( "warning", "s" );
  95. const idEventDef EV_Thread_StrLen( "strLength", "s", 'd' );
  96. const idEventDef EV_Thread_StrLeft( "strLeft", "sd", 's' );
  97. const idEventDef EV_Thread_StrRight( "strRight", "sd", 's' );
  98. const idEventDef EV_Thread_StrSkip( "strSkip", "sd", 's' );
  99. const idEventDef EV_Thread_StrMid( "strMid", "sdd", 's' );
  100. const idEventDef EV_Thread_StrToFloat( "strToFloat", "s", 'f' );
  101. const idEventDef EV_Thread_RadiusDamage( "radiusDamage", "vEEEsf" );
  102. const idEventDef EV_Thread_IsClient( "isClient", NULL, 'f' );
  103. const idEventDef EV_Thread_IsMultiplayer( "isMultiplayer", NULL, 'f' );
  104. const idEventDef EV_Thread_GetFrameTime( "getFrameTime", NULL, 'f' );
  105. const idEventDef EV_Thread_GetTicsPerSecond( "getTicsPerSecond", NULL, 'f' );
  106. const idEventDef EV_Thread_DebugLine( "debugLine", "vvvf" );
  107. const idEventDef EV_Thread_DebugArrow( "debugArrow", "vvvdf" );
  108. const idEventDef EV_Thread_DebugCircle( "debugCircle", "vvvfdf" );
  109. const idEventDef EV_Thread_DebugBounds( "debugBounds", "vvvf" );
  110. const idEventDef EV_Thread_DrawText( "drawText", "svfvdf" );
  111. const idEventDef EV_Thread_InfluenceActive( "influenceActive", NULL, 'd' );
  112. CLASS_DECLARATION( idClass, idThread )
  113. EVENT( EV_Thread_Execute, idThread::Event_Execute )
  114. EVENT( EV_Thread_TerminateThread, idThread::Event_TerminateThread )
  115. EVENT( EV_Thread_Pause, idThread::Event_Pause )
  116. EVENT( EV_Thread_Wait, idThread::Event_Wait )
  117. EVENT( EV_Thread_WaitFrame, idThread::Event_WaitFrame )
  118. EVENT( EV_Thread_WaitFor, idThread::Event_WaitFor )
  119. EVENT( EV_Thread_WaitForThread, idThread::Event_WaitForThread )
  120. EVENT( EV_Thread_Print, idThread::Event_Print )
  121. EVENT( EV_Thread_PrintLn, idThread::Event_PrintLn )
  122. EVENT( EV_Thread_Say, idThread::Event_Say )
  123. EVENT( EV_Thread_Assert, idThread::Event_Assert )
  124. EVENT( EV_Thread_Trigger, idThread::Event_Trigger )
  125. EVENT( EV_Thread_SetCvar, idThread::Event_SetCvar )
  126. EVENT( EV_Thread_GetCvar, idThread::Event_GetCvar )
  127. EVENT( EV_Thread_Random, idThread::Event_Random )
  128. #ifdef _D3XP
  129. EVENT( EV_Thread_RandomInt, idThread::Event_RandomInt )
  130. #endif
  131. EVENT( EV_Thread_GetTime, idThread::Event_GetTime )
  132. EVENT( EV_Thread_KillThread, idThread::Event_KillThread )
  133. EVENT( EV_Thread_SetThreadName, idThread::Event_SetThreadName )
  134. EVENT( EV_Thread_GetEntity, idThread::Event_GetEntity )
  135. EVENT( EV_Thread_Spawn, idThread::Event_Spawn )
  136. EVENT( EV_Thread_CopySpawnArgs, idThread::Event_CopySpawnArgs )
  137. EVENT( EV_Thread_SetSpawnArg, idThread::Event_SetSpawnArg )
  138. EVENT( EV_Thread_SpawnString, idThread::Event_SpawnString )
  139. EVENT( EV_Thread_SpawnFloat, idThread::Event_SpawnFloat )
  140. EVENT( EV_Thread_SpawnVector, idThread::Event_SpawnVector )
  141. EVENT( EV_Thread_ClearPersistantArgs, idThread::Event_ClearPersistantArgs )
  142. EVENT( EV_Thread_SetPersistantArg, idThread::Event_SetPersistantArg )
  143. EVENT( EV_Thread_GetPersistantString, idThread::Event_GetPersistantString )
  144. EVENT( EV_Thread_GetPersistantFloat, idThread::Event_GetPersistantFloat )
  145. EVENT( EV_Thread_GetPersistantVector, idThread::Event_GetPersistantVector )
  146. EVENT( EV_Thread_AngToForward, idThread::Event_AngToForward )
  147. EVENT( EV_Thread_AngToRight, idThread::Event_AngToRight )
  148. EVENT( EV_Thread_AngToUp, idThread::Event_AngToUp )
  149. EVENT( EV_Thread_Sine, idThread::Event_GetSine )
  150. EVENT( EV_Thread_Cosine, idThread::Event_GetCosine )
  151. #ifdef _D3XP
  152. EVENT( EV_Thread_ArcSine, idThread::Event_GetArcSine )
  153. EVENT( EV_Thread_ArcCosine, idThread::Event_GetArcCosine )
  154. #endif
  155. EVENT( EV_Thread_SquareRoot, idThread::Event_GetSquareRoot )
  156. EVENT( EV_Thread_Normalize, idThread::Event_VecNormalize )
  157. EVENT( EV_Thread_VecLength, idThread::Event_VecLength )
  158. EVENT( EV_Thread_VecDotProduct, idThread::Event_VecDotProduct )
  159. EVENT( EV_Thread_VecCrossProduct, idThread::Event_VecCrossProduct )
  160. EVENT( EV_Thread_VecToAngles, idThread::Event_VecToAngles )
  161. #ifdef _D3XP
  162. EVENT( EV_Thread_VecToOrthoBasisAngles, idThread::Event_VecToOrthoBasisAngles )
  163. EVENT( EV_Thread_RotateVector, idThread::Event_RotateVector )
  164. #endif
  165. EVENT( EV_Thread_OnSignal, idThread::Event_OnSignal )
  166. EVENT( EV_Thread_ClearSignal, idThread::Event_ClearSignalThread )
  167. EVENT( EV_Thread_SetCamera, idThread::Event_SetCamera )
  168. EVENT( EV_Thread_FirstPerson, idThread::Event_FirstPerson )
  169. EVENT( EV_Thread_Trace, idThread::Event_Trace )
  170. EVENT( EV_Thread_TracePoint, idThread::Event_TracePoint )
  171. EVENT( EV_Thread_GetTraceFraction, idThread::Event_GetTraceFraction )
  172. EVENT( EV_Thread_GetTraceEndPos, idThread::Event_GetTraceEndPos )
  173. EVENT( EV_Thread_GetTraceNormal, idThread::Event_GetTraceNormal )
  174. EVENT( EV_Thread_GetTraceEntity, idThread::Event_GetTraceEntity )
  175. EVENT( EV_Thread_GetTraceJoint, idThread::Event_GetTraceJoint )
  176. EVENT( EV_Thread_GetTraceBody, idThread::Event_GetTraceBody )
  177. EVENT( EV_Thread_FadeIn, idThread::Event_FadeIn )
  178. EVENT( EV_Thread_FadeOut, idThread::Event_FadeOut )
  179. EVENT( EV_Thread_FadeTo, idThread::Event_FadeTo )
  180. EVENT( EV_SetShaderParm, idThread::Event_SetShaderParm )
  181. EVENT( EV_Thread_StartMusic, idThread::Event_StartMusic )
  182. EVENT( EV_Thread_Warning, idThread::Event_Warning )
  183. EVENT( EV_Thread_Error, idThread::Event_Error )
  184. EVENT( EV_Thread_StrLen, idThread::Event_StrLen )
  185. EVENT( EV_Thread_StrLeft, idThread::Event_StrLeft )
  186. EVENT( EV_Thread_StrRight, idThread::Event_StrRight )
  187. EVENT( EV_Thread_StrSkip, idThread::Event_StrSkip )
  188. EVENT( EV_Thread_StrMid, idThread::Event_StrMid )
  189. EVENT( EV_Thread_StrToFloat, idThread::Event_StrToFloat )
  190. EVENT( EV_Thread_RadiusDamage, idThread::Event_RadiusDamage )
  191. EVENT( EV_Thread_IsClient, idThread::Event_IsClient )
  192. EVENT( EV_Thread_IsMultiplayer, idThread::Event_IsMultiplayer )
  193. EVENT( EV_Thread_GetFrameTime, idThread::Event_GetFrameTime )
  194. EVENT( EV_Thread_GetTicsPerSecond, idThread::Event_GetTicsPerSecond )
  195. EVENT( EV_CacheSoundShader, idThread::Event_CacheSoundShader )
  196. EVENT( EV_Thread_DebugLine, idThread::Event_DebugLine )
  197. EVENT( EV_Thread_DebugArrow, idThread::Event_DebugArrow )
  198. EVENT( EV_Thread_DebugCircle, idThread::Event_DebugCircle )
  199. EVENT( EV_Thread_DebugBounds, idThread::Event_DebugBounds )
  200. EVENT( EV_Thread_DrawText, idThread::Event_DrawText )
  201. EVENT( EV_Thread_InfluenceActive, idThread::Event_InfluenceActive )
  202. END_CLASS
  203. idThread *idThread::currentThread = NULL;
  204. int idThread::threadIndex = 0;
  205. idList<idThread *> idThread::threadList;
  206. trace_t idThread::trace;
  207. /*
  208. ================
  209. idThread::CurrentThread
  210. ================
  211. */
  212. idThread *idThread::CurrentThread( void ) {
  213. return currentThread;
  214. }
  215. /*
  216. ================
  217. idThread::CurrentThreadNum
  218. ================
  219. */
  220. int idThread::CurrentThreadNum( void ) {
  221. if ( currentThread ) {
  222. return currentThread->GetThreadNum();
  223. } else {
  224. return 0;
  225. }
  226. }
  227. /*
  228. ================
  229. idThread::BeginMultiFrameEvent
  230. ================
  231. */
  232. bool idThread::BeginMultiFrameEvent( idEntity *ent, const idEventDef *event ) {
  233. if ( !currentThread ) {
  234. gameLocal.Error( "idThread::BeginMultiFrameEvent called without a current thread" );
  235. }
  236. return currentThread->interpreter.BeginMultiFrameEvent( ent, event );
  237. }
  238. /*
  239. ================
  240. idThread::EndMultiFrameEvent
  241. ================
  242. */
  243. void idThread::EndMultiFrameEvent( idEntity *ent, const idEventDef *event ) {
  244. if ( !currentThread ) {
  245. gameLocal.Error( "idThread::EndMultiFrameEvent called without a current thread" );
  246. }
  247. currentThread->interpreter.EndMultiFrameEvent( ent, event );
  248. }
  249. /*
  250. ================
  251. idThread::idThread
  252. ================
  253. */
  254. idThread::idThread() {
  255. Init();
  256. SetThreadName( va( "thread_%d", threadIndex ) );
  257. if ( g_debugScript.GetBool() ) {
  258. gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  259. }
  260. }
  261. /*
  262. ================
  263. idThread::idThread
  264. ================
  265. */
  266. idThread::idThread( idEntity *self, const function_t *func ) {
  267. assert( self );
  268. Init();
  269. SetThreadName( self->name );
  270. interpreter.EnterObjectFunction( self, func, false );
  271. if ( g_debugScript.GetBool() ) {
  272. gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  273. }
  274. }
  275. /*
  276. ================
  277. idThread::idThread
  278. ================
  279. */
  280. idThread::idThread( const function_t *func ) {
  281. assert( func );
  282. Init();
  283. SetThreadName( func->Name() );
  284. interpreter.EnterFunction( func, false );
  285. if ( g_debugScript.GetBool() ) {
  286. gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  287. }
  288. }
  289. /*
  290. ================
  291. idThread::idThread
  292. ================
  293. */
  294. idThread::idThread( idInterpreter *source, const function_t *func, int args ) {
  295. Init();
  296. interpreter.ThreadCall( source, func, args );
  297. if ( g_debugScript.GetBool() ) {
  298. gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  299. }
  300. }
  301. /*
  302. ================
  303. idThread::idThread
  304. ================
  305. */
  306. idThread::idThread( idInterpreter *source, idEntity *self, const function_t *func, int args ) {
  307. assert( self );
  308. Init();
  309. SetThreadName( self->name );
  310. interpreter.ThreadCall( source, func, args );
  311. if ( g_debugScript.GetBool() ) {
  312. gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  313. }
  314. }
  315. /*
  316. ================
  317. idThread::~idThread
  318. ================
  319. */
  320. idThread::~idThread() {
  321. idThread *thread;
  322. int i;
  323. int n;
  324. if ( g_debugScript.GetBool() ) {
  325. gameLocal.Printf( "%d: end thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() );
  326. }
  327. threadList.Remove( this );
  328. n = threadList.Num();
  329. for( i = 0; i < n; i++ ) {
  330. thread = threadList[ i ];
  331. if ( thread->WaitingOnThread() == this ) {
  332. thread->ThreadCallback( this );
  333. }
  334. }
  335. if ( currentThread == this ) {
  336. currentThread = NULL;
  337. }
  338. }
  339. /*
  340. ================
  341. idThread::ManualDelete
  342. ================
  343. */
  344. void idThread::ManualDelete( void ) {
  345. interpreter.terminateOnExit = false;
  346. }
  347. /*
  348. ================
  349. idThread::Save
  350. ================
  351. */
  352. void idThread::Save( idSaveGame *savefile ) const {
  353. // We will check on restore that threadNum is still the same,
  354. // threads should have been restored in the same order.
  355. savefile->WriteInt( threadNum );
  356. savefile->WriteObject( waitingForThread );
  357. savefile->WriteInt( waitingFor );
  358. savefile->WriteInt( waitingUntil );
  359. interpreter.Save( savefile );
  360. savefile->WriteDict( &spawnArgs );
  361. savefile->WriteString( threadName );
  362. savefile->WriteInt( lastExecuteTime );
  363. savefile->WriteInt( creationTime );
  364. savefile->WriteBool( manualControl );
  365. }
  366. /*
  367. ================
  368. idThread::Restore
  369. ================
  370. */
  371. void idThread::Restore( idRestoreGame *savefile ) {
  372. savefile->ReadInt( threadNum );
  373. savefile->ReadObject( reinterpret_cast<idClass *&>( waitingForThread ) );
  374. savefile->ReadInt( waitingFor );
  375. savefile->ReadInt( waitingUntil );
  376. interpreter.Restore( savefile );
  377. savefile->ReadDict( &spawnArgs );
  378. savefile->ReadString( threadName );
  379. savefile->ReadInt( lastExecuteTime );
  380. savefile->ReadInt( creationTime );
  381. savefile->ReadBool( manualControl );
  382. }
  383. /*
  384. ================
  385. idThread::Init
  386. ================
  387. */
  388. void idThread::Init( void ) {
  389. // create a unique threadNum
  390. do {
  391. threadIndex++;
  392. if ( threadIndex == 0 ) {
  393. threadIndex = 1;
  394. }
  395. } while( GetThread( threadIndex ) );
  396. threadNum = threadIndex;
  397. threadList.Append( this );
  398. creationTime = gameLocal.time;
  399. lastExecuteTime = 0;
  400. manualControl = false;
  401. ClearWaitFor();
  402. interpreter.SetThread( this );
  403. }
  404. /*
  405. ================
  406. idThread::GetThread
  407. ================
  408. */
  409. idThread *idThread::GetThread( int num ) {
  410. int i;
  411. int n;
  412. idThread *thread;
  413. n = threadList.Num();
  414. for( i = 0; i < n; i++ ) {
  415. thread = threadList[ i ];
  416. if ( thread->GetThreadNum() == num ) {
  417. return thread;
  418. }
  419. }
  420. return NULL;
  421. }
  422. /*
  423. ================
  424. idThread::DisplayInfo
  425. ================
  426. */
  427. void idThread::DisplayInfo( void ) {
  428. gameLocal.Printf(
  429. "%12i: '%s'\n"
  430. " File: %s(%d)\n"
  431. " Created: %d (%d ms ago)\n"
  432. " Status: ",
  433. threadNum, threadName.c_str(),
  434. interpreter.CurrentFile(), interpreter.CurrentLine(),
  435. creationTime, gameLocal.time - creationTime );
  436. if ( interpreter.threadDying ) {
  437. gameLocal.Printf( "Dying\n" );
  438. } else if ( interpreter.doneProcessing ) {
  439. gameLocal.Printf(
  440. "Paused since %d (%d ms)\n"
  441. " Reason: ", lastExecuteTime, gameLocal.time - lastExecuteTime );
  442. if ( waitingForThread ) {
  443. gameLocal.Printf( "Waiting for thread #%3i '%s'\n", waitingForThread->GetThreadNum(), waitingForThread->GetThreadName() );
  444. } else if ( ( waitingFor != ENTITYNUM_NONE ) && ( gameLocal.entities[ waitingFor ] ) ) {
  445. gameLocal.Printf( "Waiting for entity #%3i '%s'\n", waitingFor, gameLocal.entities[ waitingFor ]->name.c_str() );
  446. } else if ( waitingUntil ) {
  447. gameLocal.Printf( "Waiting until %d (%d ms total wait time)\n", waitingUntil, waitingUntil - lastExecuteTime );
  448. } else {
  449. gameLocal.Printf( "None\n" );
  450. }
  451. } else {
  452. gameLocal.Printf( "Processing\n" );
  453. }
  454. interpreter.DisplayInfo();
  455. gameLocal.Printf( "\n" );
  456. }
  457. /*
  458. ================
  459. idThread::ListThreads_f
  460. ================
  461. */
  462. void idThread::ListThreads_f( const idCmdArgs &args ) {
  463. int i;
  464. int n;
  465. n = threadList.Num();
  466. for( i = 0; i < n; i++ ) {
  467. //threadList[ i ]->DisplayInfo();
  468. gameLocal.Printf( "%3i: %-20s : %s(%d)\n", threadList[ i ]->threadNum, threadList[ i ]->threadName.c_str(), threadList[ i ]->interpreter.CurrentFile(), threadList[ i ]->interpreter.CurrentLine() );
  469. }
  470. gameLocal.Printf( "%d active threads\n\n", n );
  471. }
  472. /*
  473. ================
  474. idThread::Restart
  475. ================
  476. */
  477. void idThread::Restart( void ) {
  478. int i;
  479. int n;
  480. // reset the threadIndex
  481. threadIndex = 0;
  482. currentThread = NULL;
  483. n = threadList.Num();
  484. for( i = n - 1; i >= 0; i-- ) {
  485. delete threadList[ i ];
  486. }
  487. threadList.Clear();
  488. memset( &trace, 0, sizeof( trace ) );
  489. trace.c.entityNum = ENTITYNUM_NONE;
  490. }
  491. /*
  492. ================
  493. idThread::DelayedStart
  494. ================
  495. */
  496. void idThread::DelayedStart( int delay ) {
  497. CancelEvents( &EV_Thread_Execute );
  498. if ( gameLocal.time <= 0 ) {
  499. delay++;
  500. }
  501. PostEventMS( &EV_Thread_Execute, delay );
  502. }
  503. /*
  504. ================
  505. idThread::Start
  506. ================
  507. */
  508. bool idThread::Start( void ) {
  509. bool result;
  510. CancelEvents( &EV_Thread_Execute );
  511. result = Execute();
  512. return result;
  513. }
  514. /*
  515. ================
  516. idThread::SetThreadName
  517. ================
  518. */
  519. void idThread::SetThreadName( const char *name ) {
  520. threadName = name;
  521. }
  522. /*
  523. ================
  524. idThread::ObjectMoveDone
  525. ================
  526. */
  527. void idThread::ObjectMoveDone( int threadnum, idEntity *obj ) {
  528. idThread *thread;
  529. if ( !threadnum ) {
  530. return;
  531. }
  532. thread = GetThread( threadnum );
  533. if ( thread ) {
  534. thread->ObjectMoveDone( obj );
  535. }
  536. }
  537. /*
  538. ================
  539. idThread::End
  540. ================
  541. */
  542. void idThread::End( void ) {
  543. // Tell thread to die. It will exit on its own.
  544. Pause();
  545. interpreter.threadDying = true;
  546. }
  547. /*
  548. ================
  549. idThread::KillThread
  550. ================
  551. */
  552. void idThread::KillThread( const char *name ) {
  553. int i;
  554. int num;
  555. int len;
  556. const char *ptr;
  557. idThread *thread;
  558. // see if the name uses a wild card
  559. ptr = strchr( name, '*' );
  560. if ( ptr ) {
  561. len = ptr - name;
  562. } else {
  563. len = strlen( name );
  564. }
  565. // kill only those threads whose name matches name
  566. num = threadList.Num();
  567. for( i = 0; i < num; i++ ) {
  568. thread = threadList[ i ];
  569. if ( !idStr::Cmpn( thread->GetThreadName(), name, len ) ) {
  570. thread->End();
  571. }
  572. }
  573. }
  574. /*
  575. ================
  576. idThread::KillThread
  577. ================
  578. */
  579. void idThread::KillThread( int num ) {
  580. idThread *thread;
  581. thread = GetThread( num );
  582. if ( thread ) {
  583. // Tell thread to die. It will delete itself on it's own.
  584. thread->End();
  585. }
  586. }
  587. /*
  588. ================
  589. idThread::Execute
  590. ================
  591. */
  592. bool idThread::Execute( void ) {
  593. idThread *oldThread;
  594. bool done;
  595. if ( manualControl && ( waitingUntil > gameLocal.time ) ) {
  596. return false;
  597. }
  598. oldThread = currentThread;
  599. currentThread = this;
  600. lastExecuteTime = gameLocal.time;
  601. ClearWaitFor();
  602. done = interpreter.Execute();
  603. if ( done ) {
  604. End();
  605. if ( interpreter.terminateOnExit ) {
  606. PostEventMS( &EV_Remove, 0 );
  607. }
  608. } else if ( !manualControl ) {
  609. if ( waitingUntil > lastExecuteTime ) {
  610. PostEventMS( &EV_Thread_Execute, waitingUntil - lastExecuteTime );
  611. } else if ( interpreter.MultiFrameEventInProgress() ) {
  612. PostEventMS( &EV_Thread_Execute, gameLocal.msec );
  613. }
  614. }
  615. currentThread = oldThread;
  616. return done;
  617. }
  618. /*
  619. ================
  620. idThread::IsWaiting
  621. Checks if thread is still waiting for some event to occur.
  622. ================
  623. */
  624. bool idThread::IsWaiting( void ) {
  625. if ( waitingForThread || ( waitingFor != ENTITYNUM_NONE ) ) {
  626. return true;
  627. }
  628. if ( waitingUntil && ( waitingUntil > gameLocal.time ) ) {
  629. return true;
  630. }
  631. return false;
  632. }
  633. /*
  634. ================
  635. idThread::CallFunction
  636. NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function.
  637. ================
  638. */
  639. void idThread::CallFunction( const function_t *func, bool clearStack ) {
  640. ClearWaitFor();
  641. interpreter.EnterFunction( func, clearStack );
  642. }
  643. /*
  644. ================
  645. idThread::CallFunction
  646. NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function.
  647. ================
  648. */
  649. void idThread::CallFunction( idEntity *self, const function_t *func, bool clearStack ) {
  650. assert( self );
  651. ClearWaitFor();
  652. interpreter.EnterObjectFunction( self, func, clearStack );
  653. }
  654. /*
  655. ================
  656. idThread::ClearWaitFor
  657. ================
  658. */
  659. void idThread::ClearWaitFor( void ) {
  660. waitingFor = ENTITYNUM_NONE;
  661. waitingForThread = NULL;
  662. waitingUntil = 0;
  663. }
  664. /*
  665. ================
  666. idThread::IsWaitingFor
  667. ================
  668. */
  669. bool idThread::IsWaitingFor( idEntity *obj ) {
  670. assert( obj );
  671. return waitingFor == obj->entityNumber;
  672. }
  673. /*
  674. ================
  675. idThread::ObjectMoveDone
  676. ================
  677. */
  678. void idThread::ObjectMoveDone( idEntity *obj ) {
  679. assert( obj );
  680. if ( IsWaitingFor( obj ) ) {
  681. ClearWaitFor();
  682. DelayedStart( 0 );
  683. }
  684. }
  685. /*
  686. ================
  687. idThread::ThreadCallback
  688. ================
  689. */
  690. void idThread::ThreadCallback( idThread *thread ) {
  691. if ( interpreter.threadDying ) {
  692. return;
  693. }
  694. if ( thread == waitingForThread ) {
  695. ClearWaitFor();
  696. DelayedStart( 0 );
  697. }
  698. }
  699. /*
  700. ================
  701. idThread::Event_SetThreadName
  702. ================
  703. */
  704. void idThread::Event_SetThreadName( const char *name ) {
  705. SetThreadName( name );
  706. }
  707. /*
  708. ================
  709. idThread::Error
  710. ================
  711. */
  712. void idThread::Error( const char *fmt, ... ) const {
  713. va_list argptr;
  714. char text[ 1024 ];
  715. va_start( argptr, fmt );
  716. vsprintf( text, fmt, argptr );
  717. va_end( argptr );
  718. interpreter.Error( text );
  719. }
  720. /*
  721. ================
  722. idThread::Warning
  723. ================
  724. */
  725. void idThread::Warning( const char *fmt, ... ) const {
  726. va_list argptr;
  727. char text[ 1024 ];
  728. va_start( argptr, fmt );
  729. vsprintf( text, fmt, argptr );
  730. va_end( argptr );
  731. interpreter.Warning( text );
  732. }
  733. /*
  734. ================
  735. idThread::ReturnString
  736. ================
  737. */
  738. void idThread::ReturnString( const char *text ) {
  739. gameLocal.program.ReturnString( text );
  740. }
  741. /*
  742. ================
  743. idThread::ReturnFloat
  744. ================
  745. */
  746. void idThread::ReturnFloat( float value ) {
  747. gameLocal.program.ReturnFloat( value );
  748. }
  749. /*
  750. ================
  751. idThread::ReturnInt
  752. ================
  753. */
  754. void idThread::ReturnInt( int value ) {
  755. // true integers aren't supported in the compiler,
  756. // so int values are stored as floats
  757. gameLocal.program.ReturnFloat( value );
  758. }
  759. /*
  760. ================
  761. idThread::ReturnVector
  762. ================
  763. */
  764. void idThread::ReturnVector( idVec3 const &vec ) {
  765. gameLocal.program.ReturnVector( vec );
  766. }
  767. /*
  768. ================
  769. idThread::ReturnEntity
  770. ================
  771. */
  772. void idThread::ReturnEntity( idEntity *ent ) {
  773. gameLocal.program.ReturnEntity( ent );
  774. }
  775. /*
  776. ================
  777. idThread::Event_Execute
  778. ================
  779. */
  780. void idThread::Event_Execute( void ) {
  781. Execute();
  782. }
  783. /*
  784. ================
  785. idThread::Pause
  786. ================
  787. */
  788. void idThread::Pause( void ) {
  789. ClearWaitFor();
  790. interpreter.doneProcessing = true;
  791. }
  792. /*
  793. ================
  794. idThread::WaitMS
  795. ================
  796. */
  797. void idThread::WaitMS( int time ) {
  798. Pause();
  799. waitingUntil = gameLocal.time + time;
  800. }
  801. /*
  802. ================
  803. idThread::WaitSec
  804. ================
  805. */
  806. void idThread::WaitSec( float time ) {
  807. WaitMS( SEC2MS( time ) );
  808. }
  809. /*
  810. ================
  811. idThread::WaitFrame
  812. ================
  813. */
  814. void idThread::WaitFrame( void ) {
  815. Pause();
  816. // manual control threads don't set waitingUntil so that they can be run again
  817. // that frame if necessary.
  818. if ( !manualControl ) {
  819. waitingUntil = gameLocal.time + gameLocal.msec;
  820. }
  821. }
  822. /***********************************************************************
  823. Script callable events
  824. ***********************************************************************/
  825. /*
  826. ================
  827. idThread::Event_TerminateThread
  828. ================
  829. */
  830. void idThread::Event_TerminateThread( int num ) {
  831. idThread *thread;
  832. thread = GetThread( num );
  833. KillThread( num );
  834. }
  835. /*
  836. ================
  837. idThread::Event_Pause
  838. ================
  839. */
  840. void idThread::Event_Pause( void ) {
  841. Pause();
  842. }
  843. /*
  844. ================
  845. idThread::Event_Wait
  846. ================
  847. */
  848. void idThread::Event_Wait( float time ) {
  849. WaitSec( time );
  850. }
  851. /*
  852. ================
  853. idThread::Event_WaitFrame
  854. ================
  855. */
  856. void idThread::Event_WaitFrame( void ) {
  857. WaitFrame();
  858. }
  859. /*
  860. ================
  861. idThread::Event_WaitFor
  862. ================
  863. */
  864. void idThread::Event_WaitFor( idEntity *ent ) {
  865. if ( ent && ent->RespondsTo( EV_Thread_SetCallback ) ) {
  866. ent->ProcessEvent( &EV_Thread_SetCallback );
  867. if ( gameLocal.program.GetReturnedInteger() ) {
  868. Pause();
  869. waitingFor = ent->entityNumber;
  870. }
  871. }
  872. }
  873. /*
  874. ================
  875. idThread::Event_WaitForThread
  876. ================
  877. */
  878. void idThread::Event_WaitForThread( int num ) {
  879. idThread *thread;
  880. thread = GetThread( num );
  881. if ( !thread ) {
  882. if ( g_debugScript.GetBool() ) {
  883. // just print a warning and continue executing
  884. Warning( "Thread %d not running", num );
  885. }
  886. } else {
  887. Pause();
  888. waitingForThread = thread;
  889. }
  890. }
  891. /*
  892. ================
  893. idThread::Event_Print
  894. ================
  895. */
  896. void idThread::Event_Print( const char *text ) {
  897. gameLocal.Printf( "%s", text );
  898. }
  899. /*
  900. ================
  901. idThread::Event_PrintLn
  902. ================
  903. */
  904. void idThread::Event_PrintLn( const char *text ) {
  905. gameLocal.Printf( "%s\n", text );
  906. }
  907. /*
  908. ================
  909. idThread::Event_Say
  910. ================
  911. */
  912. void idThread::Event_Say( const char *text ) {
  913. cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say \"%s\"", text ) );
  914. }
  915. /*
  916. ================
  917. idThread::Event_Assert
  918. ================
  919. */
  920. void idThread::Event_Assert( float value ) {
  921. assert( value );
  922. }
  923. /*
  924. ================
  925. idThread::Event_Trigger
  926. ================
  927. */
  928. void idThread::Event_Trigger( idEntity *ent ) {
  929. if ( ent ) {
  930. ent->Signal( SIG_TRIGGER );
  931. ent->ProcessEvent( &EV_Activate, gameLocal.GetLocalPlayer() );
  932. ent->TriggerGuis();
  933. }
  934. }
  935. /*
  936. ================
  937. idThread::Event_SetCvar
  938. ================
  939. */
  940. void idThread::Event_SetCvar( const char *name, const char *value ) const {
  941. cvarSystem->SetCVarString( name, value );
  942. }
  943. /*
  944. ================
  945. idThread::Event_GetCvar
  946. ================
  947. */
  948. void idThread::Event_GetCvar( const char *name ) const {
  949. ReturnString( cvarSystem->GetCVarString( name ) );
  950. }
  951. /*
  952. ================
  953. idThread::Event_Random
  954. ================
  955. */
  956. void idThread::Event_Random( float range ) const {
  957. float result;
  958. result = gameLocal.random.RandomFloat();
  959. ReturnFloat( range * result );
  960. }
  961. #ifdef _D3XP
  962. void idThread::Event_RandomInt( int range ) const {
  963. int result;
  964. result = gameLocal.random.RandomInt(range);
  965. ReturnFloat(result);
  966. }
  967. #endif
  968. /*
  969. ================
  970. idThread::Event_GetTime
  971. ================
  972. */
  973. void idThread::Event_GetTime( void ) {
  974. ReturnFloat( MS2SEC( gameLocal.realClientTime ) );
  975. }
  976. /*
  977. ================
  978. idThread::Event_KillThread
  979. ================
  980. */
  981. void idThread::Event_KillThread( const char *name ) {
  982. KillThread( name );
  983. }
  984. /*
  985. ================
  986. idThread::Event_GetEntity
  987. ================
  988. */
  989. void idThread::Event_GetEntity( const char *name ) {
  990. int entnum;
  991. idEntity *ent;
  992. assert( name );
  993. if ( name[ 0 ] == '*' ) {
  994. entnum = atoi( &name[ 1 ] );
  995. if ( ( entnum < 0 ) || ( entnum >= MAX_GENTITIES ) ) {
  996. Error( "Entity number in string out of range." );
  997. }
  998. ReturnEntity( gameLocal.entities[ entnum ] );
  999. } else {
  1000. ent = gameLocal.FindEntity( name );
  1001. ReturnEntity( ent );
  1002. }
  1003. }
  1004. /*
  1005. ================
  1006. idThread::Event_Spawn
  1007. ================
  1008. */
  1009. void idThread::Event_Spawn( const char *classname ) {
  1010. idEntity *ent;
  1011. spawnArgs.Set( "classname", classname );
  1012. gameLocal.SpawnEntityDef( spawnArgs, &ent );
  1013. ReturnEntity( ent );
  1014. spawnArgs.Clear();
  1015. }
  1016. /*
  1017. ================
  1018. idThread::Event_CopySpawnArgs
  1019. ================
  1020. */
  1021. void idThread::Event_CopySpawnArgs( idEntity *ent ) {
  1022. spawnArgs.Copy( ent->spawnArgs );
  1023. }
  1024. /*
  1025. ================
  1026. idThread::Event_SetSpawnArg
  1027. ================
  1028. */
  1029. void idThread::Event_SetSpawnArg( const char *key, const char *value ) {
  1030. spawnArgs.Set( key, value );
  1031. }
  1032. /*
  1033. ================
  1034. idThread::Event_SpawnString
  1035. ================
  1036. */
  1037. void idThread::Event_SpawnString( const char *key, const char *defaultvalue ) {
  1038. const char *result;
  1039. spawnArgs.GetString( key, defaultvalue, &result );
  1040. ReturnString( result );
  1041. }
  1042. /*
  1043. ================
  1044. idThread::Event_SpawnFloat
  1045. ================
  1046. */
  1047. void idThread::Event_SpawnFloat( const char *key, float defaultvalue ) {
  1048. float result;
  1049. spawnArgs.GetFloat( key, va( "%f", defaultvalue ), result );
  1050. ReturnFloat( result );
  1051. }
  1052. /*
  1053. ================
  1054. idThread::Event_SpawnVector
  1055. ================
  1056. */
  1057. void idThread::Event_SpawnVector( const char *key, idVec3 &defaultvalue ) {
  1058. idVec3 result;
  1059. spawnArgs.GetVector( key, va( "%f %f %f", defaultvalue.x, defaultvalue.y, defaultvalue.z ), result );
  1060. ReturnVector( result );
  1061. }
  1062. /*
  1063. ================
  1064. idThread::Event_ClearPersistantArgs
  1065. ================
  1066. */
  1067. void idThread::Event_ClearPersistantArgs( void ) {
  1068. gameLocal.persistentLevelInfo.Clear();
  1069. }
  1070. /*
  1071. ================
  1072. idThread::Event_SetPersistantArg
  1073. ================
  1074. */
  1075. void idThread::Event_SetPersistantArg( const char *key, const char *value ) {
  1076. gameLocal.persistentLevelInfo.Set( key, value );
  1077. }
  1078. /*
  1079. ================
  1080. idThread::Event_GetPersistantString
  1081. ================
  1082. */
  1083. void idThread::Event_GetPersistantString( const char *key ) {
  1084. const char *result;
  1085. gameLocal.persistentLevelInfo.GetString( key, "", &result );
  1086. ReturnString( result );
  1087. }
  1088. /*
  1089. ================
  1090. idThread::Event_GetPersistantFloat
  1091. ================
  1092. */
  1093. void idThread::Event_GetPersistantFloat( const char *key ) {
  1094. float result;
  1095. gameLocal.persistentLevelInfo.GetFloat( key, "0", result );
  1096. ReturnFloat( result );
  1097. }
  1098. /*
  1099. ================
  1100. idThread::Event_GetPersistantVector
  1101. ================
  1102. */
  1103. void idThread::Event_GetPersistantVector( const char *key ) {
  1104. idVec3 result;
  1105. gameLocal.persistentLevelInfo.GetVector( key, "0 0 0", result );
  1106. ReturnVector( result );
  1107. }
  1108. /*
  1109. ================
  1110. idThread::Event_AngToForward
  1111. ================
  1112. */
  1113. void idThread::Event_AngToForward( idAngles &ang ) {
  1114. ReturnVector( ang.ToForward() );
  1115. }
  1116. /*
  1117. ================
  1118. idThread::Event_AngToRight
  1119. ================
  1120. */
  1121. void idThread::Event_AngToRight( idAngles &ang ) {
  1122. idVec3 vec;
  1123. ang.ToVectors( NULL, &vec );
  1124. ReturnVector( vec );
  1125. }
  1126. /*
  1127. ================
  1128. idThread::Event_AngToUp
  1129. ================
  1130. */
  1131. void idThread::Event_AngToUp( idAngles &ang ) {
  1132. idVec3 vec;
  1133. ang.ToVectors( NULL, NULL, &vec );
  1134. ReturnVector( vec );
  1135. }
  1136. /*
  1137. ================
  1138. idThread::Event_GetSine
  1139. ================
  1140. */
  1141. void idThread::Event_GetSine( float angle ) {
  1142. ReturnFloat( idMath::Sin( DEG2RAD( angle ) ) );
  1143. }
  1144. /*
  1145. ================
  1146. idThread::Event_GetCosine
  1147. ================
  1148. */
  1149. void idThread::Event_GetCosine( float angle ) {
  1150. ReturnFloat( idMath::Cos( DEG2RAD( angle ) ) );
  1151. }
  1152. #ifdef _D3XP
  1153. /*
  1154. ================
  1155. idThread::Event_GetArcSine
  1156. ================
  1157. */
  1158. void idThread::Event_GetArcSine( float a ) {
  1159. ReturnFloat(RAD2DEG(idMath::ASin(a)));
  1160. }
  1161. /*
  1162. ================
  1163. idThread::Event_GetArcCosine
  1164. ================
  1165. */
  1166. void idThread::Event_GetArcCosine( float a ) {
  1167. ReturnFloat(RAD2DEG(idMath::ACos(a)));
  1168. }
  1169. #endif
  1170. /*
  1171. ================
  1172. idThread::Event_GetSquareRoot
  1173. ================
  1174. */
  1175. void idThread::Event_GetSquareRoot( float theSquare ) {
  1176. ReturnFloat( idMath::Sqrt( theSquare ) );
  1177. }
  1178. /*
  1179. ================
  1180. idThread::Event_VecNormalize
  1181. ================
  1182. */
  1183. void idThread::Event_VecNormalize( idVec3 &vec ) {
  1184. idVec3 n;
  1185. n = vec;
  1186. n.Normalize();
  1187. ReturnVector( n );
  1188. }
  1189. /*
  1190. ================
  1191. idThread::Event_VecLength
  1192. ================
  1193. */
  1194. void idThread::Event_VecLength( idVec3 &vec ) {
  1195. ReturnFloat( vec.Length() );
  1196. }
  1197. /*
  1198. ================
  1199. idThread::Event_VecDotProduct
  1200. ================
  1201. */
  1202. void idThread::Event_VecDotProduct( idVec3 &vec1, idVec3 &vec2 ) {
  1203. ReturnFloat( vec1 * vec2 );
  1204. }
  1205. /*
  1206. ================
  1207. idThread::Event_VecCrossProduct
  1208. ================
  1209. */
  1210. void idThread::Event_VecCrossProduct( idVec3 &vec1, idVec3 &vec2 ) {
  1211. ReturnVector( vec1.Cross( vec2 ) );
  1212. }
  1213. /*
  1214. ================
  1215. idThread::Event_VecToAngles
  1216. ================
  1217. */
  1218. void idThread::Event_VecToAngles( idVec3 &vec ) {
  1219. idAngles ang = vec.ToAngles();
  1220. ReturnVector( idVec3( ang[0], ang[1], ang[2] ) );
  1221. }
  1222. #ifdef _D3XP
  1223. /*
  1224. ================
  1225. idThread::Event_VecToOrthoBasisAngles
  1226. ================
  1227. */
  1228. void idThread::Event_VecToOrthoBasisAngles( idVec3 &vec ) {
  1229. idVec3 left, up;
  1230. idAngles ang;
  1231. vec.OrthogonalBasis( left, up );
  1232. idMat3 axis( left, up, vec );
  1233. ang = axis.ToAngles();
  1234. ReturnVector( idVec3( ang[0], ang[1], ang[2] ) );
  1235. }
  1236. void idThread::Event_RotateVector( idVec3 &vec, idVec3 &ang ) {
  1237. idAngles tempAng(ang);
  1238. idMat3 axis = tempAng.ToMat3();
  1239. idVec3 ret = vec * axis;
  1240. ReturnVector(ret);
  1241. }
  1242. #endif
  1243. /*
  1244. ================
  1245. idThread::Event_OnSignal
  1246. ================
  1247. */
  1248. void idThread::Event_OnSignal( int signal, idEntity *ent, const char *func ) {
  1249. const function_t *function;
  1250. assert( func );
  1251. if ( !ent ) {
  1252. Error( "Entity not found" );
  1253. }
  1254. if ( ( signal < 0 ) || ( signal >= NUM_SIGNALS ) ) {
  1255. Error( "Signal out of range" );
  1256. }
  1257. function = gameLocal.program.FindFunction( func );
  1258. if ( !function ) {
  1259. Error( "Function '%s' not found", func );
  1260. }
  1261. ent->SetSignal( ( signalNum_t )signal, this, function );
  1262. }
  1263. /*
  1264. ================
  1265. idThread::Event_ClearSignalThread
  1266. ================
  1267. */
  1268. void idThread::Event_ClearSignalThread( int signal, idEntity *ent ) {
  1269. if ( !ent ) {
  1270. Error( "Entity not found" );
  1271. }
  1272. if ( ( signal < 0 ) || ( signal >= NUM_SIGNALS ) ) {
  1273. Error( "Signal out of range" );
  1274. }
  1275. ent->ClearSignalThread( ( signalNum_t )signal, this );
  1276. }
  1277. /*
  1278. ================
  1279. idThread::Event_SetCamera
  1280. ================
  1281. */
  1282. void idThread::Event_SetCamera( idEntity *ent ) {
  1283. if ( !ent ) {
  1284. Error( "Entity not found" );
  1285. return;
  1286. }
  1287. if ( !ent->IsType( idCamera::Type ) ) {
  1288. Error( "Entity is not a camera" );
  1289. return;
  1290. }
  1291. gameLocal.SetCamera( ( idCamera * )ent );
  1292. }
  1293. /*
  1294. ================
  1295. idThread::Event_FirstPerson
  1296. ================
  1297. */
  1298. void idThread::Event_FirstPerson( void ) {
  1299. gameLocal.SetCamera( NULL );
  1300. }
  1301. /*
  1302. ================
  1303. idThread::Event_Trace
  1304. ================
  1305. */
  1306. void idThread::Event_Trace( const idVec3 &start, const idVec3 &end, const idVec3 &mins, const idVec3 &maxs, int contents_mask, idEntity *passEntity ) {
  1307. if ( mins == vec3_origin && maxs == vec3_origin ) {
  1308. gameLocal.clip.TracePoint( trace, start, end, contents_mask, passEntity );
  1309. } else {
  1310. gameLocal.clip.TraceBounds( trace, start, end, idBounds( mins, maxs ), contents_mask, passEntity );
  1311. }
  1312. ReturnFloat( trace.fraction );
  1313. }
  1314. /*
  1315. ================
  1316. idThread::Event_TracePoint
  1317. ================
  1318. */
  1319. void idThread::Event_TracePoint( const idVec3 &start, const idVec3 &end, int contents_mask, idEntity *passEntity ) {
  1320. gameLocal.clip.TracePoint( trace, start, end, contents_mask, passEntity );
  1321. ReturnFloat( trace.fraction );
  1322. }
  1323. /*
  1324. ================
  1325. idThread::Event_GetTraceFraction
  1326. ================
  1327. */
  1328. void idThread::Event_GetTraceFraction( void ) {
  1329. ReturnFloat( trace.fraction );
  1330. }
  1331. /*
  1332. ================
  1333. idThread::Event_GetTraceEndPos
  1334. ================
  1335. */
  1336. void idThread::Event_GetTraceEndPos( void ) {
  1337. ReturnVector( trace.endpos );
  1338. }
  1339. /*
  1340. ================
  1341. idThread::Event_GetTraceNormal
  1342. ================
  1343. */
  1344. void idThread::Event_GetTraceNormal( void ) {
  1345. if ( trace.fraction < 1.0f ) {
  1346. ReturnVector( trace.c.normal );
  1347. } else {
  1348. ReturnVector( vec3_origin );
  1349. }
  1350. }
  1351. /*
  1352. ================
  1353. idThread::Event_GetTraceEntity
  1354. ================
  1355. */
  1356. void idThread::Event_GetTraceEntity( void ) {
  1357. if ( trace.fraction < 1.0f ) {
  1358. ReturnEntity( gameLocal.entities[ trace.c.entityNum ] );
  1359. } else {
  1360. ReturnEntity( ( idEntity * )NULL );
  1361. }
  1362. }
  1363. /*
  1364. ================
  1365. idThread::Event_GetTraceJoint
  1366. ================
  1367. */
  1368. void idThread::Event_GetTraceJoint( void ) {
  1369. if ( trace.fraction < 1.0f && trace.c.id < 0 ) {
  1370. idAFEntity_Base *af = static_cast<idAFEntity_Base *>( gameLocal.entities[ trace.c.entityNum ] );
  1371. if ( af && af->IsType( idAFEntity_Base::Type ) && af->IsActiveAF() ) {
  1372. ReturnString( af->GetAnimator()->GetJointName( CLIPMODEL_ID_TO_JOINT_HANDLE( trace.c.id ) ) );
  1373. return;
  1374. }
  1375. }
  1376. ReturnString( "" );
  1377. }
  1378. /*
  1379. ================
  1380. idThread::Event_GetTraceBody
  1381. ================
  1382. */
  1383. void idThread::Event_GetTraceBody( void ) {
  1384. if ( trace.fraction < 1.0f && trace.c.id < 0 ) {
  1385. idAFEntity_Base *af = static_cast<idAFEntity_Base *>( gameLocal.entities[ trace.c.entityNum ] );
  1386. if ( af && af->IsType( idAFEntity_Base::Type ) && af->IsActiveAF() ) {
  1387. int bodyId = af->BodyForClipModelId( trace.c.id );
  1388. idAFBody *body = af->GetAFPhysics()->GetBody( bodyId );
  1389. if ( body ) {
  1390. ReturnString( body->GetName() );
  1391. return;
  1392. }
  1393. }
  1394. }
  1395. ReturnString( "" );
  1396. }
  1397. /*
  1398. ================
  1399. idThread::Event_FadeIn
  1400. ================
  1401. */
  1402. void idThread::Event_FadeIn( idVec3 &color, float time ) {
  1403. idVec4 fadeColor;
  1404. idPlayer *player;
  1405. player = gameLocal.GetLocalPlayer();
  1406. if ( player ) {
  1407. fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], 0.0f );
  1408. player->playerView.Fade(fadeColor, SEC2MS( time ) );
  1409. }
  1410. }
  1411. /*
  1412. ================
  1413. idThread::Event_FadeOut
  1414. ================
  1415. */
  1416. void idThread::Event_FadeOut( idVec3 &color, float time ) {
  1417. idVec4 fadeColor;
  1418. idPlayer *player;
  1419. player = gameLocal.GetLocalPlayer();
  1420. if ( player ) {
  1421. fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], 1.0f );
  1422. player->playerView.Fade(fadeColor, SEC2MS( time ) );
  1423. }
  1424. }
  1425. /*
  1426. ================
  1427. idThread::Event_FadeTo
  1428. ================
  1429. */
  1430. void idThread::Event_FadeTo( idVec3 &color, float alpha, float time ) {
  1431. idVec4 fadeColor;
  1432. idPlayer *player;
  1433. player = gameLocal.GetLocalPlayer();
  1434. if ( player ) {
  1435. fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], alpha );
  1436. player->playerView.Fade(fadeColor, SEC2MS( time ) );
  1437. }
  1438. }
  1439. /*
  1440. ================
  1441. idThread::Event_SetShaderParm
  1442. ================
  1443. */
  1444. void idThread::Event_SetShaderParm( int parmnum, float value ) {
  1445. if ( ( parmnum < 0 ) || ( parmnum >= MAX_GLOBAL_SHADER_PARMS ) ) {
  1446. Error( "shader parm index (%d) out of range", parmnum );
  1447. }
  1448. gameLocal.globalShaderParms[ parmnum ] = value;
  1449. }
  1450. /*
  1451. ================
  1452. idThread::Event_StartMusic
  1453. ================
  1454. */
  1455. void idThread::Event_StartMusic( const char *text ) {
  1456. gameSoundWorld->PlayShaderDirectly( text );
  1457. }
  1458. /*
  1459. ================
  1460. idThread::Event_Warning
  1461. ================
  1462. */
  1463. void idThread::Event_Warning( const char *text ) {
  1464. Warning( "%s", text );
  1465. }
  1466. /*
  1467. ================
  1468. idThread::Event_Error
  1469. ================
  1470. */
  1471. void idThread::Event_Error( const char *text ) {
  1472. Error( "%s", text );
  1473. }
  1474. /*
  1475. ================
  1476. idThread::Event_StrLen
  1477. ================
  1478. */
  1479. void idThread::Event_StrLen( const char *string ) {
  1480. int len;
  1481. len = strlen( string );
  1482. idThread::ReturnInt( len );
  1483. }
  1484. /*
  1485. ================
  1486. idThread::Event_StrLeft
  1487. ================
  1488. */
  1489. void idThread::Event_StrLeft( const char *string, int num ) {
  1490. int len;
  1491. if ( num < 0 ) {
  1492. idThread::ReturnString( "" );
  1493. return;
  1494. }
  1495. len = strlen( string );
  1496. if ( len < num ) {
  1497. idThread::ReturnString( string );
  1498. return;
  1499. }
  1500. idStr result( string, 0, num );
  1501. idThread::ReturnString( result );
  1502. }
  1503. /*
  1504. ================
  1505. idThread::Event_StrRight
  1506. ================
  1507. */
  1508. void idThread::Event_StrRight( const char *string, int num ) {
  1509. int len;
  1510. if ( num < 0 ) {
  1511. idThread::ReturnString( "" );
  1512. return;
  1513. }
  1514. len = strlen( string );
  1515. if ( len < num ) {
  1516. idThread::ReturnString( string );
  1517. return;
  1518. }
  1519. idThread::ReturnString( string + len - num );
  1520. }
  1521. /*
  1522. ================
  1523. idThread::Event_StrSkip
  1524. ================
  1525. */
  1526. void idThread::Event_StrSkip( const char *string, int num ) {
  1527. int len;
  1528. if ( num < 0 ) {
  1529. idThread::ReturnString( string );
  1530. return;
  1531. }
  1532. len = strlen( string );
  1533. if ( len < num ) {
  1534. idThread::ReturnString( "" );
  1535. return;
  1536. }
  1537. idThread::ReturnString( string + num );
  1538. }
  1539. /*
  1540. ================
  1541. idThread::Event_StrMid
  1542. ================
  1543. */
  1544. void idThread::Event_StrMid( const char *string, int start, int num ) {
  1545. int len;
  1546. if ( num < 0 ) {
  1547. idThread::ReturnString( "" );
  1548. return;
  1549. }
  1550. if ( start < 0 ) {
  1551. start = 0;
  1552. }
  1553. len = strlen( string );
  1554. if ( start > len ) {
  1555. start = len;
  1556. }
  1557. if ( start + num > len ) {
  1558. num = len - start;
  1559. }
  1560. idStr result( string, start, start + num );
  1561. idThread::ReturnString( result );
  1562. }
  1563. /*
  1564. ================
  1565. idThread::Event_StrToFloat( const char *string )
  1566. ================
  1567. */
  1568. void idThread::Event_StrToFloat( const char *string ) {
  1569. float result;
  1570. result = atof( string );
  1571. idThread::ReturnFloat( result );
  1572. }
  1573. /*
  1574. ================
  1575. idThread::Event_RadiusDamage
  1576. ================
  1577. */
  1578. void idThread::Event_RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignore, const char *damageDefName, float dmgPower ) {
  1579. gameLocal.RadiusDamage( origin, inflictor, attacker, ignore, ignore, damageDefName, dmgPower );
  1580. }
  1581. /*
  1582. ================
  1583. idThread::Event_IsClient
  1584. ================
  1585. */
  1586. void idThread::Event_IsClient( void ) {
  1587. idThread::ReturnFloat( gameLocal.isClient );
  1588. }
  1589. /*
  1590. ================
  1591. idThread::Event_IsMultiplayer
  1592. ================
  1593. */
  1594. void idThread::Event_IsMultiplayer( void ) {
  1595. idThread::ReturnFloat( gameLocal.isMultiplayer );
  1596. }
  1597. /*
  1598. ================
  1599. idThread::Event_GetFrameTime
  1600. ================
  1601. */
  1602. void idThread::Event_GetFrameTime( void ) {
  1603. idThread::ReturnFloat( MS2SEC( gameLocal.msec ) );
  1604. }
  1605. /*
  1606. ================
  1607. idThread::Event_GetTicsPerSecond
  1608. ================
  1609. */
  1610. void idThread::Event_GetTicsPerSecond( void ) {
  1611. idThread::ReturnFloat( USERCMD_HZ );
  1612. }
  1613. /*
  1614. ================
  1615. idThread::Event_CacheSoundShader
  1616. ================
  1617. */
  1618. void idThread::Event_CacheSoundShader( const char *soundName ) {
  1619. declManager->FindSound( soundName );
  1620. }
  1621. /*
  1622. ================
  1623. idThread::Event_DebugLine
  1624. ================
  1625. */
  1626. void idThread::Event_DebugLine( const idVec3 &color, const idVec3 &start, const idVec3 &end, const float lifetime ) {
  1627. gameRenderWorld->DebugLine( idVec4( color.x, color.y, color.z, 0.0f ), start, end, SEC2MS( lifetime ) );
  1628. }
  1629. /*
  1630. ================
  1631. idThread::Event_DebugArrow
  1632. ================
  1633. */
  1634. void idThread::Event_DebugArrow( const idVec3 &color, const idVec3 &start, const idVec3 &end, const int size, const float lifetime ) {
  1635. gameRenderWorld->DebugArrow( idVec4( color.x, color.y, color.z, 0.0f ), start, end, size, SEC2MS( lifetime ) );
  1636. }
  1637. /*
  1638. ================
  1639. idThread::Event_DebugCircle
  1640. ================
  1641. */
  1642. void idThread::Event_DebugCircle( const idVec3 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const float lifetime ) {
  1643. gameRenderWorld->DebugCircle( idVec4( color.x, color.y, color.z, 0.0f ), origin, dir, radius, numSteps, SEC2MS( lifetime ) );
  1644. }
  1645. /*
  1646. ================
  1647. idThread::Event_DebugBounds
  1648. ================
  1649. */
  1650. void idThread::Event_DebugBounds( const idVec3 &color, const idVec3 &mins, const idVec3 &maxs, const float lifetime ) {
  1651. gameRenderWorld->DebugBounds( idVec4( color.x, color.y, color.z, 0.0f ), idBounds( mins, maxs ), vec3_origin, SEC2MS( lifetime ) );
  1652. }
  1653. /*
  1654. ================
  1655. idThread::Event_DrawText
  1656. ================
  1657. */
  1658. void idThread::Event_DrawText( const char *text, const idVec3 &origin, float scale, const idVec3 &color, const int align, const float lifetime ) {
  1659. gameRenderWorld->DrawText( text, origin, scale, idVec4( color.x, color.y, color.z, 0.0f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), align, SEC2MS( lifetime ) );
  1660. }
  1661. /*
  1662. ================
  1663. idThread::Event_InfluenceActive
  1664. ================
  1665. */
  1666. void idThread::Event_InfluenceActive( void ) {
  1667. idPlayer *player;
  1668. player = gameLocal.GetLocalPlayer();
  1669. if ( player && player->GetInfluenceLevel() ) {
  1670. idThread::ReturnInt( true );
  1671. } else {
  1672. idThread::ReturnInt( false );
  1673. }
  1674. }