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.

162 lines
5.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // A message forwarder. Fires an OnTrigger output when triggered, and can be
  4. // disabled to prevent forwarding outputs.
  5. //
  6. // Useful as an intermediary between one entity and another for turning on or
  7. // off an I/O connection, or as a container for holding a set of outputs that
  8. // can be triggered from multiple places.
  9. //
  10. //=============================================================================
  11. #include "cbase.h"
  12. #include "entityinput.h"
  13. #include "entityoutput.h"
  14. #include "eventqueue.h"
  15. #include "soundent.h"
  16. #include "logicrelay.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. const int SF_REMOVE_ON_FIRE = 0x001; // Relay will remove itself after being triggered.
  20. const int SF_ALLOW_FAST_RETRIGGER = 0x002; // Unless set, relay will disable itself until the last output is sent.
  21. LINK_ENTITY_TO_CLASS(logic_relay, CLogicRelay);
  22. BEGIN_DATADESC( CLogicRelay )
  23. DEFINE_FIELD(m_bWaitForRefire, FIELD_BOOLEAN),
  24. DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled"),
  25. // Inputs
  26. DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable),
  27. DEFINE_INPUTFUNC(FIELD_VOID, "EnableRefire", InputEnableRefire),
  28. DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable),
  29. DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle),
  30. DEFINE_INPUTFUNC(FIELD_VOID, "Trigger", InputTrigger),
  31. DEFINE_INPUTFUNC(FIELD_VOID, "CancelPending", InputCancelPending),
  32. // Outputs
  33. DEFINE_OUTPUT(m_OnTrigger, "OnTrigger"),
  34. DEFINE_OUTPUT(m_OnSpawn, "OnSpawn"),
  35. END_DATADESC()
  36. //-----------------------------------------------------------------------------
  37. // Purpose: Constructor.
  38. //-----------------------------------------------------------------------------
  39. CLogicRelay::CLogicRelay(void)
  40. {
  41. }
  42. //------------------------------------------------------------------------------
  43. // Kickstarts a think if we have OnSpawn connections.
  44. //------------------------------------------------------------------------------
  45. void CLogicRelay::Activate()
  46. {
  47. BaseClass::Activate();
  48. if ( m_OnSpawn.NumberOfElements() > 0)
  49. {
  50. SetNextThink( gpGlobals->curtime + 0.01 );
  51. }
  52. }
  53. //-----------------------------------------------------------------------------
  54. // If we have OnSpawn connections, this is called shortly after spawning to
  55. // fire the OnSpawn output.
  56. //-----------------------------------------------------------------------------
  57. void CLogicRelay::Think()
  58. {
  59. // Fire an output when we spawn. This is used for self-starting an entity
  60. // template -- since the logic_relay is inside the template, it gets all the
  61. // name and I/O connection fixup, so can target other entities in the template.
  62. m_OnSpawn.FireOutput( this, this );
  63. // We only get here if we had OnSpawn connections, so this is safe.
  64. if ( m_spawnflags & SF_REMOVE_ON_FIRE )
  65. {
  66. UTIL_Remove(this);
  67. }
  68. }
  69. //------------------------------------------------------------------------------
  70. // Purpose: Turns on the relay, allowing it to fire outputs.
  71. //------------------------------------------------------------------------------
  72. void CLogicRelay::InputEnable( inputdata_t &inputdata )
  73. {
  74. m_bDisabled = false;
  75. }
  76. //------------------------------------------------------------------------------
  77. // Purpose: Enables us to fire again. This input is only posted from our Trigger
  78. // function to prevent rapid refire.
  79. //------------------------------------------------------------------------------
  80. void CLogicRelay::InputEnableRefire( inputdata_t &inputdata )
  81. {
  82. m_bWaitForRefire = false;
  83. }
  84. //------------------------------------------------------------------------------
  85. // Purpose: Cancels any I/O events in the queue that were fired by us.
  86. //------------------------------------------------------------------------------
  87. void CLogicRelay::InputCancelPending( inputdata_t &inputdata )
  88. {
  89. g_EventQueue.CancelEvents( this );
  90. // Stop waiting; allow another Trigger.
  91. m_bWaitForRefire = false;
  92. }
  93. //------------------------------------------------------------------------------
  94. // Purpose: Turns off the relay, preventing it from firing outputs.
  95. //------------------------------------------------------------------------------
  96. void CLogicRelay::InputDisable( inputdata_t &inputdata )
  97. {
  98. m_bDisabled = true;
  99. }
  100. //------------------------------------------------------------------------------
  101. // Purpose: Toggles the enabled/disabled state of the relay.
  102. //------------------------------------------------------------------------------
  103. void CLogicRelay::InputToggle( inputdata_t &inputdata )
  104. {
  105. m_bDisabled = !m_bDisabled;
  106. }
  107. //-----------------------------------------------------------------------------
  108. // Purpose: Input handler that triggers the relay.
  109. //-----------------------------------------------------------------------------
  110. void CLogicRelay::InputTrigger( inputdata_t &inputdata )
  111. {
  112. if ((!m_bDisabled) && (!m_bWaitForRefire))
  113. {
  114. m_OnTrigger.FireOutput( inputdata.pActivator, this );
  115. if (m_spawnflags & SF_REMOVE_ON_FIRE)
  116. {
  117. UTIL_Remove(this);
  118. }
  119. else if (!(m_spawnflags & SF_ALLOW_FAST_RETRIGGER))
  120. {
  121. //
  122. // Disable the relay so that it cannot be refired until after the last output
  123. // has been fired and post an input to re-enable ourselves.
  124. //
  125. m_bWaitForRefire = true;
  126. g_EventQueue.AddEvent(this, "EnableRefire", m_OnTrigger.GetMaxDelay() + 0.001, this, this);
  127. }
  128. }
  129. }