Push Gameplay: Difference between revisions
Jump to navigation
Jump to search
mNo edit summary |
mNo edit summary |
||
Line 1: | Line 1: | ||
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 == | |||
<pre>//========= 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; | |||
} | |||
}</pre> | |||
== FGD Entry == | |||
<pre>@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." | |||
] | |||
</pre> |
Revision as of 05:13, 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." ]