Check out Half-Life Re-imagined competition results!
Check out Skewing textures in Hammer, our newest tutorial!
Welcome, fighter667, our newest member!

logo

Site Stuff

Reference

Maps

Community

ShoutBOX

Poll

Feeling Blue

What's your favourite shade of blue?

Azure

14

Cobalt

32

Turquoise

9

Cyan

10

Royal

8

Teal

3

Onliners

2 mins

Ghost129er

10 mins

Suparsonik

14 mins

NineTnine

32 mins

Crollo

35 mins

Jessie

59 mins

Solokiller

1 hours

Penguinboy

Affiliates

A gaming and technology blog by TWHL admins Penguinboy and Ant. A music blog by TWHL users Ant and Hugh.

Making A Player Fly

By Stephan

This is a tutorial teaching you how to make a flying system in half-life. This is my first real tutorial. Thanks to Mr. Pinstripe Suit for the code. Lets start shall we?

This article uses the following format to separate new code from old code:

Old code
New code

Ok start by going to const.h around line 80 You should see

#define MOVETYPE_FOLLOW	12
#define MOVETYPE_PUSHSTEP	13

Add:

#define MOVETYPE_NEW_FLY	14

This Will be our new flying move type.

Ok Now close that and open pm_shared.h. You should see:
char PM_FindTextureType( char *name );

Add:

void PM_NewFly (void);

Close that and open pm_shared.c. Go to the end and add

void PM_NewFly(void)
{
	
}

Now go to somewhere around line 1320 and copy all of the code from PM_WaterMove into PM_NewFly(void). Now look in your new function and you should see code like this

// Sinking after no other movement occurs
if (!pmove->cmd.forwardmove && !pmove->cmd.sidemove && !pmove->cmd.upmove)
wishvel[2] -= 60;// drift towards bottom
else  // Go straight up by upmove amount.
	wishvel[2] += pmove->cmd.upmove;

Either comment this out or delete it because we dont want our player "sinking" because hes not in water hes in the air.

Now under that you should see:

wishspeed *= .8;

Change to:

wishspeed *= .9;

This way hes goes at 90% of full speed instead of 80%.

Now go to PM_Physics_Toss() at about line 2440 and you should see:

if ( pmove->movetype != MOVETYPE_FLY &&
pmove->movetype != MOVETYPE_BOUNCEMISSILE &&
pmove->movetype != MOVETYPE_FLYMISSILE) PM_AddGravity ();

Change it to:

if ( pmove->movetype != MOVETYPE_FLY &&
pmove->movetype != MOVETYPE_BOUNCEMISSILE &&
pmove->movetype != MOVETYPE_FLYMISSILE
&&
pmove->movetype != MOVETYPE_NEW_FLY
) PM_AddGravity ();

This way it doesnt add gravity to the player making him fall.

Now go to PM_PlayerMove() at around line 3085 and you should see:

if ( pLadder )
{
	PM_LadderMove( pLadder );
}
else if ( pmove->movetype != MOVETYPE_WALK &&
pmove->movetype != MOVETYPE_NOCLIP)
{
	// Clear ladder stuff unless player is noclipping
	//  it will be set immediately again next frame if necessary
	pmove->movetype = MOVETYPE_WALK;
}

Change to:

if ( pLadder )
{
	PM_LadderMove( pLadder );
}
else if ( pmove->movetype != MOVETYPE_WALK &&
pmove->movetype != MOVETYPE_NOCLIP &&
pmove->movetype != MOVETYPE_NEW_FLY)
{
	// Clear ladder stuff unless player is noclipping
	//  it will be set immediately again next frame if necessary
	pmove->movetype = MOVETYPE_WALK;
}

Ok now go down till you see:

switch ( pmove->movetype )
{
default:
pmove->Con_DPrintf("Bogus pmove player movetype %i on (%i) 0=cl 1=sv\n",
 pmove->movetype,
 pmove->server);
		break;

case MOVETYPE_NONE:
		break;
	.....

Now add ours:

switch ( pmove->movetype )
{
default:
pmove->Con_DPrintf("Bogus pmove player movetype %i on (%i) 0=cl 1=sv\n",
 pmove->movetype,
 pmove->server);
		break;

case MOVETYPE_NONE:
	break;
	
case MOVETYPE_NEW_FLY:
	PM_NewFly();
	break;

Ok so now whenever it checks to see what movement type the player is if its our new fly it sends it to the new fly function.

So now to make a player fly you would just set pev->movetype = MOVETYPE_NEW_FLY

Heres how you would use it if you wanted a button bound to make you fly or walk (warning this part is not cut and paste! You do need to think a little),

Go to client.cpp then go down to client command around line 355 and you should see something in there like:

else if ( FStrEq(pcmd, "use" ) )
{
GetClassPtr((CBasePlayer *)pev)->SelectItem((char *)CMD_ARGV(1));
}

Now add something like this:

else if (FStrEq(pcmd, "startfly" ) )
{

if (GetClassPtr((CBasePlayer *)pev)->IsFlying)
{
ALERT ( at_console, "Damn gravity! \n" );
GetClassPtr((CBasePlayer *)pev)->IsFlying = false;
GetClassPtr((CBasePlayer *)pev)->BeginFly();
}
else if (!(GetClassPtr((CBasePlayer *)pev)->IsFlying))
{
if (GetClassPtr((CBasePlayer *)pev)->m_iEP > 1500)
{
GetClassPtr((CBasePlayer *)pev)->pev->velocity.z += 20;
ALERT ( at_console, "Look Im flying! \n" );
GetClassPtr((CBasePlayer *)pev)->IsFlying = true;
GetClassPtr((CBasePlayer *)pev)->BeginFly();
}
else
{
ClientPrint( &pEntity->v, HUD_PRINTCENTER, "Need 1500 EP to fly" );
}
}
}

Then the function getting called I have in the player.cpp

void CBasePlayer::BeginFly( void )
{
if(IsFlying) 
{
pev->movetype = MOVETYPE_NEW_FLY;
ClearBits (pev->flags , FL_ONGROUND);
SetBits (pev->flags, FL_FLY);
pev->gravity = 0.000;
}
else
{
pev->movetype = MOVETYPE_WALK;
SetBits (pev->flags , FL_ONGROUND);
ClearBits (pev->flags, FL_FLY);
pev->gravity = 1;
}
}
So up there it checks if he's flying and if he's not it makes him fly. If hes flying it makes him walk. That extra else is to check if he has enough Expirence points. Now I dont think you have that in your mod but its just there to show you some uses. Well thats about it a lot less harder then I thought it would be. Well really its just a hack but works good.

Any questions or suggestions should be sent to : gimli@jrrclan.com