Counter Strike : Global Offensive Source Code
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.

200 lines
6.5 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ====
  2. //
  3. // When triggered, will attempt to fire off each of its outputs. Each output
  4. // has its own chance of firing.
  5. //
  6. //=============================================================================
  7. #include "cbase.h"
  8. #include "entityinput.h"
  9. #include "entityoutput.h"
  10. #include "eventqueue.h"
  11. #include "soundent.h"
  12. #include "logic_random_outputs.h"
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. const int SF_REMOVE_ON_FIRE = 0x001; // Relay will remove itself after being triggered.
  16. const int SF_ALLOW_FAST_RETRIGGER = 0x002; // Unless set, entity will disable itself until the last output is sent.
  17. LINK_ENTITY_TO_CLASS(logic_random_outputs, CLogicRandomOutputs);
  18. BEGIN_DATADESC( CLogicRandomOutputs )
  19. DEFINE_FIELD(m_bWaitForRefire, FIELD_BOOLEAN),
  20. DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled"),
  21. DEFINE_AUTO_ARRAY( m_flOnTriggerChance, FIELD_FLOAT ),
  22. // Inputs
  23. DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable),
  24. DEFINE_INPUTFUNC(FIELD_VOID, "EnableRefire", InputEnableRefire),
  25. DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable),
  26. DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle),
  27. DEFINE_INPUTFUNC(FIELD_VOID, "Trigger", InputTrigger),
  28. DEFINE_INPUTFUNC(FIELD_VOID, "CancelPending", InputCancelPending),
  29. // Outputs
  30. DEFINE_OUTPUT(m_OnSpawn, "OnSpawn"),
  31. DEFINE_OUTPUT(m_Output[0], "OnTrigger1"),
  32. DEFINE_OUTPUT(m_Output[1], "OnTrigger2"),
  33. DEFINE_OUTPUT(m_Output[2], "OnTrigger3"),
  34. DEFINE_OUTPUT(m_Output[3], "OnTrigger4"),
  35. DEFINE_OUTPUT(m_Output[4], "OnTrigger5"),
  36. DEFINE_OUTPUT(m_Output[5], "OnTrigger6"),
  37. DEFINE_OUTPUT(m_Output[6], "OnTrigger7"),
  38. DEFINE_OUTPUT(m_Output[7], "OnTrigger8"),
  39. END_DATADESC()
  40. //-----------------------------------------------------------------------------
  41. // Purpose: Constructor.
  42. //-----------------------------------------------------------------------------
  43. CLogicRandomOutputs::CLogicRandomOutputs(void)
  44. {
  45. }
  46. //-----------------------------------------------------------------------------
  47. // Purpose: Read in the chance of firing each output
  48. //-----------------------------------------------------------------------------
  49. bool CLogicRandomOutputs::KeyValue( const char *szKeyName, const char *szValue )
  50. {
  51. if ( szValue && szValue[0] )
  52. {
  53. for ( int i=0; i < NUM_RANDOM_OUTPUTS; i++ )
  54. {
  55. if ( FStrEq( szKeyName, UTIL_VarArgs( "OnTriggerChance%d", i ) ) )
  56. {
  57. m_flOnTriggerChance[i] = atof( szValue );
  58. return true;
  59. }
  60. }
  61. }
  62. return BaseClass::KeyValue( szKeyName, szValue );
  63. }
  64. //------------------------------------------------------------------------------
  65. // Kickstarts a think if we have OnSpawn connections.
  66. //------------------------------------------------------------------------------
  67. void CLogicRandomOutputs::Activate()
  68. {
  69. BaseClass::Activate();
  70. if ( m_OnSpawn.NumberOfElements() > 0)
  71. {
  72. SetNextThink( gpGlobals->curtime + 0.01 );
  73. }
  74. }
  75. //-----------------------------------------------------------------------------
  76. // If we have OnSpawn connections, this is called shortly after spawning to
  77. // fire the OnSpawn output.
  78. //-----------------------------------------------------------------------------
  79. void CLogicRandomOutputs::Think()
  80. {
  81. // Fire an output when we spawn. This is used for self-starting an entity
  82. // template -- since the logic_random_outputs is inside the template, it gets all the
  83. // name and I/O connection fixup, so can target other entities in the template.
  84. m_OnSpawn.FireOutput( this, this );
  85. // We only get here if we had OnSpawn connections, so this is safe.
  86. if ( m_spawnflags & SF_REMOVE_ON_FIRE )
  87. {
  88. UTIL_Remove(this);
  89. }
  90. }
  91. //------------------------------------------------------------------------------
  92. // Purpose: Turns on the entity, allowing it to fire outputs.
  93. //------------------------------------------------------------------------------
  94. void CLogicRandomOutputs::InputEnable( inputdata_t &inputdata )
  95. {
  96. m_bDisabled = false;
  97. }
  98. //------------------------------------------------------------------------------
  99. // Purpose: Enables us to fire again. This input is only posted from our Trigger
  100. // function to prevent rapid refire.
  101. //------------------------------------------------------------------------------
  102. void CLogicRandomOutputs::InputEnableRefire( inputdata_t &inputdata )
  103. {
  104. Msg(" now enabling refire\n" );
  105. m_bWaitForRefire = false;
  106. }
  107. //------------------------------------------------------------------------------
  108. // Purpose: Cancels any I/O events in the queue that were fired by us.
  109. //------------------------------------------------------------------------------
  110. void CLogicRandomOutputs::InputCancelPending( inputdata_t &inputdata )
  111. {
  112. g_EventQueue.CancelEvents( this );
  113. // Stop waiting; allow another Trigger.
  114. m_bWaitForRefire = false;
  115. }
  116. //------------------------------------------------------------------------------
  117. // Purpose: Turns off the entity, preventing it from firing outputs.
  118. //------------------------------------------------------------------------------
  119. void CLogicRandomOutputs::InputDisable( inputdata_t &inputdata )
  120. {
  121. m_bDisabled = true;
  122. }
  123. //------------------------------------------------------------------------------
  124. // Purpose: Toggles the enabled/disabled state of the entity.
  125. //------------------------------------------------------------------------------
  126. void CLogicRandomOutputs::InputToggle( inputdata_t &inputdata )
  127. {
  128. m_bDisabled = !m_bDisabled;
  129. }
  130. //-----------------------------------------------------------------------------
  131. // Purpose: Input handler that triggers the logic_random_outputs.
  132. //-----------------------------------------------------------------------------
  133. void CLogicRandomOutputs::InputTrigger( inputdata_t &inputdata )
  134. {
  135. if ((!m_bDisabled) && (!m_bWaitForRefire))
  136. {
  137. for ( int i=0 ; i < NUM_RANDOM_OUTPUTS ; i++ )
  138. {
  139. if ( RandomFloat() <= m_flOnTriggerChance[i] )
  140. {
  141. m_Output[i].FireOutput( inputdata.pActivator, this );
  142. }
  143. }
  144. if (m_spawnflags & SF_REMOVE_ON_FIRE)
  145. {
  146. UTIL_Remove(this);
  147. }
  148. else if (!(m_spawnflags & SF_ALLOW_FAST_RETRIGGER))
  149. {
  150. // find the max delay from all our outputs
  151. float fMaxDelay = 0;
  152. for ( int i=0 ; i < NUM_RANDOM_OUTPUTS ; i++ )
  153. {
  154. fMaxDelay = MAX( fMaxDelay, m_Output[i].GetMaxDelay() );
  155. }
  156. if ( fMaxDelay > 0 )
  157. {
  158. // Disable the relay so that it cannot be refired until after the last output
  159. // has been fired and post an input to re-enable ourselves.
  160. m_bWaitForRefire = true;
  161. g_EventQueue.AddEvent(this, "EnableRefire", fMaxDelay + 0.001, this, this);
  162. }
  163. }
  164. }
  165. }