Exemple #1
0
//=========================================================
// StartMonster
//=========================================================
void CSquadMonster :: StartMonster( void )
{
	CBaseMonster :: StartMonster();

	if ( ( m_afCapability & bits_CAP_SQUAD ) && !InSquad() )
	{
		if ( HasNetName() )
		{
			// if I have a groupname, I can only recruit if I'm flagged as leader
			if ( !GetSpawnFlags().Any( SF_SQUADMONSTER_LEADER ) )
			{
				return;
			}
		}

		// try to form squads now.
		int iSquadSize = SquadRecruit( 1024, 4 );

		if ( iSquadSize )
		{
		  ALERT ( at_aiconsole, "Squad of %d %s formed\n", iSquadSize, GetClassname() );
		}

		if ( IsLeader() && ClassnameIs( "monster_human_grunt" ) )
		{
			SetBodygroup( 1, 1 ); // UNDONE: truly ugly hack
			SetSkin( 0 );
		}

	}
}
Exemple #2
0
//
// The door has reached the "down" position.  Back to quiescence.
//
void CBaseDoor::DoorHitBottom( void )
{
	if( !GetSpawnFlags().Any( SF_DOOR_SILENT ) )
	{
		STOP_SOUND( this, CHAN_STATIC, ( char* ) STRING( pev->noiseMoving ) );
		EMIT_SOUND( this, CHAN_STATIC, ( char* ) STRING( pev->noiseArrived ), 1, ATTN_NORM );
	}

	ASSERT( m_toggle_state == TS_GOING_DOWN );
	m_toggle_state = TS_AT_BOTTOM;

	// Re-instate touch method, cycle is complete
	if( GetSpawnFlags().Any( SF_DOOR_USE_ONLY ) )
	{// use only door
		SetTouch( NULL );
	}
	else // touchable door
		SetTouch( &CBaseDoor::DoorTouch );

	SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished

												   // Fire the close target (if startopen is set, then "top" is closed) - netname is the close target
	if( HasNetName() && !GetSpawnFlags().Any( SF_DOOR_START_OPEN ) )
		FireTargets( GetNetName(), m_hActivator, this, USE_TOGGLE, 0 );
}
Exemple #3
0
//
// The door has reached the "up" position.  Either go back down, or wait for another activation.
//
void CBaseDoor::DoorHitTop( void )
{
	if( !GetSpawnFlags().Any( SF_DOOR_SILENT ) )
	{
		STOP_SOUND( this, CHAN_STATIC, ( char* ) STRING( pev->noiseMoving ) );
		EMIT_SOUND( this, CHAN_STATIC, ( char* ) STRING( pev->noiseArrived ), 1, ATTN_NORM );
	}

	ASSERT( m_toggle_state == TS_GOING_UP );
	m_toggle_state = TS_AT_TOP;

	// toggle-doors don't come down automatically, they wait for refire.
	if( GetSpawnFlags().Any( SF_DOOR_NO_AUTO_RETURN ) )
	{
		// Re-instate touch method, movement is complete
		if( !GetSpawnFlags().Any( SF_DOOR_USE_ONLY ) )
			SetTouch( &CBaseDoor::DoorTouch );
	}
	else
	{
		// In flWait seconds, DoorGoDown will fire, unless wait is -1, then door stays open
		SetNextThink( GetLastThink() + m_flWait );
		SetThink( &CBaseDoor::DoorGoDown );

		if( m_flWait == -1 )
		{
			SetNextThink( -1 );
		}
	}

	// Fire the close target (if startopen is set, then "top" is closed) - netname is the close target
	if( HasNetName() && GetSpawnFlags().Any( SF_DOOR_START_OPEN ) )
		FireTargets( GetNetName(), m_hActivator, this, USE_TOGGLE, 0 );

	SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished
}
Exemple #4
0
//=========================================================
//
// SquadRecruit(), get some monsters of my classification and
// link them as a group.  returns the group size
//
//=========================================================
int CSquadMonster :: SquadRecruit( int searchRadius, int maxMembers )
{
	int squadCount;
	EntityClassification_t iMyClass = Classify();// cache this monster's class


	// Don't recruit if I'm already in a group
	if ( InSquad() )
		return 0;

	if ( maxMembers < 2 )
		return 0;

	// I am my own leader
	m_hSquadLeader = this;
	squadCount = 1;

	CBaseEntity *pEntity = NULL;

	if ( HasNetName() )
	{
		// I have a netname, so unconditionally recruit everyone else with that name.
		pEntity = UTIL_FindEntityByString( pEntity, "netname", GetNetName() );
		while ( pEntity )
		{
			CSquadMonster *pRecruit = pEntity->MySquadMonsterPointer();

			if ( pRecruit )
			{
				if ( !pRecruit->InSquad() && pRecruit->Classify() == iMyClass && pRecruit != this )
				{
					// minimum protection here against user error.in worldcraft. 
					if (!SquadAdd( pRecruit ))
						break;
					squadCount++;
				}
			}
	
			pEntity = UTIL_FindEntityByString( pEntity, "netname", GetNetName() );
		}
	}
	else 
	{
		while ((pEntity = UTIL_FindEntityInSphere( pEntity, GetAbsOrigin(), searchRadius )) != NULL)
		{
			CSquadMonster *pRecruit = pEntity->MySquadMonsterPointer( );

			if ( pRecruit && pRecruit != this && pRecruit->IsAlive() && !pRecruit->m_pCine )
			{
				// Can we recruit this guy?
				if ( !pRecruit->InSquad() && pRecruit->Classify() == iMyClass &&
				   ( (iMyClass != EntityClassifications().GetClassificationId( classify::ALIEN_MONSTER )) || FStrEq( GetClassname(), pRecruit->GetClassname() )) &&
				    !pRecruit->HasNetName() )
				{
					TraceResult tr;
					UTIL_TraceLine( GetAbsOrigin() + GetViewOffset(), pRecruit->GetAbsOrigin() + GetViewOffset(), ignore_monsters, pRecruit->edict(), &tr );// try to hit recruit with a traceline.
					if ( tr.flFraction == 1.0 )
					{
						if (!SquadAdd( pRecruit ))
							break;

						squadCount++;
					}
				}
			}
		}
	}

	// no single member squads
	if (squadCount == 1)
	{
		m_hSquadLeader = NULL;
	}

	return squadCount;
}
Exemple #5
0
//=========================================================
// MakeMonster-  this is the code that drops the monster
//=========================================================
void CMonsterMaker::MakeMonster( void )
{
	if ( m_iMaxLiveChildren > 0 && m_cLiveChildren >= m_iMaxLiveChildren )
	{// not allowed to make a new one yet. Too many live ones out right now.
		return;
	}

	if ( !m_flGround )
	{
		// set altitude. Now that I'm activated, any breakables, etc should be out from under me. 
		TraceResult tr;

		UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() - Vector ( 0, 0, 2048 ), ignore_monsters, ENT(pev), &tr );
		m_flGround = tr.vecEndPos.z;
	}

	Vector mins = GetAbsOrigin() - Vector( 34, 34, 0 );
	Vector maxs = GetAbsOrigin() + Vector( 34, 34, 0 );
	maxs.z = GetAbsOrigin().z;
	mins.z = m_flGround;

	CBaseEntity *pList[2];
	int count = UTIL_EntitiesInBox( pList, 2, mins, maxs, FL_CLIENT|FL_MONSTER );
	if ( count )
	{
		// don't build a stack of monsters!
		return;
	}

	CBaseEntity* pEntity = CBaseEntity::Create( STRING( m_iszMonsterClassname ), GetAbsOrigin(), GetAbsAngles(), nullptr, false );

	if( !pEntity )
	{
		ALERT( at_console, "NULL Ent in MonsterMaker!\n" );
		return;
	}
	
	// If I have a target, fire!
	if ( HasTarget() )
	{
		// delay already overloaded for this entity, so can't call SUB_UseTargets()
		FireTargets( GetTarget(), this, this, USE_TOGGLE, 0 );
	}

	pEntity->SetAbsOrigin( GetAbsOrigin() );
	pEntity->SetAbsAngles( GetAbsAngles() );
	pEntity->GetSpawnFlags() |= SF_MONSTER_FALL_TO_GROUND;

	// Children hit monsterclip brushes
	if ( GetSpawnFlags().Any(SF_MONSTERMAKER_MONSTERCLIP ) )
		pEntity->GetSpawnFlags() |= SF_MONSTER_HITMONSTERCLIP;

	DispatchSpawn( pEntity->edict() );

	pEntity->SetOwner( this );

	if ( HasNetName() )
	{
		// if I have a netname (overloaded), give the child monster that name as a targetname
		pEntity->SetTargetname( GetNetName() );
	}

	m_cLiveChildren++;// count this monster
	m_cNumMonsters--;

	if ( m_cNumMonsters == 0 )
	{
		// Disable this forever.  Don't kill it because it still gets death notices
		SetThink( NULL );
		SetUse( NULL );
	}
}