Script_Thread.cpp 45 KB

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