Script_Thread.cpp 43 KB

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