home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2006 March / Gamestar_82_2006-03_dvd.iso / DVDStar / Editace / quake4_sdkv10.exe / source / game / Trigger.cpp < prev    next >
C/C++ Source or Header  |  2005-11-14  |  34KB  |  1,391 lines

  1.  
  2. #include "../idlib/precompiled.h"
  3. #pragma hdrstop
  4.  
  5. #include "Game_local.h"
  6. #include "ai/AI_Manager.h"
  7.  
  8. /*
  9. ===============================================================================
  10.  
  11.   idTrigger
  12.     
  13. ===============================================================================
  14. */
  15.  
  16. const idEventDef EV_Enable( "enable", NULL );
  17. const idEventDef EV_Disable( "disable", NULL );
  18.  
  19. CLASS_DECLARATION( idEntity, idTrigger )
  20.     EVENT( EV_Enable,    idTrigger::Event_Enable )
  21.     EVENT( EV_Disable,    idTrigger::Event_Disable )
  22. END_CLASS
  23.  
  24. /*
  25. ================
  26. idTrigger::DrawDebugInfo
  27. ================
  28. */
  29. void idTrigger::DrawDebugInfo( void ) {
  30.     idMat3        axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3();
  31.     idVec3        up = axis[ 2 ] * 5.0f;
  32.     idBounds    viewTextBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() );
  33.     idBounds    viewBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() );
  34.     idBounds    box( idVec3( -4.0f, -4.0f, -4.0f ), idVec3( 4.0f, 4.0f, 4.0f ) );
  35.     idEntity    *ent;
  36.     idEntity    *target;
  37.     int            i;
  38.     bool        show;
  39.     const function_t *func;
  40.  
  41.     viewTextBounds.ExpandSelf( 128.0f );
  42.     viewBounds.ExpandSelf( 512.0f );
  43.     for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
  44.         if ( ent->GetPhysics()->GetContents() & ( CONTENTS_TRIGGER | CONTENTS_FLASHLIGHT_TRIGGER ) ) {
  45.             show = viewBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() );
  46.             if ( !show ) {
  47.                 for( i = 0; i < ent->targets.Num(); i++ ) {
  48.                     target = ent->targets[ i ].GetEntity();
  49.                     if ( target && viewBounds.IntersectsBounds( target->GetPhysics()->GetAbsBounds() ) ) {
  50.                         show = true;
  51.                         break;
  52.                     }
  53.                 }
  54.             }
  55.  
  56.             if ( !show ) {
  57.                 continue;
  58.             }
  59.  
  60.             gameRenderWorld->DebugBounds( colorOrange, ent->GetPhysics()->GetAbsBounds() );
  61.             if ( viewTextBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ) ) {
  62.                 gameRenderWorld->DrawText( ent->name.c_str(), ent->GetPhysics()->GetAbsBounds().GetCenter(), 0.1f, colorWhite, axis, 1 );
  63.                 gameRenderWorld->DrawText( ent->GetEntityDefName(), ent->GetPhysics()->GetAbsBounds().GetCenter() + up, 0.1f, colorWhite, axis, 1 );
  64.                 if ( ent->IsType( idTrigger::Type ) ) {
  65.                     func = static_cast<idTrigger *>( ent )->GetScriptFunction();
  66.                 } else {
  67.                     func = NULL;
  68.                 }
  69.  
  70.                 if ( func ) {
  71.                     gameRenderWorld->DrawText( va( "call script '%s'", func->Name() ), ent->GetPhysics()->GetAbsBounds().GetCenter() - up, 0.1f, colorWhite, axis, 1 );
  72.                 }
  73.             }
  74.  
  75.             for( i = 0; i < ent->targets.Num(); i++ ) {
  76.                 target = ent->targets[ i ].GetEntity();
  77.                 if ( target ) {
  78.                     gameRenderWorld->DebugArrow( colorYellow, ent->GetPhysics()->GetAbsBounds().GetCenter(), target->GetPhysics()->GetOrigin(), 10, 0 );
  79.                     gameRenderWorld->DebugBounds( colorGreen, box, target->GetPhysics()->GetOrigin() );
  80.                     if ( viewTextBounds.IntersectsBounds( target->GetPhysics()->GetAbsBounds() ) ) {
  81.                         gameRenderWorld->DrawText( target->name.c_str(), target->GetPhysics()->GetAbsBounds().GetCenter(), 0.1f, colorWhite, axis, 1 );
  82.                     }
  83.                 }
  84.             }
  85.         }
  86.     }
  87. }
  88.  
  89. /*
  90. ================
  91. idTrigger::Enable
  92. ================
  93. */
  94. void idTrigger::Enable( void ) {
  95.     GetPhysics()->SetContents( CONTENTS_TRIGGER );
  96.     GetPhysics()->EnableClip();
  97. }
  98.  
  99. /*
  100. ================
  101. idTrigger::Disable
  102. ================
  103. */
  104. void idTrigger::Disable( void ) {
  105.     // we may be relinked if we're bound to another object, so clear the contents as well
  106.     GetPhysics()->SetContents( 0 );
  107.     GetPhysics()->DisableClip();
  108. }
  109.  
  110. /*
  111. ================
  112. idTrigger::CallScript
  113. ================
  114. */
  115. void idTrigger::CallScript( idEntity* scriptEntity ) {
  116. // RAVEN BEGIN
  117. // abahr
  118.     for( int ix = scriptFunctions.Num() - 1; ix >= 0; --ix ) {
  119.         scriptFunctions[ix].InsertEntity( scriptEntity, 0 );//We could pass both the activator and self if wanted
  120.         scriptFunctions[ix].CallFunc( &spawnArgs );
  121.         scriptFunctions[ix].RemoveIndex( 0 );
  122.     }
  123. // RAVEN END
  124.  
  125. }
  126.  
  127. /*
  128. ================
  129. idTrigger::GetScriptFunction
  130. ================
  131. */
  132. const function_t *idTrigger::GetScriptFunction( void ) const {
  133. // RAVEN BEGIN
  134. // abahr: 
  135.     return (scriptFunctions.Num()) ? scriptFunctions[0].GetFunc() : NULL;
  136. // RAVEN END
  137. }
  138.  
  139. /*
  140. ================
  141. idTrigger::Save
  142. ================
  143. */
  144. void idTrigger::Save( idSaveGame *savefile ) const {
  145. // RAVEN BEGIN
  146. // abahr
  147.     savefile->WriteInt( scriptFunctions.Num() );
  148.     for( int ix = scriptFunctions.Num() - 1; ix >= 0; --ix ) {
  149.         scriptFunctions[ix].Save( savefile );
  150.     }
  151. // RAVEN END
  152. }
  153.  
  154. /*
  155. ================
  156. idTrigger::Restore
  157. ================
  158. */
  159. void idTrigger::Restore( idRestoreGame *savefile ) {
  160. // RAVEN BEGIN
  161. // abahr
  162.     int numScripts = 0;
  163.     savefile->ReadInt( numScripts );
  164.     scriptFunctions.SetNum( numScripts );
  165.     for( int ix = scriptFunctions.Num() - 1; ix >= 0; --ix ) {
  166.         scriptFunctions[ix].Restore( savefile );
  167.     }
  168. // RAVEN END
  169. }
  170.  
  171. /*
  172. ================
  173. idTrigger::Event_Enable
  174. ================
  175. */
  176. void idTrigger::Event_Enable( void ) {
  177.     Enable();
  178. }
  179.  
  180. /*
  181. ================
  182. idTrigger::Event_Disable
  183. ================
  184. */
  185. void idTrigger::Event_Disable( void ) {
  186.     Disable();
  187. }
  188.  
  189. /*
  190. ================
  191. idTrigger::idTrigger
  192. ================
  193. */
  194. idTrigger::idTrigger() {
  195. // RAVEN BEGIN
  196. // abahr: scriptFunction init's itself
  197.     //scriptFunction = NULL;
  198. // RAVEN END
  199. }
  200.  
  201. /*
  202. ================
  203. idTrigger::Spawn
  204. ================
  205. */
  206. void idTrigger::Spawn( void ) {
  207.     GetPhysics()->SetContents( CONTENTS_TRIGGER );
  208.  
  209. // RAVEN BEGIN
  210. // abahr:
  211.     scriptFunctions.SetGranularity( 1 );
  212.     for( const idKeyValue* kv = spawnArgs.MatchPrefix("call"); kv; kv = spawnArgs.MatchPrefix("call", kv) ) {
  213.         if( !kv->GetValue() ) {
  214.             continue;
  215.         }
  216.  
  217.         rvScriptFuncUtility& utility = scriptFunctions.Alloc();
  218.         if( !utility.Init(kv->GetValue()) ) {
  219.             gameLocal.Warning( "Trigger '%s' at (%s) trying to call an unknown function.", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
  220.         }
  221.     }
  222. // RAVEN END
  223. }
  224.  
  225.  
  226. /*
  227. ===============================================================================
  228.  
  229.   idTrigger_Multi
  230.     
  231. ===============================================================================
  232. */
  233.  
  234. // RAVEN BEGIN
  235. // abahr: changed to 'E' to allow NULL entities
  236. const idEventDef EV_TriggerAction( "<triggerAction>", "E" );
  237. // RAVEN END
  238.  
  239. CLASS_DECLARATION( idTrigger, idTrigger_Multi )
  240.     EVENT( EV_Touch,            idTrigger_Multi::Event_Touch )
  241.     EVENT( EV_Activate,            idTrigger_Multi::Event_Trigger )
  242.     EVENT( EV_TriggerAction,    idTrigger_Multi::Event_TriggerAction )
  243.  
  244. // RAVEN BEGIN
  245. // kfuller: respond to earthquakes
  246.     EVENT( EV_Earthquake,        idTrigger_Multi::Event_EarthQuake )
  247. // RAVEN END
  248. END_CLASS
  249.  
  250.  
  251. /*
  252. ================
  253. idTrigger_Multi::idTrigger_Multi
  254. ================
  255. */
  256. idTrigger_Multi::idTrigger_Multi( void ) {
  257.     wait = 0.0f;
  258.     random = 0.0f;
  259.     delay = 0.0f;
  260.     random_delay = 0.0f;
  261.     nextTriggerTime = 0;
  262.     removeItem = 0;
  263.     touchClient = false;
  264.     touchOther = false;
  265.     touchVehicle = false;
  266.     triggerFirst = false;
  267.     triggerWithSelf = false;
  268. }
  269.  
  270. /*
  271. ================
  272. idTrigger_Multi::Save
  273. ================
  274. */
  275. void idTrigger_Multi::Save( idSaveGame *savefile ) const {
  276.     savefile->WriteFloat( wait );
  277.     savefile->WriteFloat( random );
  278.     savefile->WriteFloat( delay );
  279.     savefile->WriteFloat( random_delay );
  280.     savefile->WriteInt( nextTriggerTime );
  281.     savefile->WriteString( requires );
  282.     savefile->WriteInt( removeItem );
  283.     savefile->WriteBool( touchClient );
  284.     savefile->WriteBool( touchOther );
  285.     savefile->WriteBool( touchVehicle );
  286.     savefile->WriteBool( triggerFirst );
  287.     savefile->WriteBool( triggerWithSelf );
  288. }
  289.  
  290. /*
  291. ================
  292. idTrigger_Multi::Restore
  293. ================
  294. */
  295. void idTrigger_Multi::Restore( idRestoreGame *savefile ) {
  296.     savefile->ReadFloat( wait );
  297.     savefile->ReadFloat( random );
  298.     savefile->ReadFloat( delay );
  299.     savefile->ReadFloat( random_delay );
  300.     savefile->ReadInt( nextTriggerTime );
  301.     savefile->ReadString( requires );
  302.     savefile->ReadInt( removeItem );
  303.     savefile->ReadBool( touchClient );
  304.     savefile->ReadBool( touchOther );
  305.     savefile->ReadBool( touchVehicle );
  306.     savefile->ReadBool( triggerFirst );
  307.     savefile->ReadBool( triggerWithSelf );
  308. }
  309.  
  310. /*
  311. ================
  312. idTrigger_Multi::Spawn
  313.  
  314. "wait" : Seconds between triggerings, 0.5 default, -1 = one time only.
  315. "call" : Script function to call when triggered
  316. "random"    wait variance, default is 0
  317. Variable sized repeatable trigger.  Must be targeted at one or more entities.
  318. so, the basic time between firing is a random time between
  319. (wait - random) and (wait + random)
  320. ================
  321. */
  322. void idTrigger_Multi::Spawn( void ) {
  323.     spawnArgs.GetFloat( "wait", "0.5", wait );
  324.     spawnArgs.GetFloat( "random", "0", random );
  325.     spawnArgs.GetFloat( "delay", "0", delay );
  326.     spawnArgs.GetFloat( "random_delay", "0", random_delay );
  327.     
  328.     if ( random && ( random >= wait ) && ( wait >= 0 ) ) {
  329.         random = wait - 1;
  330.         gameLocal.Warning( "idTrigger_Multi '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
  331.     }
  332.  
  333.     if ( random_delay && ( random_delay >= delay ) && ( delay >= 0 ) ) {
  334.         random_delay = delay - 1;
  335.         gameLocal.Warning( "idTrigger_Multi '%s' at (%s) has random_delay >= delay", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
  336.     }
  337.  
  338.     spawnArgs.GetString( "requires", "", requires );
  339.     spawnArgs.GetInt( "removeItem", "0", removeItem );
  340.     spawnArgs.GetBool( "triggerFirst", "0", triggerFirst );
  341.     spawnArgs.GetBool( "triggerWithSelf", "0", triggerWithSelf );
  342.  
  343.     if ( spawnArgs.GetBool( "onlyVehicle" ) ) {
  344.         touchVehicle = true;
  345.     } else if ( spawnArgs.GetBool( "anyTouch" ) ) {
  346.         touchClient = true;
  347.         touchOther = true;
  348.     } else if ( spawnArgs.GetBool( "noTouch" ) ) {
  349.         touchClient = false;
  350.         touchOther = false;
  351.     } else if ( spawnArgs.GetBool( "noClient" ) ) {
  352.         touchClient = false;
  353.         touchOther = true;
  354.     } else {
  355.         touchClient = true;
  356.         touchOther = false;
  357.     }
  358.  
  359.     nextTriggerTime = 0;
  360.  
  361.     if ( spawnArgs.GetBool( "flashlight_trigger" ) ) {
  362.         GetPhysics()->SetContents( CONTENTS_FLASHLIGHT_TRIGGER );
  363.     } else if ( spawnArgs.GetBool( "projectile_trigger" ) ) {
  364.         GetPhysics()->SetContents( CONTENTS_TRIGGER | CONTENTS_PROJECTILE );
  365.     } else {
  366.         GetPhysics()->SetContents( CONTENTS_TRIGGER );
  367.     }
  368. }
  369.  
  370. /*
  371. ================
  372. idTrigger_Multi::CheckFacing
  373. ================
  374. */
  375. bool idTrigger_Multi::CheckFacing( idEntity *activator ) {
  376.     if ( spawnArgs.GetBool( "facing" ) ) {
  377.         if ( !activator->IsType( idPlayer::GetClassType() ) ) {
  378.             return true;
  379.         }
  380.         idPlayer *player = static_cast< idPlayer* >( activator );
  381.  
  382.         // Unfortunately, the angle key rotates the trigger entity also.  So I've added
  383.         //    an angleFacing key which is used instead when present, otherwise the code defaults
  384.         //    to the behaviour present prior to this change
  385.         idVec3 tFacing = GetPhysics()->GetAxis()[0];
  386.         if ( spawnArgs.FindKey( "angleFacing" )) {
  387.             idAngles angs(0,spawnArgs.GetFloat( "angleFacing", "0" ),0);
  388.             tFacing = angs.ToForward();
  389.         }
  390.         float dot = player->viewAngles.ToForward() * tFacing;
  391.  
  392.         float angle = RAD2DEG( idMath::ACos( dot ) );
  393.         if ( angle  > spawnArgs.GetFloat( "angleLimit", "30" ) ) {
  394.             return false;
  395.         }
  396.     }
  397.     return true;
  398. }
  399.  
  400.  
  401. /*
  402. ================
  403. idTrigger_Multi::TriggerAction
  404. ================
  405. */
  406. void idTrigger_Multi::TriggerAction( idEntity *activator ) {
  407. // RAVEN BEGIN
  408. // jdischler: added for Aweldon.  The trigger, when activated, will call the listed func with all attached targets, then return.
  409.     if ( spawnArgs.GetBool( "_callWithTargets", "0" )) 
  410.     {
  411.         idEntity *ent;
  412.         for( int i = 0; i < targets.Num(); i++ ) 
  413.         {
  414.             ent = targets[ i ].GetEntity();
  415.             if ( !ent ) 
  416.             {
  417.                 continue;
  418.             }
  419.             CallScript( ent );
  420.         }
  421.         return;
  422.     }
  423. // RAVEN END
  424.     ActivateTargets( triggerWithSelf ? this : activator );
  425.     CallScript( triggerWithSelf ? this : activator );
  426.  
  427.     if ( wait >= 0 ) {
  428.         nextTriggerTime = gameLocal.time + SEC2MS( wait + random * gameLocal.random.CRandomFloat() );
  429.     } else {
  430.         // we can't just remove (this) here, because this is a touch function
  431.         // called while looping through area links...
  432.         nextTriggerTime = gameLocal.time + 1;
  433.         PostEventMS( &EV_Remove, 0 );
  434.     }
  435. }
  436.  
  437. /*
  438. ================
  439. idTrigger_Multi::Event_TriggerAction
  440. ================
  441. */
  442. void idTrigger_Multi::Event_TriggerAction( idEntity *activator ) {
  443.     TriggerAction( activator );
  444. }
  445.  
  446. /*
  447. ================
  448. idTrigger_Multi::Event_Trigger
  449.  
  450. the trigger was just activated
  451. activated should be the entity that originated the activation sequence (ie. the original target)
  452. activator should be set to the activator so it can be held through a delay
  453. so wait for the delay time before firing
  454. ================
  455. */
  456. void idTrigger_Multi::Event_Trigger( idEntity *activator ) {
  457. // RAVEN BEGIN
  458. // bdube: moved trigger first 
  459.     if ( triggerFirst ) {
  460.         triggerFirst = false;
  461.         return;
  462.     }
  463.  
  464.     if ( nextTriggerTime > gameLocal.time ) {
  465.         // can't retrigger until the wait is over
  466.         return;
  467.     }
  468.  
  469.     // see if this trigger requires an item
  470.     if ( !gameLocal.RequirementMet( activator, requires, removeItem ) ) {
  471.         return;
  472.     }
  473.  
  474.     if ( !CheckFacing( activator ) ) {
  475.         return;
  476.     }
  477. // RAVEN END
  478.  
  479.     // don't allow it to trigger twice in a single frame
  480.     nextTriggerTime = gameLocal.time + 1;
  481.  
  482.     if ( delay > 0 ) {
  483.         // don't allow it to trigger again until our delay has passed
  484.         nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() );
  485.         PostEventSec( &EV_TriggerAction, delay, activator );
  486.     } else {
  487.         TriggerAction( activator );
  488.     }
  489. }
  490.  
  491. /*
  492. ================
  493. idTrigger_Multi::Event_Touch
  494. ================
  495. */
  496. void idTrigger_Multi::Event_Touch( idEntity *other, trace_t *trace ) {
  497.     if( triggerFirst ) {
  498.         return;
  499.     }
  500.  
  501. // RAVEN BEGIN
  502. // jdischler: vehicle only trigger
  503.     if ( touchVehicle ) {
  504.         if ( !other->IsType(rvVehicle::GetClassType()) ) {
  505.             return;
  506.         }
  507.     } else {
  508. // RAVEN BEGIN
  509. // jnewquist: Use accessor for static class type 
  510.         bool player = other->IsType( idPlayer::GetClassType() );
  511. // RAVEN END
  512.         if ( player ) {
  513.             if ( !touchClient ) {
  514.                 return;
  515.             }
  516.             if ( static_cast< idPlayer * >( other )->spectating ) {
  517.                 return;
  518.             }
  519.         } else if ( !touchOther ) {
  520.             return;
  521.         }
  522.     }
  523.  
  524.     if ( nextTriggerTime > gameLocal.time ) {
  525.         // can't retrigger until the wait is over
  526.         return;
  527.     }
  528.  
  529.     // see if this trigger requires an item
  530.     if ( !gameLocal.RequirementMet( other, requires, removeItem ) ) {
  531.         return;
  532.     }
  533.  
  534.     if ( !CheckFacing( other ) ) {
  535.         return;
  536.     }
  537.  
  538.     if ( spawnArgs.GetBool( "toggleTriggerFirst" ) ) {
  539.         triggerFirst = true;
  540.     }
  541.  
  542. // RAVEN BEGIN
  543. // rjohnson: added block
  544.     if ( developer.GetBool() && *spawnArgs.GetString ( "message" ) ) {
  545.         gameLocal.DPrintf ( "Trigger: %s\n", spawnArgs.GetString ( "message" ) );
  546.     }
  547. // RAVEN END
  548.  
  549.     nextTriggerTime = gameLocal.time + 1;
  550.     if ( delay > 0 ) {
  551.         // don't allow it to trigger again until our delay has passed
  552.         nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() );
  553.         PostEventSec( &EV_TriggerAction, delay, other );
  554.     } else {
  555.         TriggerAction( other );
  556.     }
  557. }
  558.  
  559. // RAVEN BEGIN
  560. // kfuller:
  561. void idTrigger_Multi::Event_EarthQuake(float requiresLOS)
  562. {
  563.     // does this entity even care about earthquakes?
  564.     float    quakeChance = 0;
  565.  
  566.     if (!spawnArgs.GetFloat("quakeChance", "0", quakeChance))
  567.     {
  568.         return;
  569.     }
  570.     if (rvRandom::flrand(0, 1.0f) > quakeChance)
  571.     {
  572.         // failed its activation roll
  573.         return;
  574.     }
  575.     if (requiresLOS)
  576.     {
  577.         // if the player doesn't have line of sight to this fx, don't do anything
  578.         trace_t        trace;
  579.         idPlayer    *player = gameLocal.GetLocalPlayer();
  580.         idVec3        viewOrigin;
  581.         idMat3        viewAxis;
  582.  
  583.         player->GetViewPos(viewOrigin, viewAxis);
  584. // RAVEN BEGIN
  585. // ddynerman: multiple clip worlds
  586.         gameLocal.TracePoint( this, trace, viewOrigin, GetPhysics()->GetOrigin(), MASK_OPAQUE, player );
  587. // RAVEN END
  588.         if (trace.fraction < 1.0f)
  589.         {
  590.             // something blocked LOS
  591.             return;
  592.         }
  593.     }
  594.     // activate this effect now
  595.     TriggerAction(gameLocal.entities[ENTITYNUM_WORLD]);
  596. }
  597.  
  598. // RAVEN END
  599.  
  600. /*
  601. ===============================================================================
  602.  
  603.   idTrigger_EntityName
  604.     
  605. ===============================================================================
  606. */
  607.  
  608. CLASS_DECLARATION( idTrigger, idTrigger_EntityName )
  609.     EVENT( EV_Touch,            idTrigger_EntityName::Event_Touch )
  610.     EVENT( EV_Activate,            idTrigger_EntityName::Event_Trigger )
  611.     EVENT( EV_TriggerAction,    idTrigger_EntityName::Event_TriggerAction )
  612. END_CLASS
  613.  
  614. /*
  615. ================
  616. idTrigger_EntityName::idTrigger_EntityName
  617. ================
  618. */
  619. idTrigger_EntityName::idTrigger_EntityName( void ) {
  620.     wait = 0.0f;
  621.     random = 0.0f;
  622.     delay = 0.0f;
  623.     random_delay = 0.0f;
  624.     nextTriggerTime = 0;
  625.     triggerFirst = false;
  626. }
  627.  
  628. /*
  629. ================
  630. idTrigger_EntityName::Save
  631. ================
  632. */
  633. void idTrigger_EntityName::Save( idSaveGame *savefile ) const {
  634.     savefile->WriteFloat( wait );
  635.     savefile->WriteFloat( random );
  636.     savefile->WriteFloat( delay );
  637.     savefile->WriteFloat( random_delay );
  638.     savefile->WriteInt( nextTriggerTime );
  639.     savefile->WriteBool( triggerFirst );
  640.     savefile->WriteString( entityName );    
  641. }
  642.  
  643. /*
  644. ================
  645. idTrigger_EntityName::Restore
  646. ================
  647. */
  648. void idTrigger_EntityName::Restore( idRestoreGame *savefile ) {
  649.     savefile->ReadFloat( wait );
  650.     savefile->ReadFloat( random );
  651.     savefile->ReadFloat( delay );
  652.     savefile->ReadFloat( random_delay );
  653.     savefile->ReadInt( nextTriggerTime );
  654.     savefile->ReadBool( triggerFirst );
  655.     savefile->ReadString( entityName );
  656. }
  657.  
  658. /*
  659. ================
  660. idTrigger_EntityName::Spawn
  661. ================
  662. */
  663. void idTrigger_EntityName::Spawn( void ) {
  664.     spawnArgs.GetFloat( "wait", "0.5", wait );
  665.     spawnArgs.GetFloat( "random", "0", random );
  666.     spawnArgs.GetFloat( "delay", "0", delay );
  667.     spawnArgs.GetFloat( "random_delay", "0", random_delay );
  668.     
  669.     if ( random && ( random >= wait ) && ( wait >= 0 ) ) {
  670.         random = wait - 1;
  671.         gameLocal.Warning( "idTrigger_EntityName '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
  672.     }
  673.  
  674.     if ( random_delay && ( random_delay >= delay ) && ( delay >= 0 ) ) {
  675.         random_delay = delay - 1;
  676.         gameLocal.Warning( "idTrigger_EntityName '%s' at (%s) has random_delay >= delay", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
  677.     }
  678.  
  679.     spawnArgs.GetBool( "triggerFirst", "0", triggerFirst );
  680.  
  681.     entityName = spawnArgs.GetString( "entityname" );
  682.     if ( !entityName.Length() ) {
  683.         gameLocal.Error( "idTrigger_EntityName '%s' at (%s) doesn't have 'entityname' key specified", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
  684.     }
  685.  
  686.     nextTriggerTime = 0;
  687.  
  688.     if ( !spawnArgs.GetBool( "noTouch" ) ) {
  689.         GetPhysics()->SetContents( CONTENTS_TRIGGER );
  690.     }
  691. }
  692.  
  693. /*
  694. ================
  695. idTrigger_EntityName::TriggerAction
  696. ================
  697. */
  698. void idTrigger_EntityName::TriggerAction( idEntity *activator ) {
  699. // RAVEN BEGIN
  700. // abahr: want same functionality as trigger_multi.  Need to move this code into these two function calls
  701.     idEntity* scriptEntity = spawnArgs.GetBool("triggerWithSelf") ? this : activator;
  702.     ActivateTargets( scriptEntity );
  703.     CallScript( scriptEntity );
  704. // RAVEN END
  705.  
  706.     if ( wait >= 0 ) {
  707.         nextTriggerTime = gameLocal.time + SEC2MS( wait + random * gameLocal.random.CRandomFloat() );
  708.     } else {
  709.         // we can't just remove (this) here, because this is a touch function
  710.         // called while looping through area links...
  711.         nextTriggerTime = gameLocal.time + 1;
  712.         PostEventMS( &EV_Remove, 0 );
  713.     }
  714. }
  715.  
  716. /*
  717. ================
  718. idTrigger_EntityName::Event_TriggerAction
  719. ================
  720. */
  721. void idTrigger_EntityName::Event_TriggerAction( idEntity *activator ) {
  722.     TriggerAction( activator );
  723. }
  724.  
  725. /*
  726. ================
  727. idTrigger_EntityName::Event_Trigger
  728.  
  729. the trigger was just activated
  730. activated should be the entity that originated the activation sequence (ie. the original target)
  731. activator should be set to the activator so it can be held through a delay
  732. so wait for the delay time before firing
  733. ================
  734. */
  735. void idTrigger_EntityName::Event_Trigger( idEntity *activator ) {
  736.     if ( nextTriggerTime > gameLocal.time ) {
  737.         // can't retrigger until the wait is over
  738.         return;
  739.     }
  740.  
  741. // RAVEN BEGIN
  742. // abahr: so we can exclude an entity by name
  743.     if( !activator ) {
  744.         return;
  745.     }
  746.  
  747.     if( spawnArgs.GetBool("excludeEntityName") && activator->name == entityName ) {
  748.         return;
  749.     }
  750.  
  751.     if( !spawnArgs.GetBool("excludeEntityName") && activator->name != entityName ) {
  752.         return;
  753.     }
  754. // RAVEN END
  755.  
  756.     if ( triggerFirst ) {
  757.         triggerFirst = false;
  758.         return;
  759.     }
  760.  
  761.     // don't allow it to trigger twice in a single frame
  762.     nextTriggerTime = gameLocal.time + 1;
  763.  
  764.     if ( delay > 0 ) {
  765.         // don't allow it to trigger again until our delay has passed
  766.         nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() );
  767.         PostEventSec( &EV_TriggerAction, delay, activator );
  768.     } else {
  769.         TriggerAction( activator );
  770.     }
  771. }
  772.  
  773. /*
  774. ================
  775. idTrigger_EntityName::Event_Touch
  776. ================
  777. */
  778. void idTrigger_EntityName::Event_Touch( idEntity *other, trace_t *trace ) {
  779.     if( triggerFirst ) {
  780.         return;
  781.     }
  782.  
  783.     if ( nextTriggerTime > gameLocal.time ) {
  784.         // can't retrigger until the wait is over
  785.         return;
  786.     }
  787.  
  788. // RAVEN BEGIN
  789. // abahr: so we can exclude an entity by name
  790.     if( !other ) {
  791.         return;
  792.     }
  793.  
  794.     if( spawnArgs.GetBool("excludeEntityName") && other->name == entityName ) {
  795.         return;
  796.     }
  797.  
  798.     if( !spawnArgs.GetBool("excludeEntityName") && other->name != entityName ) {
  799.         return;
  800.     }
  801. // RAVEN END
  802.  
  803.     nextTriggerTime = gameLocal.time + 1;
  804.     if ( delay > 0 ) {
  805.         // don't allow it to trigger again until our delay has passed
  806.         nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() );
  807.         PostEventSec( &EV_TriggerAction, delay, other );
  808.     } else {
  809.         TriggerAction( other );
  810.     }
  811. }
  812.  
  813. /*
  814. ===============================================================================
  815.  
  816.   idTrigger_Timer
  817.     
  818. ===============================================================================
  819. */
  820.  
  821. const idEventDef EV_Timer( "<timer>", NULL );
  822.  
  823. CLASS_DECLARATION( idTrigger, idTrigger_Timer )
  824.     EVENT( EV_Timer,        idTrigger_Timer::Event_Timer )
  825.     EVENT( EV_Activate,        idTrigger_Timer::Event_Use )
  826. END_CLASS
  827.  
  828. /*
  829. ================
  830. idTrigger_Timer::idTrigger_Timer
  831. ================
  832. */
  833. idTrigger_Timer::idTrigger_Timer( void ) {
  834.     random = 0.0f;
  835.     wait = 0.0f;
  836.     on = false;
  837.     delay = 0.0f;
  838. }
  839.  
  840. /*
  841. ================
  842. idTrigger_Timer::Save
  843. ================
  844. */
  845. void idTrigger_Timer::Save( idSaveGame *savefile ) const {
  846.     savefile->WriteFloat( random );
  847.     savefile->WriteFloat( wait );
  848.     savefile->WriteBool( on );
  849.     savefile->WriteFloat( delay );
  850.     savefile->WriteString( onName );
  851.     savefile->WriteString( offName );
  852. }
  853.  
  854. /*
  855. ================
  856. idTrigger_Timer::Restore
  857. ================
  858. */
  859. void idTrigger_Timer::Restore( idRestoreGame *savefile ) {
  860.     savefile->ReadFloat( random );
  861.     savefile->ReadFloat( wait );
  862.     savefile->ReadBool( on );
  863.     savefile->ReadFloat( delay );
  864.     savefile->ReadString( onName );
  865.     savefile->ReadString( offName );
  866. }
  867.  
  868. /*
  869. ================
  870. idTrigger_Timer::Spawn
  871.  
  872. Repeatedly fires its targets.
  873. Can be turned on or off by using.
  874. ================
  875. */
  876. void idTrigger_Timer::Spawn( void ) {
  877.     spawnArgs.GetFloat( "random", "1", random );
  878.     spawnArgs.GetFloat( "wait", "1", wait );
  879.     spawnArgs.GetBool( "start_on", "0", on );
  880.     spawnArgs.GetFloat( "delay", "0", delay );
  881.     onName = spawnArgs.GetString( "onName" );
  882.     offName = spawnArgs.GetString( "offName" );
  883.  
  884.     if ( random >= wait && wait >= 0 ) {
  885.         random = wait - 0.001;
  886.         gameLocal.Warning( "idTrigger_Timer '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
  887.     }
  888.  
  889.     if ( on ) {
  890.         PostEventSec( &EV_Timer, delay );
  891.     }
  892. }
  893.  
  894. /*
  895. ================
  896. idTrigger_Timer::Enable
  897. ================
  898. */
  899. void idTrigger_Timer::Enable( void ) {
  900.     // if off, turn it on
  901.     if ( !on ) {
  902.         on = true;
  903.         PostEventSec( &EV_Timer, delay );
  904.     }
  905. }
  906.  
  907. /*
  908. ================
  909. idTrigger_Timer::Disable
  910. ================
  911. */
  912. void idTrigger_Timer::Disable( void ) {
  913.     // if on, turn it off
  914.     if ( on ) {
  915.         on = false;
  916.         CancelEvents( &EV_Timer );
  917.     }
  918. }
  919.  
  920. /*
  921. ================
  922. idTrigger_Timer::Event_Timer
  923. ================
  924. */
  925. void idTrigger_Timer::Event_Timer( void ) {
  926.     ActivateTargets( this );
  927.  
  928.     // set time before next firing
  929.     if ( wait >= 0.0f ) {
  930.         PostEventSec( &EV_Timer, wait + gameLocal.random.CRandomFloat() * random );
  931.     }
  932. }
  933.  
  934. /*
  935. ================
  936. idTrigger_Timer::Event_Use
  937. ================
  938. */
  939. void idTrigger_Timer::Event_Use( idEntity *activator ) {
  940.     // if on, turn it off
  941.     if ( on ) {
  942.         if ( offName.Length() && offName.Icmp( activator->GetName() ) ) {
  943.             return;
  944.         }
  945.         on = false;
  946.         CancelEvents( &EV_Timer );
  947.     } else {
  948.         // turn it on
  949.         if ( onName.Length() && onName.Icmp( activator->GetName() ) ) {
  950.             return;
  951.         }
  952.         on = true;
  953.         PostEventSec( &EV_Timer, delay );
  954.     }
  955. }
  956.  
  957. /*
  958. ===============================================================================
  959.  
  960.   idTrigger_Count
  961.     
  962. ===============================================================================
  963. */
  964.  
  965. CLASS_DECLARATION( idTrigger, idTrigger_Count )
  966.     EVENT( EV_Activate,    idTrigger_Count::Event_Trigger )
  967.     EVENT( EV_TriggerAction,    idTrigger_Count::Event_TriggerAction )
  968. END_CLASS
  969.  
  970. /*
  971. ================
  972. idTrigger_Count::idTrigger_Count
  973. ================
  974. */
  975. idTrigger_Count::idTrigger_Count( void ) {
  976.     goal = 0;
  977.     count = 0;
  978.     delay = 0.0f;
  979. }
  980.  
  981. /*
  982. ================
  983. idTrigger_Count::Save
  984. ================
  985. */
  986. void idTrigger_Count::Save( idSaveGame *savefile ) const {
  987.     savefile->WriteInt( goal );
  988.     savefile->WriteInt( count );
  989.     savefile->WriteFloat( delay );
  990. }
  991.  
  992. /*
  993. ================
  994. idTrigger_Count::Restore
  995. ================
  996. */
  997. void idTrigger_Count::Restore( idRestoreGame *savefile ) {
  998.     savefile->ReadInt( goal );
  999.     savefile->ReadInt( count );
  1000.     savefile->ReadFloat( delay );
  1001. }
  1002.  
  1003. /*
  1004. ================
  1005. idTrigger_Count::Spawn
  1006. ================
  1007. */
  1008. void idTrigger_Count::Spawn( void ) {
  1009.     spawnArgs.GetInt( "count", "1", goal );
  1010.     spawnArgs.GetFloat( "delay", "0", delay );
  1011.     count = 0;
  1012. }
  1013.  
  1014. /*
  1015. ================
  1016. idTrigger_Count::Event_Trigger
  1017. ================
  1018. */
  1019. void idTrigger_Count::Event_Trigger( idEntity *activator ) {
  1020.     // goal of -1 means trigger has been exhausted
  1021.     if (goal >= 0) {
  1022.         count++;
  1023.         if ( count >= goal ) {
  1024.             if (spawnArgs.GetBool("repeat")) {
  1025.                 count = 0;
  1026.             } else {
  1027.                 goal = -1;
  1028.             }
  1029.             PostEventSec( &EV_TriggerAction, delay, activator );
  1030.         }
  1031.     }
  1032. }
  1033.  
  1034. /*
  1035. ================
  1036. idTrigger_Count::Event_TriggerAction
  1037. ================
  1038. */
  1039. void idTrigger_Count::Event_TriggerAction( idEntity *activator ) {
  1040.     ActivateTargets( activator );
  1041.     CallScript( activator );
  1042.     if ( goal == -1 ) {
  1043.         PostEventMS( &EV_Remove, 0 );
  1044.     }
  1045. }
  1046.  
  1047. /*
  1048. ===============================================================================
  1049.  
  1050.   idTrigger_Hurt
  1051.     
  1052. ===============================================================================
  1053. */
  1054.  
  1055. CLASS_DECLARATION( idTrigger, idTrigger_Hurt )
  1056.     EVENT( EV_Touch,        idTrigger_Hurt::Event_Touch )
  1057.     EVENT( EV_Activate,        idTrigger_Hurt::Event_Toggle )
  1058. END_CLASS
  1059.  
  1060. /*
  1061. ================
  1062. idTrigger_Hurt::idTrigger_Hurt
  1063. ================
  1064. */
  1065. idTrigger_Hurt::idTrigger_Hurt( void ) {
  1066.     on = false;
  1067.     delay = 0.0f;
  1068.     nextTime = 0;
  1069. }
  1070.  
  1071. /*
  1072. ================
  1073. idTrigger_Hurt::Save
  1074. ================
  1075. */
  1076. void idTrigger_Hurt::Save( idSaveGame *savefile ) const {
  1077.     savefile->WriteBool( on );
  1078.     savefile->WriteFloat( delay );
  1079.     savefile->WriteInt( nextTime );
  1080. // RAVEN BEGIN
  1081. // bdube: playeronly flag
  1082.     savefile->WriteBool ( playerOnly );
  1083. // RAVEN END    
  1084. }
  1085.  
  1086. /*
  1087. ================
  1088. idTrigger_Hurt::Restore
  1089. ================
  1090. */
  1091. void idTrigger_Hurt::Restore( idRestoreGame *savefile ) {
  1092.     savefile->ReadBool( on );
  1093.     savefile->ReadFloat( delay );
  1094.     savefile->ReadInt( nextTime );
  1095. // RAVEN BEGIN
  1096. // bdube: playeronly flag
  1097.     savefile->ReadBool( playerOnly );
  1098. // RAVEN END    
  1099. }
  1100.  
  1101. /*
  1102. ================
  1103. idTrigger_Hurt::Spawn
  1104.  
  1105.     Damages activator
  1106.     Can be turned on or off by using.
  1107. ================
  1108. */
  1109. void idTrigger_Hurt::Spawn( void ) {
  1110.     spawnArgs.GetBool( "on", "1", on );
  1111.     spawnArgs.GetFloat( "delay", "1.0", delay );
  1112.  
  1113. // RAVEN BEGIN
  1114. // kfuller: playeronly flag
  1115.     spawnArgs.GetBool( "playerOnly", "0", playerOnly );
  1116. // RAVEN END
  1117.  
  1118.     nextTime = gameLocal.time;
  1119.     Enable();
  1120. }
  1121.  
  1122. /*
  1123. ================
  1124. idTrigger_Hurt::Event_Touch
  1125. ================
  1126. */
  1127. void idTrigger_Hurt::Event_Touch( idEntity *other, trace_t *trace ) {
  1128.     const char *damage;
  1129.  
  1130. // RAVEN BEGIN
  1131. // kfuller: playeronly flag
  1132. // jnewquist: Use accessor for static class type 
  1133.     if ( playerOnly && !other->IsType( idPlayer::GetClassType() ) ) {
  1134.         return;
  1135.     }
  1136. // RAVEN END
  1137.  
  1138.     if ( on && other && gameLocal.time >= nextTime ) {
  1139.         damage = spawnArgs.GetString( "def_damage", "damage_painTrigger" );
  1140.         other->Damage( this, NULL, vec3_origin, damage, 1.0f, INVALID_JOINT );
  1141.  
  1142.         ActivateTargets( other );
  1143.         CallScript( other );
  1144.  
  1145.         nextTime = gameLocal.time + SEC2MS( delay );
  1146.     }
  1147. }
  1148.  
  1149. /*
  1150. ================
  1151. idTrigger_Hurt::Event_Toggle
  1152. ================
  1153. */
  1154. void idTrigger_Hurt::Event_Toggle( idEntity *activator ) {
  1155.     on = !on;
  1156. }
  1157.  
  1158.  
  1159. /*
  1160. ===============================================================================
  1161.  
  1162.   idTrigger_Fade
  1163.  
  1164. ===============================================================================
  1165. */
  1166.  
  1167. CLASS_DECLARATION( idTrigger, idTrigger_Fade )
  1168.     EVENT( EV_Activate,        idTrigger_Fade::Event_Trigger )
  1169. END_CLASS
  1170.  
  1171. /*
  1172. ================
  1173. idTrigger_Fade::Event_Trigger
  1174. ================
  1175. */
  1176. void idTrigger_Fade::Event_Trigger( idEntity *activator ) {
  1177.     idVec4        fadeColor;
  1178.     int            fadeTime;
  1179.     idPlayer    *player;
  1180.  
  1181.     player = gameLocal.GetLocalPlayer();
  1182.     if ( player ) {
  1183.         fadeColor = spawnArgs.GetVec4( "fadeColor", "0, 0, 0, 1" );
  1184.         fadeTime = SEC2MS( spawnArgs.GetFloat( "fadeTime", "0.5" ) );
  1185.         player->playerView.Fade( fadeColor, fadeTime );
  1186.         PostEventMS( &EV_ActivateTargets, fadeTime, activator );
  1187.     }
  1188. }
  1189.  
  1190. /*
  1191. ===============================================================================
  1192.  
  1193.   idTrigger_Touch
  1194.     
  1195. ===============================================================================
  1196. */
  1197.  
  1198. CLASS_DECLARATION( idTrigger, idTrigger_Touch )
  1199.     EVENT( EV_Activate,        idTrigger_Touch::Event_Trigger )
  1200. END_CLASS
  1201.  
  1202.  
  1203. /*
  1204. ================
  1205. idTrigger_Touch::idTrigger_Touch
  1206. ================
  1207. */
  1208. idTrigger_Touch::idTrigger_Touch( void ) {
  1209.     clipModel = NULL;
  1210. }
  1211.  
  1212. /*
  1213. ================
  1214. idTrigger_Touch::Spawn
  1215. ================
  1216. */
  1217. void idTrigger_Touch::Spawn( void ) {
  1218.     // get the clip model
  1219. // RAVEN BEGIN
  1220. // mwhitlock: Dynamic memory consolidation
  1221.     RV_PUSH_HEAP_MEM(this);
  1222. // RAVEN END
  1223.     clipModel = new idClipModel( GetPhysics()->GetClipModel() );
  1224. // RAVEN BEGIN
  1225. // mwhitlock: Dynamic memory consolidation
  1226.     RV_POP_HEAP();
  1227. // RAVEN END
  1228.     // remove the collision model from the physics object
  1229.     GetPhysics()->SetClipModel( NULL, 1.0f );
  1230.  
  1231.     if ( spawnArgs.GetBool( "start_on" ) ) {
  1232.         BecomeActive( TH_THINK );
  1233.     }
  1234.     filterTeam = -1;
  1235.     idStr filterTeamStr = spawnArgs.GetString( "filterTeam" );
  1236.     if ( filterTeamStr.Size() )
  1237.     {
  1238.         if ( !idStr::Icmp( "marine", filterTeamStr.c_str() ) )
  1239.         {
  1240.             filterTeam = AITEAM_MARINE;
  1241.         }
  1242.         else if ( !idStr::Icmp( "strogg", filterTeamStr.c_str() ) )
  1243.         {
  1244.             filterTeam = AITEAM_STROGG;
  1245.         }
  1246.     }
  1247. }
  1248.  
  1249. /*
  1250. ================
  1251. idTrigger_Touch::Save
  1252. ================
  1253. */
  1254. void idTrigger_Touch::Save( idSaveGame *savefile ) {
  1255.     savefile->WriteClipModel( clipModel );
  1256.     savefile->WriteInt( filterTeam );
  1257. }
  1258.  
  1259. /*
  1260. ================
  1261. idTrigger_Touch::Restore
  1262. ================
  1263. */
  1264. void idTrigger_Touch::Restore( idRestoreGame *savefile ) {
  1265.     savefile->ReadClipModel( clipModel );
  1266.     savefile->ReadInt( filterTeam );
  1267. }
  1268.  
  1269. /*
  1270. ================
  1271. idTrigger_Touch::TouchEntities
  1272. ================
  1273. */
  1274. void idTrigger_Touch::TouchEntities( void ) {
  1275.     int numClipModels, i;
  1276.     idBounds bounds;
  1277.     idClipModel *cm, *clipModelList[ MAX_GENTITIES ];
  1278.  
  1279. // RAVEN BEGIN
  1280. // abahr: now scriptFunction list
  1281.     if ( clipModel == NULL || !scriptFunctions.Num() ) {
  1282. // RAVEN END
  1283.         return;
  1284.     }
  1285.  
  1286.     bounds.FromTransformedBounds( clipModel->GetBounds(), GetBindMaster()!=NULL?GetPhysics()->GetOrigin():clipModel->GetOrigin(), GetBindMaster()!=NULL?GetPhysics()->GetAxis():clipModel->GetAxis() );
  1287. // RAVEN BEGIN
  1288. // MCG: filterTeam
  1289.     if ( filterTeam != -1 )
  1290.     {
  1291.         idActor* actor;
  1292.         // Iterate through the filter team
  1293.         for( actor = aiManager.GetAllyTeam ( (aiTeam_t)filterTeam ); actor; actor = actor->teamNode.Next() ) {
  1294.             // Skip hidden actors and actors that can't be targeted
  1295.             if( actor->fl.notarget || actor->fl.isDormant || ( actor->IsHidden ( ) && !actor->IsInVehicle() ) ) {
  1296.                 continue;
  1297.             }
  1298.             if ( !bounds.IntersectsBounds ( actor->GetPhysics()->GetAbsBounds ( ) ) ) {
  1299.                 continue;
  1300.             }
  1301.             cm = actor->GetPhysics()->GetClipModel();
  1302.             if ( !cm || !cm->IsTraceModel() ) {
  1303.                 continue;
  1304.             }
  1305.             if ( !gameLocal.ContentsModel( this, cm->GetOrigin(), cm, cm->GetAxis(), -1,
  1306.                 clipModel->GetCollisionModel(), GetBindMaster()!=NULL?GetPhysics()->GetOrigin():clipModel->GetOrigin(), GetBindMaster()!=NULL?GetPhysics()->GetAxis():clipModel->GetAxis() ) ) {
  1307.                 continue;
  1308.             }
  1309.             ActivateTargets( (idEntity*)actor );
  1310.  
  1311.             CallScript( (idEntity*)actor );
  1312.         }
  1313.         return;
  1314.     }
  1315. // ddynerman: multiple clip worlds
  1316.     numClipModels = gameLocal.ClipModelsTouchingBounds( this, bounds, -1, clipModelList, MAX_GENTITIES );
  1317. // RAVEN END
  1318.  
  1319.     for ( i = 0; i < numClipModels; i++ ) {
  1320.         cm = clipModelList[ i ];
  1321.  
  1322.         if ( !cm->IsTraceModel() ) {
  1323.             continue;
  1324.         }
  1325.  
  1326.         idEntity *entity = cm->GetEntity();
  1327.  
  1328.         if ( !entity ) {
  1329.             continue;
  1330.         }
  1331.         
  1332. // RAVEN BEGIN
  1333. // ddynerman: multiple clip worlds
  1334.         if ( !gameLocal.ContentsModel( this, cm->GetOrigin(), cm, cm->GetAxis(), -1,
  1335.                                     clipModel->GetCollisionModel(), clipModel->GetOrigin(), clipModel->GetAxis() ) ) {
  1336. // RAVEN END
  1337.             continue;
  1338.         }
  1339.  
  1340.         ActivateTargets( entity );
  1341.  
  1342. // RAVEN BEGIN
  1343. // abahr: changed to be compatible with new script function utility
  1344.         CallScript( entity );
  1345. // RAVEN END
  1346.     }
  1347. }
  1348.  
  1349. /*
  1350. ================
  1351. idTrigger_Touch::Think
  1352. ================
  1353. */
  1354. void idTrigger_Touch::Think( void ) {
  1355.     if ( thinkFlags & TH_THINK ) {
  1356.         TouchEntities();
  1357.     }
  1358.     idEntity::Think();
  1359. }
  1360.  
  1361. /*
  1362. ================
  1363. idTrigger_Touch::Event_Trigger
  1364. ================
  1365. */
  1366. void idTrigger_Touch::Event_Trigger( idEntity *activator ) {
  1367.     if ( thinkFlags & TH_THINK ) {
  1368.         BecomeInactive( TH_THINK );
  1369.     } else {
  1370.         BecomeActive( TH_THINK );
  1371.     }
  1372. }
  1373.  
  1374. /*
  1375. ================
  1376. idTrigger_Touch::Enable
  1377. ================
  1378. */
  1379. void idTrigger_Touch::Enable( void ) {
  1380.     BecomeActive( TH_THINK );
  1381. }
  1382.  
  1383. /*
  1384. ================
  1385. idTrigger_Touch::Disable
  1386. ================
  1387. */
  1388. void idTrigger_Touch::Disable( void ) {
  1389.     BecomeInactive( TH_THINK );
  1390. }
  1391.