Welcome, Guest! Login | Register

CTF Gameplay Part 1 [Print this Article]
Posted by: DarkNight
Date posted: Apr 14 2003
User Rating: 5 out of 5.0
Number of views: 6376
Number of comments: 3
Description: Creating the Flag Entity
This part of the tutorial will show you how to create the Flag entity for the CTF Gamerules.

NOTE: This code will need modifying to suit your team system,ect so don't take this as a complete C&P (which it basically is).


Ok firstly create a header file called ctf_gameplay.h and put the following in it:

 CODE (C++) 

// Status of the flag
#define FLAG_STOLEN 1
#define FLAG_CAPTURE    2
#define FLAG_DROPPED    3

// Our flag class which holds all our functions and variables we're going to use

class CObjectFlag : public CBaseEntity
{
public:
    void Spawn( );
    void Precache( );
    void Touch(CBaseEntity *);
    bool m_fIsInPlay;
};

// The Flag entity that is dropped by a player when killed/disconnected/whatnot
class CDroppedFlag : public CBaseEntity
{
public:
    void Spawn( );
    void Precache( );
    void Touch(CBaseEntity *);
};


In player.h, put the following in class CBasePlayer : public CBaseMonster in the publics:

 CODE (C++) 
bool m_fHasObject;


Next make a file called ctf_gameplay.cpp and put the following in it:

 CODE (C++) 

// includes needed for everything to compile
#include "extdll.h"
#include "decals.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "player.h"
#include "soundent.h"
#include "shake.h"
#include "gamerules.h"
#include "ctf_object.h"
#include "teamplay_gamerules.h"

LINK_ENTITY_TO_CLASS( object_flag, CObjectFlag );

void CObjectFlag :: Spawn( )
{
    // Calls the precache function to precache any models, sounds,ect you need
    //before it spawns
    Precache( );
    // Setup what model we want to use for the flag, change this to
    // whatever you want. Just remember precache it.
    SET_MODEL( ENT(pev), "models/flag.mdl" );
   
    UTIL_SetOrigin( pev, pev->origin + Vector(0,0,10) );
    UTIL_SetSize( pev, Vector(-16,-16,0), Vector(16,16,16) );

    // This is so it falls to the brush below it
    pev->movetype = MOVETYPE_TOSS;

    // This allows you to trigger it by walking through it
    pev->solid = SOLID_TRIGGER;

    // This just sets our Touch to Touch, which is down a little further
    SetTouch(Touch);

    // This just makes a GlowShell around the model, you can
    // change the colour of the shell by changing the RGB values,
    // which are the XYZ values in this case. So at the moment we have
    // a nice bright red colour. Feel free to change this to your needs.
    pev->renderfx = kRenderFxGlowShell;
    pev->rendercolor.x = 255;
    pev->rendercolor.y = 0;
    pev->rendercolor.z = 0;
    pev->renderamt = 10; // 10 units off the sides of the model

    // This just sets our IsInPlay bool to false, because its only just spawned and
    // no one has picked it up yet.
    m_fIsInPlay = false;
}

// This is the Precache function which is called from the Spawn function.

void CObjectFlag :: Precache( )
{
    // Precache's the model
    PRECACHE_MODEL( "models/flag.mdl" );
}

// This is the Touch function which was set above, in the Spawn function,
// its basically the stuff that runs when the flag has been touched by a player

void CObjectFlag :: Touch(CBaseEntity *pOther)
{
    // If its in play, do nothing
    if(m_fIsInPlay)
        return;

    // Determine if the object that touches it, is a player
    // and check if the player is alive.
    if(!pOther)
         return;
    if(!pOther->IsPlayer())
         return;
    if(!pOther->IsAlive())
         return;

    CBasePlayer *pPlayer = (CBasePlayer *)pOther;

    // Print to the HUD who has taken the flag
    UTIL_ClientPrintAll( HUD_PRINTCENTER, UTIL_VarArgs( "%s has the Flag!\n", STRING( pPlayer->pev->netname )));
   
    pPlayer->m_fHasObject = true;

    // Set the client attachment using an event
    PLAYBACK_EVENT_FULL(0, pPlayer->edict(), g_usObject, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, FLAG_STOLEN, 0, 0, 0);

    m_fIsInPlay = true;

    // Give the illusion of the player taking the model by not drawing it
    pev->effects = EF_NODRAW;

    // Now don't let it accept any more touch's
    SetTouch(NULL);
}


 CODE (C++) 

// This is the Flag that is dropped by a player when killed,disconnected,ect.
// Its basically the same as CObjectFlag, with a few changes.

LINK_ENTITY_TO_CLASS( dropped_flag, CDroppedFlag );

void CDroppedFlag :: Spawn( )
{
    // Calls the precache function to precache any models or sounds,ect
    // you need before it spawns.
    Precache( );

    // Setup what model we want to use for the flag, change this to
    // whatever you want. Just remember precache it.
    SET_MODEL( ENT(pev), "models/flag.mdl" );
   
    UTIL_SetOrigin( pev, pev->origin );
    UTIL_SetSize( pev, Vector(-16,-16,0), Vector(16,16,16) );

    // This is so it falls to the brush below it
    pev->movetype = MOVETYPE_TOSS;

    // This allows you to trigger it by walking through it
    pev->solid = SOLID_TRIGGER;

    // This just sets our Touch to Touch, which is down a little further
    SetTouch(Touch);

    // This just makes a GlowShell around the model, you can
    // change the colour of the shell by changing the RGB values,
    // which are the XYZ values in this case. So at the moment we have
    // a nice bright red colour. Feel free to change this to your needs.
    pev->effects = EF_BRIGHTFIELD;
    pev->renderfx = kRenderFxGlowShell;
    pev->rendercolor.x = 255;
    pev->rendercolor.y = 0;
    pev->rendercolor.z = 0;
    pev->renderamt = 10; // 10 units off the sides of the model
    pev->avelocity.z = 25;
}

// This is the Precache function which is called from the Spawn function.

void CDroppedFlag :: Precache( )
{
    // Precache's the model
    PRECACHE_MODEL( "models/flag.mdl" );
}

// This is the Touch function which was set above, in the Spawn function,
// its basically the stuff that runs when the flag has been touched by a player.

void CDroppedFlag :: Touch(CBaseEntity *pOther)
{
    // Determine if the object that touches it, is a player
    // and check if the player is alive.
    if(!pOther)
         return;
    if(!pOther->IsPlayer())
         return;
    if(!pOther->IsAlive())
         return;

    CBasePlayer *pPlayer = (CBasePlayer *)pOther;

    // Print to the HUD who has taken the flag
    UTIL_ClientPrintAll( HUD_PRINTCENTER, UTIL_VarArgs( "%s has the Flag!\n", STRING( pPlayer->pev->netname )));

    // Set it to true because the player has the flag
    pPlayer->m_fHasObject = true;

    // Set the client attachment using an event
    PLAYBACK_EVENT_FULL(0, pPlayer->edict(), g_usObject, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, FLAG_STOLEN, 0, 0, 0);

    // remove this item
    SetThink(SUB_Remove);

    // next think time to now!
    pev->nextthink = gpGlobals->time;
}


Now in teamplay_gamerules in, void CHalfLifeTeamplay :: PlayerKilled put the following:
 CODE (C++) 
    // If they have the flag, drop it.
    if( pVictim->m_fHasObject )
    {
         // Print to HUD who has dropped the flag
         UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s has dropped the Flag!\n", STRING( pPlayer->pev->netname )));

         // Creates the flag entity in the direction the player is facing
         CDroppedFlag *pFlag = (CDroppedFlag *)CBaseEntity::Create("dropped_flag", pVictim->pev->origin, pVictim->pev->angles);

         // Player no longer has flag so set the bool to false
    pVictim->m_fHasObject = false;

         // Update client with what has happened
         PLAYBACK_EVENT_FULL(0, pVictim->edict(), g_usObject, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, FLAG_DROPPED, 0, 0, 0);
    }


Now in multiplay_gamerules.cpp in,
void CHalfLifeMultiplay :: ClientDisconnected( edict_t *pClient ) put the following below this part:
 CODE (C++) 
if ( pClient )
{
    CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance( pClient );


 CODE (C++) 
    // If they have the flag, drop it
if( pPlayer->m_fHasObject )
{
    // Print to HUD who has dropped the flag
    UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s has dropped the Flag!\n", STRING( pPlayer->pev->netname )));

    // Creates the flag entity in the direction the player is facing
    CDroppedFlag *pFlag = (CDroppedFlag *)CBaseEntity::Create("dropped_flag", pPlayer->pev->origin, pPlayer->pev->angles);

    // Player no longer has flag so set the bool to false
    pPlayer->m_fHasObject = false;

    // Update client with what has happened
    PLAYBACK_EVENT_FULL(0, pPlayer->edict(), g_usObject, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, FLAG_DROPPED, 0, 0, 0);

}




Now in weapons.cpp find, DLL_GLOBAL short g_sModelIndexBloodSpray; and put the following after it:
 CODE (C++) 
    DLL_GLOBAL unsigned short g_usObject; // object capture/taken event

Now find g_sModelIndexBloodSpray = PRECACHE_MODEL ("sprites/bloodspray.spr");
and put the following after it:

 CODE (C++) 
    g_usObject = PRECACHE_EVENT(1, "events/object.sc");


Now in weapons.h fine, extern DLL_GLOBAL short g_sModelIndexBloodSpray; and put the following after it:
 CODE (C++) 
    extern DLL_GLOBAL unsigned short g_usObject; // object capture/stolen event

Rate This Article
This article is currently rated: 5 out of 5.0 (2 Votes)

You have to register to rate this article.
User Comments Showing comments 1-3

Posted By: AlperiNi on Jul 23 2005 at 00:19:25
Where I can find ctf_objects.h?

Posted By: deedok on Aug 20 2007 at 18:18:28
whe are ctf_objects.h?

Posted By: DarkNight on Aug 28 2007 at 07:06:31
ctf_object.h is actually ctf_gameplay.h I think. It was a very long time ago I posted this and I think some header names and variables don't match all the way through, but its very simple to fix those if you can code. Just look at the code and include the header that has the class definition in it.


You must register to post a comment. If you have already registered, you must login.

Latest Articles
3rd person View in Multiplayer
Half-Life 2 | Coding | Client Side Tutorials
How to enable it in HL2DM

By: cct | Nov 13 2006

Making a Camera
Half-Life 2 | Level Design
This camera is good for when you join a map, it gives you a view of the map before you join a team

By: slackiller | Mar 05 2006

Making a camera , Part 2
Half-Life 2 | Level Design
these cameras are working monitors that turn on when a button is pushed.

By: slackiller | Mar 04 2006

Storing weapons on ladder
Half-Life 2 | Coding | Snippets
like Raven Sheild or BF2

By: British_Bomber | Dec 24 2005

Implementation of a string lookup table
Half-Life 2 | Coding | Snippets
A string lookup table is a set of functions that is used to convert strings to pre-defined values

By: deathz0rz | Nov 13 2005


Latest Comments
knock knock
General | News
By: omega | Dec 22 2016
 
knock knock
General | News
By: MIFUNE | Oct 10 2015
 
New HL HUD Message System
Half-Life | Coding | Shared Tutorials
By: chbrules | Dec 31 2011
 
knock knock
General | News
By: Whistler | Nov 05 2011
 
Particle Engine tutorial part 4
Half-Life | Coding | Client Side Tutorials
By: darkPhoenix | Feb 18 2010
 
Particle Engine tutorial part 2
Half-Life | Coding | Client Side Tutorials
By: darkPhoenix | Feb 11 2010
 
Particle Engine tutorial part 3
Half-Life | Coding | Client Side Tutorials
By: darkPhoenix | Feb 11 2010
 
Game Movement Series #2: Analog Jumping and Floating
Half-Life 2 | Coding | Shared Tutorials
By: mars3554 | Oct 26 2009
 
Particle Engine tutorial part 5
Half-Life | Coding | Client Side Tutorials
By: Deadpool | Aug 02 2009
 
Particle Engine tutorial part 5
Half-Life | Coding | Client Side Tutorials
By: Persuter | Aug 02 2009
 

Site Info
297 Approved Articless
8 Pending Articles
3940 Registered Members
0 People Online (5 guests)
About - Credits - Contact Us

Wavelength version: 3.0.0.9
Valid XHTML 1.0! Valid CSS!