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.

294 lines
7.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: An entity that creates NPCs in the game.
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "entityapi.h"
  8. #include "entityoutput.h"
  9. #include "ai_basenpc.h"
  10. #include "hl1_monstermaker.h"
  11. #include "mapentities.h"
  12. BEGIN_DATADESC( CNPCMaker )
  13. DEFINE_KEYFIELD( m_iMaxNumNPCs, FIELD_INTEGER, "monstercount" ),
  14. DEFINE_KEYFIELD( m_iMaxLiveChildren, FIELD_INTEGER, "MaxLiveChildren" ),
  15. DEFINE_KEYFIELD( m_flSpawnFrequency, FIELD_FLOAT, "delay" ),
  16. DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ),
  17. DEFINE_KEYFIELD( m_iszNPCClassname, FIELD_STRING, "monstertype" ),
  18. DEFINE_FIELD( m_cLiveChildren, FIELD_INTEGER ),
  19. DEFINE_FIELD( m_flGround, FIELD_FLOAT ),
  20. // Inputs
  21. DEFINE_INPUTFUNC( FIELD_VOID, "Spawn", InputSpawnNPC ),
  22. DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
  23. DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
  24. DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ),
  25. // Outputs
  26. DEFINE_OUTPUT( m_OnSpawnNPC, "OnSpawnNPC" ),
  27. // Function Pointers
  28. DEFINE_THINKFUNC( MakerThink ),
  29. END_DATADESC()
  30. LINK_ENTITY_TO_CLASS( monstermaker, CNPCMaker );
  31. //-----------------------------------------------------------------------------
  32. // Purpose: Spawn
  33. //-----------------------------------------------------------------------------
  34. void CNPCMaker::Spawn( void )
  35. {
  36. SetSolid( SOLID_NONE );
  37. m_cLiveChildren = 0;
  38. Precache();
  39. // If I can make an infinite number of NPC, force them to fade
  40. if ( m_spawnflags & SF_NPCMAKER_INF_CHILD )
  41. {
  42. m_spawnflags |= SF_NPCMAKER_FADE;
  43. }
  44. //Start on?
  45. if ( m_bDisabled == false )
  46. {
  47. SetThink ( &CNPCMaker::MakerThink );
  48. SetNextThink( gpGlobals->curtime + m_flSpawnFrequency );
  49. }
  50. else
  51. {
  52. //wait to be activated.
  53. SetThink ( &CBaseEntity::SUB_DoNothing );
  54. }
  55. m_flGround = 0;
  56. }
  57. //-----------------------------------------------------------------------------
  58. // Purpose: Returns whether or not it is OK to make an NPC at this instant.
  59. //-----------------------------------------------------------------------------
  60. bool CNPCMaker::CanMakeNPC( void )
  61. {
  62. if ( m_iMaxLiveChildren > 0 && m_cLiveChildren >= m_iMaxLiveChildren )
  63. {// not allowed to make a new one yet. Too many live ones out right now.
  64. return false;
  65. }
  66. if ( !m_flGround )
  67. {
  68. // set altitude. Now that I'm activated, any breakables, etc should be out from under me.
  69. trace_t tr;
  70. UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() - Vector ( 0, 0, 2048 ), MASK_NPCSOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
  71. m_flGround = tr.endpos.z;
  72. }
  73. Vector mins = GetAbsOrigin() - Vector( 34, 34, 0 );
  74. Vector maxs = GetAbsOrigin() + Vector( 34, 34, 0 );
  75. maxs.z = GetAbsOrigin().z;
  76. //Only adjust for the ground if we want it
  77. if ( ( m_spawnflags & SF_NPCMAKER_NO_DROP ) == false )
  78. {
  79. mins.z = m_flGround;
  80. }
  81. CBaseEntity *pList[128];
  82. int count = UTIL_EntitiesInBox( pList, 128, mins, maxs, FL_CLIENT|FL_NPC );
  83. if ( count )
  84. {
  85. //Iterate through the list and check the results
  86. for ( int i = 0; i < count; i++ )
  87. {
  88. //Don't build on top of another entity
  89. if ( pList[i] == NULL )
  90. continue;
  91. //If one of the entities is solid, then we can't spawn now
  92. if ( ( pList[i]->GetSolidFlags() & FSOLID_NOT_SOLID ) == false )
  93. return false;
  94. }
  95. }
  96. return true;
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Purpose: If this had a finite number of children, return true if they've all
  100. // been created.
  101. //-----------------------------------------------------------------------------
  102. bool CNPCMaker::IsDepleted()
  103. {
  104. if ( (m_spawnflags & SF_NPCMAKER_INF_CHILD) || m_iMaxNumNPCs > 0 )
  105. return false;
  106. return true;
  107. }
  108. //-----------------------------------------------------------------------------
  109. // Purpose: Toggle the spawner's state
  110. //-----------------------------------------------------------------------------
  111. void CNPCMaker::Toggle( void )
  112. {
  113. if ( m_bDisabled )
  114. {
  115. Enable();
  116. }
  117. else
  118. {
  119. Disable();
  120. }
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Purpose: Start the spawner
  124. //-----------------------------------------------------------------------------
  125. void CNPCMaker::Enable( void )
  126. {
  127. // can't be enabled once depleted
  128. if ( IsDepleted() )
  129. return;
  130. m_bDisabled = false;
  131. SetThink ( &CNPCMaker::MakerThink );
  132. SetNextThink( gpGlobals->curtime );
  133. }
  134. //-----------------------------------------------------------------------------
  135. // Purpose: Stop the spawner
  136. //-----------------------------------------------------------------------------
  137. void CNPCMaker::Disable( void )
  138. {
  139. m_bDisabled = true;
  140. SetThink ( NULL );
  141. }
  142. //-----------------------------------------------------------------------------
  143. // Purpose: Input handler that spawns an NPC.
  144. //-----------------------------------------------------------------------------
  145. void CNPCMaker::InputSpawnNPC( inputdata_t &inputdata )
  146. {
  147. MakeNPC();
  148. }
  149. //-----------------------------------------------------------------------------
  150. // Purpose: Input hander that starts the spawner
  151. //-----------------------------------------------------------------------------
  152. void CNPCMaker::InputEnable( inputdata_t &inputdata )
  153. {
  154. Enable();
  155. }
  156. //-----------------------------------------------------------------------------
  157. // Purpose: Input hander that stops the spawner
  158. //-----------------------------------------------------------------------------
  159. void CNPCMaker::InputDisable( inputdata_t &inputdata )
  160. {
  161. Disable();
  162. }
  163. //-----------------------------------------------------------------------------
  164. // Purpose: Input hander that toggles the spawner
  165. //-----------------------------------------------------------------------------
  166. void CNPCMaker::InputToggle( inputdata_t &inputdata )
  167. {
  168. Toggle();
  169. }
  170. //-----------------------------------------------------------------------------
  171. // Purpose: Precache the target NPC
  172. //-----------------------------------------------------------------------------
  173. void CNPCMaker::Precache( void )
  174. {
  175. BaseClass::Precache();
  176. UTIL_PrecacheOther( STRING( m_iszNPCClassname ) );
  177. }
  178. //-----------------------------------------------------------------------------
  179. // Purpose: Creates the NPC.
  180. //-----------------------------------------------------------------------------
  181. void CNPCMaker::MakeNPC( void )
  182. {
  183. if (!CanMakeNPC())
  184. {
  185. return;
  186. }
  187. CBaseEntity *pent = (CBaseEntity*)CreateEntityByName( STRING(m_iszNPCClassname) );
  188. if ( !pent )
  189. {
  190. Warning("NULL Ent in NPCMaker!\n" );
  191. return;
  192. }
  193. m_OnSpawnNPC.FireOutput( this, this );
  194. pent->SetLocalOrigin( GetAbsOrigin() );
  195. pent->SetLocalAngles( GetAbsAngles() );
  196. pent->AddSpawnFlags( SF_NPC_FALL_TO_GROUND );
  197. if ( m_spawnflags & SF_NPCMAKER_FADE )
  198. {
  199. pent->AddSpawnFlags( SF_NPC_FADE_CORPSE );
  200. }
  201. DispatchSpawn( pent );
  202. pent->SetOwnerEntity( this );
  203. m_cLiveChildren++;// count this NPC
  204. if (!(m_spawnflags & SF_NPCMAKER_INF_CHILD))
  205. {
  206. m_iMaxNumNPCs--;
  207. if ( IsDepleted() )
  208. {
  209. // Disable this forever. Don't kill it because it still gets death notices
  210. SetThink( NULL );
  211. SetUse( NULL );
  212. }
  213. }
  214. }
  215. //-----------------------------------------------------------------------------
  216. // Purpose: Creates a new NPC every so often.
  217. //-----------------------------------------------------------------------------
  218. void CNPCMaker::MakerThink ( void )
  219. {
  220. SetNextThink( gpGlobals->curtime + m_flSpawnFrequency );
  221. MakeNPC();
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Purpose:
  225. // Input : *pVictim -
  226. //-----------------------------------------------------------------------------
  227. void CNPCMaker::DeathNotice( CBaseEntity *pVictim )
  228. {
  229. // ok, we've gotten the deathnotice from our child, now clear out its owner if we don't want it to fade.
  230. m_cLiveChildren--;
  231. }