camturret.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #include "../idlib/precompiled.h"
  2. #pragma hdrstop
  3. #include "Game_local.h"
  4. #define SEARCHTIME 5000 //search for x millisecs
  5. #define SUSPICOUSTIME 400 //must see player for this much millisecs
  6. #define ALERTSTARETIME 5000
  7. #define SEARCHINTERVAL 300 //check for new player every x millisecs
  8. const idEventDef EV_camturretactivate( "camturretactivate", "d" );
  9. CLASS_DECLARATION( idAnimatedEntity, idCamturret )
  10. EVENT( EV_camturretactivate, idCamturret::Event_camturretactivate)
  11. END_CLASS
  12. void idCamturret::GotoAlert( void )
  13. {
  14. SetSkin(declManager->FindSkin( "skins/camturret/blink" ));
  15. Event_PlayAnim("alertspin", true);
  16. state = ALERTED;
  17. }
  18. void idCamturret::Event_camturretactivate( int value )
  19. {
  20. if (value >= 1)
  21. {
  22. if (state == ALERTED || state == SUSPICIOUS)
  23. {
  24. return;
  25. }
  26. SetSkin(declManager->FindSkin( "skins/camturret/skin" ));
  27. if (state == SEARCHING)
  28. {
  29. //reset the search time.
  30. nextStateTime = gameLocal.time + SEARCHTIME; //how long to search.
  31. return;
  32. }
  33. //if alarm is hit while it's unfolding, then the camera instantly unfolds.
  34. if (state == OPENING)
  35. {
  36. Event_PlayAnim("opened");
  37. nextStateTime = gameLocal.time + 100;
  38. return;
  39. }
  40. SetSkin(declManager->FindSkin( "skins/camturret/searching" ));
  41. StartSound( "snd_deploy", SND_CHANNEL_ANY, 0, false, NULL );
  42. int animDoneTime = Event_PlayAnim("opening");
  43. state = OPENING;
  44. nextStateTime = animDoneTime; //unfold animation time.
  45. }
  46. else
  47. {
  48. SetSkin(declManager->FindSkin( "skins/camturret/skin" ));
  49. StartSound( "snd_close", SND_CHANNEL_ANY, 0, false, NULL );
  50. Event_PlayAnim("closing");
  51. state = OFF;
  52. }
  53. }
  54. void idCamturret::Spawn( void )
  55. {
  56. nextSearchTime = 0;
  57. nextStateTime = 0;
  58. state = OFF;
  59. SetSkin(declManager->FindSkin( "skins/camturret/skin" ));
  60. BecomeActive( TH_THINK );
  61. }
  62. bool idCamturret::HasLOS()
  63. {
  64. idVec3 playerPos, turretPos, up;
  65. trace_t tr;
  66. this->GetPhysics()->GetAxis().ToAngles().ToVectors(NULL, NULL, &up);
  67. playerPos = gameLocal.GetLocalPlayer()->GetEyePosition();
  68. turretPos = this->GetPhysics()->GetOrigin() + (up * -12);
  69. gameLocal.clip.TracePoint( tr, turretPos, playerPos, CONTENTS_OPAQUE, this );
  70. if (tr.fraction >= 1)
  71. {
  72. return true;
  73. }
  74. return false;
  75. }
  76. void idCamturret::PointCamera( const char* jointName, idVec3 aimPos)
  77. {
  78. jointHandle_t beamJoint;
  79. idMat3 beamAngle;
  80. idVec3 beamPos;
  81. idVec3 dirToPlayer;
  82. idAngles tempAng;
  83. beamJoint = this->GetAnimator()->GetJointHandle( jointName );
  84. animator.GetJointTransform( beamJoint, gameLocal.time, beamPos, beamAngle);
  85. beamPos = this->GetPhysics()->GetOrigin() + beamPos * this->GetPhysics()->GetAxis();
  86. dirToPlayer = aimPos - beamPos;
  87. //dirToPlayer.Normalize();
  88. tempAng = dirToPlayer.ToAngles();
  89. tempAng.yaw += 180;
  90. animator.SetJointAxis( beamJoint, JOINTMOD_WORLD, tempAng.ToMat3() );
  91. }
  92. void idCamturret::Think( void )
  93. {
  94. if (state == OPENING)
  95. {
  96. if (gameLocal.time > nextStateTime)
  97. {
  98. Event_PlayAnim("searching");
  99. nextStateTime = gameLocal.time + SEARCHTIME; //how long to search.
  100. state = SEARCHING;
  101. }
  102. }
  103. else if (state == ALERTED)
  104. {
  105. idVec3 playerPos = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() + idVec3(0,0, -40);
  106. PointCamera("cam0", playerPos );
  107. PointCamera("cam1", playerPos );
  108. PointCamera("cam2", playerPos );
  109. //stays in alert mode forever, until the killcode is plugged in.
  110. }
  111. else if (state == SUSPICIOUS)
  112. {
  113. if (gameLocal.time > nextStateTime)
  114. {
  115. if (HasLOS())
  116. {
  117. //make all cameras go on alert.
  118. int i;
  119. for ( i = 0; i < gameLocal.num_entities; i++ )
  120. {
  121. if ( !gameLocal.entities[ i ] )
  122. continue;
  123. if (gameLocal.entities[i]->IsType(idCamturret::Type))
  124. {
  125. static_cast<idCamturret *>( gameLocal.entities[i] )->GotoAlert();
  126. }
  127. }
  128. ActivateTargets(this);
  129. }
  130. else
  131. {
  132. Event_PlayAnim("searching");
  133. nextStateTime = gameLocal.time + SEARCHTIME; //how long to search.
  134. state = SEARCHING;
  135. }
  136. }
  137. }
  138. else if (state == SEARCHING)
  139. {
  140. //search for LOS to player.
  141. if (gameLocal.time > nextSearchTime)
  142. {
  143. nextSearchTime = gameLocal.time + SEARCHINTERVAL;
  144. if (HasLOS())
  145. {
  146. idVec3 playerPos = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() + idVec3(0,0, -40);
  147. state = SUSPICIOUS;
  148. nextStateTime = gameLocal.time + SUSPICOUSTIME;
  149. StartSound( "snd_suspicious", SND_CHANNEL_ANY, 0, false, NULL );
  150. Event_PlayAnim("opened");
  151. PointCamera("cam0", playerPos );
  152. PointCamera("cam1", playerPos );
  153. PointCamera("cam2", playerPos );
  154. }
  155. }
  156. else if (gameLocal.time > nextStateTime)
  157. {
  158. //give up search.
  159. idStr timeouttarget = spawnArgs.GetString( "timeouttarget", "" );
  160. if ( timeouttarget.Length() )
  161. {
  162. idEntity *ent;
  163. ent = gameLocal.FindEntity( timeouttarget );
  164. if ( ent->RespondsTo( EV_Activate ) || ent->HasSignal( SIG_TRIGGER ) )
  165. {
  166. ent->Signal( SIG_TRIGGER );
  167. ent->ProcessEvent( &EV_Activate, this );
  168. }
  169. }
  170. Event_camturretactivate( 0 );
  171. }
  172. }
  173. idAnimatedEntity::Think();
  174. idAnimatedEntity::Present();
  175. }
  176. int idCamturret::Event_PlayAnim( const char* animname, bool loop)
  177. {
  178. int anim;
  179. int channel = 0;
  180. int animBlendFrames = 4;
  181. int animDoneTime = 0;
  182. anim = animator.GetAnim( animname );
  183. if ( !anim )
  184. {
  185. gameLocal.Warning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() );
  186. animator.Clear( channel, gameLocal.time, FRAME2MS( animBlendFrames ) );
  187. animDoneTime = 0;
  188. }
  189. else
  190. {
  191. if (loop)
  192. {
  193. animator.CycleAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) );
  194. }
  195. else
  196. {
  197. animator.PlayAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) );
  198. }
  199. animDoneTime = animator.CurrentAnim( channel )->GetEndTime();
  200. }
  201. animBlendFrames = 0;
  202. return animDoneTime;
  203. }