Push Gameplay
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." ]