Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

396 lines
13 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "cbase.h"
  7. #include "eventqueue.h"
  8. #include "script_intro.h"
  9. #include "point_camera.h"
  10. #include "ai_utils.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. // Used by server and client to calculate our FOV blend at any given frame
  14. extern float ScriptInfo_CalculateFOV( float flFOVBlendStartTime, float flNextFOVBlendTime, int nFOV, int nNextFOV, bool bSplineRamp );
  15. // Global point to the active intro script
  16. CHandle<CScriptIntro> g_hIntroScript;
  17. LINK_ENTITY_TO_CLASS(script_intro, CScriptIntro);
  18. BEGIN_DATADESC(CScriptIntro)
  19. // Keys
  20. DEFINE_FIELD( m_vecCameraView, FIELD_VECTOR ),
  21. DEFINE_FIELD( m_vecCameraViewAngles, FIELD_VECTOR ),
  22. DEFINE_FIELD( m_vecPlayerView, FIELD_VECTOR ),
  23. DEFINE_FIELD( m_vecPlayerViewAngles, FIELD_VECTOR ),
  24. DEFINE_FIELD( m_iBlendMode, FIELD_INTEGER ),
  25. DEFINE_FIELD( m_iQueuedBlendMode, FIELD_INTEGER ),
  26. DEFINE_FIELD( m_iQueuedNextBlendMode, FIELD_INTEGER ),
  27. DEFINE_FIELD( m_iNextBlendMode, FIELD_INTEGER ),
  28. DEFINE_FIELD( m_flNextBlendTime, FIELD_TIME ),
  29. DEFINE_FIELD( m_flBlendStartTime, FIELD_TIME ),
  30. DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ),
  31. DEFINE_FIELD( m_iNextFOV, FIELD_INTEGER ),
  32. DEFINE_FIELD( m_flNextFOVBlendTime, FIELD_TIME ),
  33. DEFINE_FIELD( m_flFOVBlendStartTime, FIELD_TIME ),
  34. DEFINE_FIELD( m_iFOV, FIELD_INTEGER ),
  35. DEFINE_ARRAY( m_flFadeColor, FIELD_FLOAT, 3 ),
  36. DEFINE_FIELD( m_flFadeAlpha, FIELD_FLOAT ),
  37. DEFINE_FIELD( m_flFadeDuration, FIELD_FLOAT ),
  38. DEFINE_FIELD( m_hCameraEntity, FIELD_EHANDLE ),
  39. DEFINE_FIELD( m_iStartFOV, FIELD_INTEGER ),
  40. DEFINE_KEYFIELD( m_bAlternateFOV, FIELD_BOOLEAN, "alternatefovchange" ),
  41. // Inputs
  42. DEFINE_INPUTFUNC(FIELD_STRING, "SetCameraViewEntity", InputSetCameraViewEntity ),
  43. DEFINE_INPUTFUNC(FIELD_INTEGER, "SetBlendMode", InputSetBlendMode ),
  44. DEFINE_INPUTFUNC(FIELD_INTEGER, "SetNextFOV", InputSetNextFOV ),
  45. DEFINE_INPUTFUNC(FIELD_FLOAT, "SetFOVBlendTime", InputSetFOVBlendTime ),
  46. DEFINE_INPUTFUNC(FIELD_INTEGER, "SetFOV", InputSetFOV ),
  47. DEFINE_INPUTFUNC(FIELD_INTEGER, "SetNextBlendMode", InputSetNextBlendMode ),
  48. DEFINE_INPUTFUNC(FIELD_FLOAT, "SetNextBlendTime", InputSetNextBlendTime ),
  49. DEFINE_INPUTFUNC(FIELD_VOID, "Activate", InputActivate ),
  50. DEFINE_INPUTFUNC(FIELD_VOID, "Deactivate", InputDeactivate ),
  51. DEFINE_INPUTFUNC(FIELD_STRING, "FadeTo", InputFadeTo ),
  52. DEFINE_INPUTFUNC(FIELD_STRING, "SetFadeColor", InputSetFadeColor ),
  53. DEFINE_THINKFUNC( BlendComplete ),
  54. END_DATADESC()
  55. IMPLEMENT_SERVERCLASS_ST( CScriptIntro, DT_ScriptIntro )
  56. SendPropVector(SENDINFO(m_vecCameraView), -1, SPROP_COORD),
  57. SendPropVector(SENDINFO(m_vecCameraViewAngles), -1, SPROP_COORD),
  58. SendPropInt( SENDINFO( m_iBlendMode ), 5 ),
  59. SendPropInt( SENDINFO( m_iNextBlendMode ), 5 ),
  60. SendPropFloat( SENDINFO( m_flNextBlendTime ), 10 ),
  61. SendPropFloat( SENDINFO( m_flBlendStartTime ), 10 ),
  62. SendPropBool( SENDINFO( m_bActive ) ),
  63. // Fov & fov blends
  64. SendPropInt( SENDINFO( m_iFOV ), 9 ),
  65. SendPropInt( SENDINFO( m_iNextFOV ), 9 ),
  66. SendPropInt( SENDINFO( m_iStartFOV ), 9 ),
  67. SendPropFloat( SENDINFO( m_flNextFOVBlendTime ), 10 ),
  68. SendPropFloat( SENDINFO( m_flFOVBlendStartTime ), 10 ),
  69. SendPropBool( SENDINFO( m_bAlternateFOV ) ),
  70. // Fades
  71. SendPropFloat( SENDINFO( m_flFadeAlpha ), 10 ),
  72. SendPropArray(
  73. SendPropFloat( SENDINFO_ARRAY(m_flFadeColor), 32, SPROP_NOSCALE),
  74. m_flFadeColor),
  75. SendPropFloat( SENDINFO( m_flFadeDuration ), 10, SPROP_ROUNDDOWN, 0.0f, 255.0 ),
  76. SendPropEHandle(SENDINFO( m_hCameraEntity ) ),
  77. END_SEND_TABLE()
  78. //-----------------------------------------------------------------------------
  79. // Purpose:
  80. //-----------------------------------------------------------------------------
  81. void CScriptIntro::Spawn( void )
  82. {
  83. m_iNextBlendMode = -1;
  84. m_iQueuedBlendMode = -1;
  85. m_iQueuedNextBlendMode = -1;
  86. AddSolidFlags( FSOLID_NOT_SOLID );
  87. SetSize( -Vector(5,5,5), Vector(5,5,5) );
  88. m_bActive = false;
  89. m_iNextFOV = 0;
  90. m_iFOV = 0;
  91. m_iStartFOV = 0;
  92. }
  93. //-----------------------------------------------------------------------------
  94. // Purpose:
  95. //-----------------------------------------------------------------------------
  96. void CScriptIntro::Activate( void )
  97. {
  98. // Restore our script pointer, this is necessary to trigger other internal logic to due with PVS checks
  99. if ( m_bActive )
  100. {
  101. g_hIntroScript = this;
  102. }
  103. BaseClass::Activate();
  104. }
  105. void CScriptIntro::Precache()
  106. {
  107. PrecacheMaterial( "scripted/intro_screenspaceeffect" );
  108. BaseClass::Precache();
  109. }
  110. //------------------------------------------------------------------------------
  111. // Purpose : Send even though we don't have a model.
  112. //------------------------------------------------------------------------------
  113. int CScriptIntro::UpdateTransmitState()
  114. {
  115. return SetTransmitState( FL_EDICT_ALWAYS );
  116. }
  117. //-----------------------------------------------------------------------------
  118. // Purpose:
  119. //-----------------------------------------------------------------------------
  120. void CScriptIntro::InputSetCameraViewEntity( inputdata_t &inputdata )
  121. {
  122. // Find the specified entity
  123. string_t iszEntityName = inputdata.value.StringID();
  124. if ( iszEntityName == NULL_STRING )
  125. return;
  126. CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, iszEntityName, NULL, inputdata.pActivator, inputdata.pCaller );
  127. if ( !pEntity )
  128. {
  129. Warning("script_intro %s couldn't find SetCameraViewEntity named %s\n", STRING(GetEntityName()), STRING(iszEntityName) );
  130. return;
  131. }
  132. m_hCameraEntity = pEntity;
  133. m_vecCameraView = pEntity->GetAbsOrigin();
  134. m_vecCameraViewAngles = pEntity->GetAbsAngles();
  135. }
  136. //-----------------------------------------------------------------------------
  137. // Purpose: Fill out the origin that should be included in the player's PVS
  138. //-----------------------------------------------------------------------------
  139. bool CScriptIntro::GetIncludedPVSOrigin( Vector *pOrigin, CBaseEntity **ppCamera )
  140. {
  141. if ( m_bActive && m_hCameraEntity.Get() )
  142. {
  143. *ppCamera = m_hCameraEntity.Get();
  144. *pOrigin = m_hCameraEntity.Get()->GetAbsOrigin();
  145. return true;
  146. }
  147. return false;
  148. }
  149. //-----------------------------------------------------------------------------
  150. // Used for debugging
  151. //-----------------------------------------------------------------------------
  152. static ConVar cl_spewscriptintro( "cl_spewscriptintro", "0" );
  153. //-----------------------------------------------------------------------------
  154. // Purpose:
  155. //-----------------------------------------------------------------------------
  156. void CScriptIntro::InputSetBlendMode( inputdata_t &inputdata )
  157. {
  158. m_iBlendMode = m_iNextBlendMode = inputdata.value.Int();
  159. m_flBlendStartTime = m_flNextBlendTime = gpGlobals->curtime;
  160. m_iQueuedBlendMode = -1;
  161. SetContextThink( NULL, gpGlobals->curtime, "BlendComplete" );
  162. if ( cl_spewscriptintro.GetInt() )
  163. {
  164. DevMsg( 1, "%.2f INPUT: Blend mode set to %d\n", gpGlobals->curtime, m_iBlendMode.Get() );
  165. }
  166. }
  167. //-----------------------------------------------------------------------------
  168. // Purpose:
  169. //-----------------------------------------------------------------------------
  170. void CScriptIntro::InputSetNextBlendMode( inputdata_t &inputdata )
  171. {
  172. m_iQueuedNextBlendMode = inputdata.value.Int();
  173. if ( cl_spewscriptintro.GetInt() )
  174. {
  175. DevMsg( 1, "%.2f INPUT: Next Blend mode set to %d\n", gpGlobals->curtime, m_iQueuedNextBlendMode );
  176. }
  177. }
  178. //-----------------------------------------------------------------------------
  179. // Purpose:
  180. // Input : &inputdata -
  181. //-----------------------------------------------------------------------------
  182. void CScriptIntro::InputSetNextFOV( inputdata_t &inputdata )
  183. {
  184. m_iNextFOV = inputdata.value.Int();
  185. }
  186. //------------------------------------------------------------------------
  187. // Purpose:
  188. // Input : &inputdata -
  189. //-----------------------------------------------------------------------------
  190. void CScriptIntro::InputSetFOVBlendTime( inputdata_t &inputdata )
  191. {
  192. // Cache our FOV starting point before we update our data here
  193. if ( m_flNextFOVBlendTime >= gpGlobals->curtime )
  194. {
  195. // We're already in a blend, so capture where we are at this point in time
  196. m_iStartFOV = ScriptInfo_CalculateFOV( m_flFOVBlendStartTime, m_flNextFOVBlendTime, m_iStartFOV, m_iNextFOV, m_bAlternateFOV );
  197. }
  198. else
  199. {
  200. // If we weren't blending, then we need to construct a proper starting point from scratch
  201. CBasePlayer *pPlayer = AI_GetSinglePlayer();
  202. if ( pPlayer )
  203. {
  204. m_iStartFOV = ( m_iFOV ) ? m_iFOV : pPlayer->GetFOV();
  205. }
  206. else
  207. {
  208. m_iStartFOV = m_iFOV;
  209. }
  210. }
  211. m_flNextFOVBlendTime = gpGlobals->curtime + inputdata.value.Float();
  212. m_flFOVBlendStartTime = gpGlobals->curtime;
  213. }
  214. //-----------------------------------------------------------------------------
  215. // Purpose:
  216. //-----------------------------------------------------------------------------
  217. void CScriptIntro::InputSetFOV( inputdata_t &inputdata )
  218. {
  219. m_iFOV = inputdata.value.Int();
  220. m_iStartFOV = m_iFOV;
  221. }
  222. //-----------------------------------------------------------------------------
  223. // Purpose:
  224. //-----------------------------------------------------------------------------
  225. void CScriptIntro::InputSetNextBlendTime( inputdata_t &inputdata )
  226. {
  227. m_flNextBlendTime = gpGlobals->curtime + inputdata.value.Float();
  228. m_flBlendStartTime = gpGlobals->curtime;
  229. // This logic is used to support continued calls to SetNextBlendMode
  230. // without intervening calls to SetBlendMode
  231. if ( m_iQueuedBlendMode >= 0 )
  232. {
  233. m_iBlendMode = m_iQueuedBlendMode;
  234. }
  235. if ( m_iQueuedNextBlendMode < 0 )
  236. {
  237. Warning( "script_intro: Warning!! Set blend time without setting next blend mode!\n" );
  238. m_iQueuedNextBlendMode = m_iBlendMode;
  239. }
  240. m_iNextBlendMode = m_iQueuedNextBlendMode;
  241. m_iQueuedNextBlendMode = -1;
  242. m_iQueuedBlendMode = m_iNextBlendMode;
  243. if ( cl_spewscriptintro.GetInt() )
  244. {
  245. DevMsg( 1, "%.2f BLEND STARTED: %d to %d, end at %.2f\n", gpGlobals->curtime, m_iBlendMode.Get(), m_iNextBlendMode.Get(), m_flNextBlendTime.Get() );
  246. }
  247. SetContextThink( &CScriptIntro::BlendComplete, m_flNextBlendTime, "BlendComplete" );
  248. }
  249. //-----------------------------------------------------------------------------
  250. // Purpose:
  251. //-----------------------------------------------------------------------------
  252. void CScriptIntro::BlendComplete( )
  253. {
  254. m_iBlendMode = m_iNextBlendMode;
  255. m_flBlendStartTime = m_flNextBlendTime = gpGlobals->curtime;
  256. m_iQueuedBlendMode = -1;
  257. SetContextThink( NULL, gpGlobals->curtime, "BlendComplete" );
  258. }
  259. //-----------------------------------------------------------------------------
  260. // Purpose:
  261. // Input : &inputdata -
  262. //-----------------------------------------------------------------------------
  263. void CScriptIntro::InputActivate( inputdata_t &inputdata )
  264. {
  265. m_bActive = true;
  266. g_hIntroScript = this;
  267. }
  268. //-----------------------------------------------------------------------------
  269. // Purpose:
  270. // Input : &inputdata -
  271. //-----------------------------------------------------------------------------
  272. void CScriptIntro::InputDeactivate( inputdata_t &inputdata )
  273. {
  274. m_bActive = false;
  275. }
  276. //-----------------------------------------------------------------------------
  277. // Purpose:
  278. // Input : &inputdata -
  279. //-----------------------------------------------------------------------------
  280. void CScriptIntro::InputFadeTo( inputdata_t &inputdata )
  281. {
  282. char parseString[255];
  283. Q_strncpy(parseString, inputdata.value.String(), sizeof(parseString));
  284. // Get the fade alpha
  285. char *pszParam = strtok(parseString," ");
  286. if ( !pszParam || !pszParam[0] )
  287. {
  288. Warning("%s (%s) received FadeTo input without an alpha. Syntax: <fade alpha> <fade duration>\n", GetClassname(), GetDebugName() );
  289. return;
  290. }
  291. float flAlpha = atof( pszParam );
  292. // Get the fade duration
  293. pszParam = strtok(NULL," ");
  294. if ( !pszParam || !pszParam[0] )
  295. {
  296. Warning("%s (%s) received FadeTo input without a duration. Syntax: <fade alpha> <fade duration>\n", GetClassname(), GetDebugName() );
  297. return;
  298. }
  299. // Set the two variables
  300. m_flFadeAlpha = flAlpha;
  301. m_flFadeDuration = atof( pszParam );
  302. //Msg("%.2f INPUT FADE: Fade to %.2f. End at %.2f\n", gpGlobals->curtime, m_flFadeAlpha.Get(), gpGlobals->curtime + m_flFadeDuration.Get() );
  303. }
  304. //-----------------------------------------------------------------------------
  305. // Purpose:
  306. // Input : &inputdata -
  307. //-----------------------------------------------------------------------------
  308. void CScriptIntro::InputSetFadeColor( inputdata_t &inputdata )
  309. {
  310. char parseString[255];
  311. Q_strncpy(parseString, inputdata.value.String(), sizeof(parseString));
  312. // Get the fade colors
  313. char *pszParam = strtok(parseString," ");
  314. if ( !pszParam || !pszParam[0] )
  315. {
  316. Warning("%s (%s) received SetFadeColor input without correct parameters. Syntax: <Red> <Green> <Blue>>\n", GetClassname(), GetDebugName() );
  317. return;
  318. }
  319. float flR = atof( pszParam );
  320. pszParam = strtok(NULL," ");
  321. if ( !pszParam || !pszParam[0] )
  322. {
  323. Warning("%s (%s) received SetFadeColor input without correct parameters. Syntax: <Red> <Green> <Blue>>\n", GetClassname(), GetDebugName() );
  324. return;
  325. }
  326. float flG = atof( pszParam );
  327. pszParam = strtok(NULL," ");
  328. if ( !pszParam || !pszParam[0] )
  329. {
  330. Warning("%s (%s) received SetFadeColor input without correct parameters. Syntax: <Red> <Green> <Blue>>\n", GetClassname(), GetDebugName() );
  331. return;
  332. }
  333. float flB = atof( pszParam );
  334. // Use the colors
  335. m_flFadeColor.Set( 0, flR );
  336. m_flFadeColor.Set( 1, flG );
  337. m_flFadeColor.Set( 2, flB );
  338. }