Difference between revisions of "Push Gameplay"

From Valve Developer Community
Jump to: navigation, search
m (FGD Entry)
m (Contact me as needed)
Line 300: Line 300:
 
----
 
----
 
   
 
   
=== Contact me as needed ===
+
== Contact me as needed ==
 
Full tutorial is possibly going to be on my site if this post is frequented enough to give me cause enough to write it.
 
Full tutorial is possibly going to be on my site if this post is frequented enough to give me cause enough to write it.
  
 
[[User:Imatard|ImaTard]] 04:14, 10 Feb 2006 (PST)
 
[[User:Imatard|ImaTard]] 04:14, 10 Feb 2006 (PST)

Revision as of 05:15, 10 February 2006

I realize this is not a complete walkthrough tutorial, but this is as good as i am able to get at my current work load. You guys can ... wikificate this all you wish. Its working, tested and in game.

1 Brush Entity 1 FGD Entry

Done...

Brush Entity

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: White --- Push Point Entity
//
//=============================================================================//
 
#include "cbase.h"
 
extern ConVar	showtriggers;
 
class CPushPoint : public CBaseToggle
{
public:
	DECLARE_CLASS( CPushPoint, CBaseToggle );
	DECLARE_DATADESC();
 
	void Spawn( void );
 
	virtual void StartTouch( CBaseEntity *pOther );
	virtual void EndTouch( CBaseEntity *pOther );
	void PlayerUpdateThink();
	bool CreateVPhysics( void );
 
	// Push Functions
	int GetStatus( void );
private:
	// Push Controls
	int				m_nControlled;		// Has this point been captured? By which team?
	float			m_fCaptured;		// Timer for capture
	
	// Alien Variables & Outputs
	COutputEvent m_OnAlienCapture;
	COutputEvent m_OnAlienStartTouch;
	COutputEvent m_OnAlienEndTouch;
	CUtlVector<CBasePlayerHandle> m_hAliens;

	// Human Variables & Outputs
	COutputEvent m_OnHumanCapture;
	COutputEvent m_OnHumanStartTouch;
	COutputEvent m_OnHumanEndTouch;
	CUtlVector<CBasePlayerHandle> m_hHumans;

	// Mapping Tagged Fields
	string_t		m_sNext;
	string_t		m_sPrev;
	string_t		m_sLocation;
	float			m_fCapture_time;

	// Misc. Outputs
	COutputEvent m_OnCapture;
	COutputEvent m_OnStartTouch;
	COutputEvent m_OnEndTouch;
};
 
LINK_ENTITY_TO_CLASS( push_block, CPushPoint );
 
// Start of our data description for the class
BEGIN_DATADESC( CPushPoint )
 
	// Think Functions
	DEFINE_THINKFUNC( PlayerUpdateThink ),

	// Mapping Tagged Fields
	DEFINE_KEYFIELD( m_sNext, FIELD_STRING, "next" ),
	DEFINE_KEYFIELD( m_sPrev, FIELD_STRING, "prev" ),
	DEFINE_KEYFIELD( m_sLocation, FIELD_STRING, "location"),
	DEFINE_KEYFIELD( m_fCapture_time, FIELD_FLOAT, "timer" ),
	
	// Alien Outputs
	DEFINE_OUTPUT( m_OnAlienCapture, "OnAlienCapture" ),
	DEFINE_OUTPUT( m_OnAlienStartTouch, "OnAlienStartTouch" ),
	DEFINE_OUTPUT( m_OnAlienEndTouch, "OnAlienEndTouch" ),

	// Human Outputs
	DEFINE_OUTPUT( m_OnHumanCapture, "OnHumanCapture" ),
	DEFINE_OUTPUT( m_OnHumanStartTouch, "OnHumanStartTouch" ),
	DEFINE_OUTPUT( m_OnHumanEndTouch, "OnHumanEndTouch" ),

	// Misc. Outputs
	DEFINE_OUTPUT( m_OnCapture, "OnCapture" ),
	DEFINE_OUTPUT( m_OnStartTouch, "OnStartTouch" ),
	DEFINE_OUTPUT( m_OnEndTouch, "OnEndTouch" ),
 
END_DATADESC()
 
//-----------------------------------------------------------------------------
// Purpose: Sets up the entity's initial state
//-----------------------------------------------------------------------------
void CPushPoint::Spawn( void )
{
	m_nControlled = 0;
 
	// We should use the bsp
	SetSolid( SOLID_BSP );	
	// And not collide with it
	AddSolidFlags( FSOLID_NOT_SOLID );
	// But still use it for interaction
	AddSolidFlags( FSOLID_TRIGGER );	
 
	// use the trigger no draw garbage
	if ( showtriggers.GetInt() == 0 )
	{
		AddEffects( EF_NODRAW );
	}

	// Use our brushmodel
	SetModel( STRING( GetModelName() ) );
 
	// Create our physics hull information
	CreateVPhysics();
}
 
//-----------------------------------------------------------------------------
// Purpose: Setup our physics information so we collide properly
//-----------------------------------------------------------------------------
bool CPushPoint::CreateVPhysics( void )
{
	// For collisions with physics objects
	VPhysicsInitShadow( false, false );
 
	return true;
}
 
 
int CPushPoint::GetStatus( void )
{
	return m_nControlled;
}
 
void CPushPoint::StartTouch( CBaseEntity *pOther )
{
	// Someone has touched me
	if (!pOther->IsPlayer())
		return;

	// they are a player... grab him/her
	CBasePlayer *pPlayer = ToBasePlayer(pOther);
 
	// if their team is in control of me...
	if (pPlayer->GetTeamNumber() == m_nControlled)
	{			
		// let them know and skip out
		Msg("You already control this point '%s'.\n",  m_sLocation.ToCStr() ); 
		return;
	}

	// Someone has touched me and im not captured by them...
	m_OnStartTouch.FireOutput(pOther,this);

	// See which previous point to call...
	string_t pPrevious = pPlayer->GetTeamNumber() == TEAM_HUMANS? m_sNext : m_sPrev;
	
	// See who the fuck just touched me
	pPlayer->GetTeamNumber() == TEAM_HUMANS? m_OnHumanStartTouch.FireOutput(pPlayer, this) : m_OnAlienStartTouch.FireOutput(pPlayer, this);;

	// Grab the previous push point
	CPushPoint *pPush = dynamic_cast<CPushPoint *>(gEntList.FindEntityByName( NULL, pPrevious, NULL ));
 
	// If there is a previous push point AND its not captured by the jerk who touched me...
	if (pPush && pPush->GetStatus() != pPlayer->GetTeamNumber())
	{
		Msg("You do not control the previous point '%s'.\nGo back.\n",  m_sLocation.ToCStr() ); 
		return ;
	}

	// Cool, i guess i can start thinking now.
	SetThink( &CPushPoint::PlayerUpdateThink );
	SetNextThink( gpGlobals->curtime + 0.2 );

	BaseClass::StartTouch( pOther );
}
 
 
void CPushPoint::EndTouch( CBaseEntity *pOther )
{
	// Someone stopped touching me, is it a player?
	if (pOther->IsPlayer())
	{
		// grab the player
		CBasePlayer *player = ToBasePlayer(pOther);

		// see what they team they are on...
		if (player->GetTeamNumber() == TEAM_HUMANS)
		{
			// remove them 
			m_hHumans.FindAndRemove(player);
			// Fire output
			m_OnHumanEndTouch.FireOutput(player,this);
		}
		else if (player->GetTeamNumber() == TEAM_ALIENS)
		{
			// remove them
			m_hAliens.FindAndRemove(player);
			// fire output
			m_OnAlienEndTouch.FireOutput(player,this);
		}

		// If there is no one of importance touching me...
		if (m_hAliens.Count() == 0 && m_hHumans.Count() == 0)
		{
			// Clear the thinking and timer
			SetThink(NULL);
			SetNextThink(0);
			m_fCaptured = 0;
		}
	}
	BaseClass::EndTouch( pOther );
}
// look for dead/spectating players in our volume, to call touch on
void CPushPoint::PlayerUpdateThink()
{
	// Set up my next thought process
	SetThink( &CPushPoint::PlayerUpdateThink );
	SetNextThink( gpGlobals->curtime + 0.2 );

	// Clear out the lists
	m_hAliens.RemoveAll();
	m_hHumans.RemoveAll();

	// See who is intersecting me and put them into the appropriate list
	for (int i=0; i<gpGlobals->maxClients; i++ )
	{
		// this player
		CBasePlayer *player = UTIL_PlayerByIndex( i );
 
		// is ... not a player...
		if ( !player )
			continue;
 
		// oh they are, they have to be alive too so...
		if ( !player->IsAlive() )
			continue;
 
		// if the player is intersecting the trigger, track it by storing them into the appropriate listing
		if ( Intersects( player ) )
			player->GetTeamNumber() == TEAM_ALIENS ? m_hAliens.AddToTail( player ) : m_hHumans.AddToTail( player );
	}

	DevMsg(1,"humans %d aliens %d\n capture time %.2f offset %.2f", m_hHumans.Count(), m_hAliens.Count(), m_fCaptured, m_fCapture_time);
	if (m_hAliens.Count() && !m_hHumans.Count() || !m_hAliens.Count() && m_hHumans.Count())
		if (m_fCaptured)
		{
			if (m_fCaptured < gpGlobals->curtime)
			{
				m_nControlled = m_hAliens.Count() ? TEAM_ALIENS : TEAM_HUMANS;	
				Msg("You have just captured the %s\n", m_sLocation.ToCStr());
				SetThink(NULL);
				SetNextThink(0);
			}
		}
		else
			m_fCaptured = gpGlobals->curtime + m_fCapture_time;
	else 
		if (m_fCaptured)
		{
			Msg("Fuck He's Here!\n");
			m_fCaptured = 0;
		}
}

FGD Entry

@include "base.fgd"

//-------------------------------------------------------------------------
//
// Push Point Map Entity
//
//-------------------------------------------------------------------------
@SolidClass base(Targetname) = push_block : "Push Entity Brush."
[
    // Mapping Tagged Fields
	next(string) : "Next Objective" : "" : "Set this to the next objective's name."
	prev(string) : "Previous Objective" : "" : "Set this to the previous objective's name."
    location(string) : "Location" : "" : "Set this to the name of this location to be echoed."
	timer(float) : "Time To Capture" : "1.0" : "Set this to the time it takes to capture this point."

	// Alien Outputs
	output OnAlienCapture(void) : "Fired when the Aliens team captures this point."
	output OnAlienStartTouch(void) : "Fired when the Aliens team touches this point, if this point has not been captured."
	output OnAlienEndTouch(void) : "Fired when the Aliens team stops touching this point, if this point has not been captured."

	// Human Outputs
	output OnHumanCapture(void) : "Fired when the Humans team captures this point."
	output OnHumanStartTouch(void) : "Fired when the Humans team touches this point, if this point has not been captured."
	output OnHumanEndTouch(void) : "Fired when the Humans team stops touching this point, if this point has not been captured."

	// Misc. Outputs
	output OnCapture(void) : "Fired when this point is captured."
	output OnStartTouch(void) : "Fired when this point is touched, if this point has not been captured."
	output OnEndTouch(void) : "Fired when a player stops touching this point, if this point has not been captured."
]

Contact me as needed

Full tutorial is possibly going to be on my site if this post is frequented enough to give me cause enough to write it.

ImaTard 04:14, 10 Feb 2006 (PST)