This member has provided no bio about themself...

Report RSS ScrGold/Coding: HL1 Flamethrower Experiement

Posted by on

weapon.h
//=========================================================
// Flamethrower
//=========================================================
class CFlamethrower : public CBasePlayerWeapon
{
public:

void Spawn( void );
void Precache( void );
int iItemSlot( void ) { return 2; }
int GetItemInfo(ItemInfo *p);
int AddToPlayer( CBasePlayer *pPlayer );
void PrimaryAttack( void );

void StartThrow (void);
void Throw (void);
void StopThrow(void);

BOOL Deploy( void );
void Holster( int skiplocal = 0 );
void WeaponIdle( void );
void UpdateTrace( void );

float m_flThrowTime;
int m_iStartThrow;
int m_iThrowCount;
int m_iFlameRange;
//int m_iFlameSprite;

virtual BOOL UseDecrement( void )
{
#if defined( CLIENT_WEAPONS )
return TRUE;
#else
return FALSE;
#endif
}

private:
unsigned short m_usThrowerFire;
unsigned short m_usThrowerStop;
unsigned short m_usThrowerFlame;
};

//=========================================================
// Flamethrower FireBall
//=========================================================
class CFireBall : public CBaseMonster
{
public:
int Save( CSave &save );
int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[]; //weapon.cpp
void Spawn( void );
void Precache( void );
void EXPORT AnimateThink( void );
void Smoke( void );
void Damage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType );
void EXPORT TouchThink( CBaseEntity *pOther );
static CFireBall *CreateFireBall( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, CFlamethrower *pLauncher );

private:
int m_iFlametrail;
int m_maxFrame;
float m_flFlameTime;
CFlamethrower *m_pLauncher;// pointer back to the launcher that fired me. MAYBE NOT NEEDED
};

flamethrower.cpp
//=========================================================
// Flamethrower
//=========================================================
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "player.h"
#include "gamerules.h"
#include "decals.h"
#include "effects.h"
#include "customentity.h"

#define FIRE_BALL_SPRITE "sprites/fireball01.spr" //"sprites/flameball.spr"
#define FIRE_BALL_SPRITE2 "sprites/fireball02.spr" //"sprites/flameball.spr"
#define FIRE_BALL_SPRITE3 "sprites/fireball03.spr" //"sprites/flameball.spr"
#define FIRE_BEAM_SPRITE "sprites/xbeam3.spr"
extern DLL_GLOBAL short g_sModelIndexSteam;
//#define SMOKE_BALL_SPRITE "sprites/stmbal1.spr"

enum flamethrower_e {
FLAME_IDLE1 = 0,
FLAME_START_SHOOT,
FLAME_SHOOT,
FLAME_STOP_SHOOT,
FLAME_DRAW,
FLAME_HOLSTER, //no animation
};

//EGON ANIMATION

//enum flamethrower_e {
// FLAME_IDLE1 = 0,
// FLAME_FIDGET,
// FLAME_FIREON,
// FLAME_FIRECYCLE,
// FLAME_FIREOFF,
// FLAME_FIRE1, //no animation
// FLAME_FIRE2, //no animation
// FLAME_FIRE3,
// FLAME_FIRE4,
// FLAME_DRAW,
// FLAME_HOLSTER
//};

#ifndef CLIENT_DLL
//=========================================================
// Flamethrower FlameBall
//=========================================================

LINK_ENTITY_TO_CLASS( ft_fireball, CFireBall );

void CFireBall :: Spawn( void )
{
Precache( );
pev->classname = MAKE_STRING("ft_fireball");
pev->movetype = MOVETYPE_FLY; //MOVETYPE_FLY;
pev->solid = SOLID_BBOX;
//pev->effects = EF_BRIGHTLIGHT; //only a test

switch ( RANDOM_LONG( 0, 2 ) )
{
case 0:
SET_MODEL(ENT(pev), FIRE_BALL_SPRITE);
break;
case 1:
SET_MODEL(ENT(pev), FIRE_BALL_SPRITE2);
break;
case 2:
SET_MODEL(ENT(pev), FIRE_BALL_SPRITE3);
break;
}

pev->rendermode = kRenderTransAdd;
pev->renderamt = 255;
pev->avelocity.z = RANDOM_FLOAT(-180,180);
pev->scale = RANDOM_FLOAT( 0.10, 0.15); //0.30;
pev->frame = 0;

// flame trail
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_BEAMFOLLOW );
WRITE_SHORT(entindex()); // entity
WRITE_SHORT(m_iFlametrail ); // model
WRITE_BYTE( 2 ); // life
WRITE_BYTE( 10 ); // width
WRITE_BYTE( 205 ); // r, g, b
WRITE_BYTE( 147 ); // r, g, b
WRITE_BYTE( 49 ); // r, g, b
WRITE_BYTE( 225 ); // brightness
MESSAGE_END(); // move PHS/PVS data sending into here (SEND_ALL, SEND_PVS, SEND_PHS)

UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));

//pev->velocity = gpGlobals->v_forward * RANDOM_FLOAT( 600, 750); //700;
m_flFlameTime = gpGlobals->time;

m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1;
pev->dmg = gSkillData.plrDmgFlame;

}

//test
void CFireBall :: Damage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType )
{
CBaseEntity *pEntity = NULL;
TraceResult tr;
float flAdjustedDamage, falloff;
Vector vecSpot;

if ( flRadius )
falloff = flDamage / flRadius;
else
falloff = 1.0;

int bInWater = (UTIL_PointContents ( vecSrc ) == CONTENTS_WATER);

vecSrc.z += 1;// in case grenade is lying on the ground

if ( !pevAttacker )
pevAttacker = pevInflictor;

// iterate on all entities in the vicinity.
while ((pEntity = UTIL_FindEntityInSphere( pEntity, vecSrc, flRadius )) != NULL)
{
if ( pEntity->pev->takedamage != DAMAGE_NO )
{
// UNDONE: this should check a damage mask, not an ignore
if ( iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore )
{// houndeyes don't hurt other houndeyes with their attack
continue;
}

// blast's don't tavel into or out of water
if (bInWater && pEntity->pev->waterlevel == 0)
continue;
if (!bInWater && pEntity->pev->waterlevel == 3)
continue;

vecSpot = pEntity->BodyTarget( vecSrc );

UTIL_TraceLine ( vecSrc, vecSpot, dont_ignore_monsters, ENT(pevInflictor), &tr );

if ( tr.flFraction == 1.0 || tr.pHit == pEntity->edict() )
{// the explosion can 'see' this entity, so hurt them!
if (tr.fStartSolid)
{
// if we're stuck inside them, fixup the position and distance
tr.vecEndPos = vecSrc;
tr.flFraction = 0.0;
}

// decrease damage for an ent that's farther from the bomb.
flAdjustedDamage = ( vecSrc - tr.vecEndPos ).Length() * falloff;
flAdjustedDamage = flDamage - flAdjustedDamage;

if ( flAdjustedDamage < 0 )
{
flAdjustedDamage = 0;
}

// ALERT( at_console, "hit %s\n", STRING( pEntity->pev->classname ) );
if (tr.flFraction != 1.0)
{
ClearMultiDamage( );
pEntity->TraceAttack( pevInflictor, flAdjustedDamage, (tr.vecEndPos - vecSrc).Normalize( ), &tr, bitsDamageType );
ApplyMultiDamage( pevInflictor, pevAttacker );
}
else
{
pEntity->TakeDamage ( pevInflictor, pevAttacker, flAdjustedDamage, bitsDamageType );
}
}
}
}
}

void CFireBall :: AnimateThink( void )
{
if( UTIL_PointContents(pev->origin) == CONTENTS_WATER )
{
Smoke();
SetThink ( &CBaseEntity::SUB_Remove );
pev->nextthink = gpGlobals->time;
}

//if( UTIL_PointContents(pev->origin) == CONTENTS_SLIME || CONTENTS_LAVA )
//{
// pev->velocity = 0;
//}

pev->nextthink = gpGlobals->time + 0.05;
pev->velocity = pev->velocity * 0.97;
pev->scale = pev->scale += 0.04;

//CBaseEntity *pHurt = CheckTraceHullAttack( 32, 1, DMG_BURN ); //works, but not perfect
entvars_t *pevOwner;
if ( pev->owner )
pevOwner = VARS( pev->owner );
else
pevOwner = NULL;

pev->owner = NULL; // can't traceline attack owner if this is set

if ( gpGlobals->time - m_flFlameTime >= 0.1 )
{
Damage( pev->origin, pev, pev, 1, pev->scale * 64, CLASS_NONE, DMG_BURN );
}

//if ( RANDOM_FLOAT( 0.0 , 0.6 ) + ( gpGlobals->time - m_flFlameTime ) >= 0.9 )
//{
// Smoke();
//}

if ( pev->frame++ || gpGlobals->time - m_flFlameTime > 0.90)
{
if ( pev->frame > m_maxFrame || gpGlobals->time - m_flFlameTime > 0.90 ) //pev->frame > m_maxFrame ||
{
pev->frame = m_maxFrame;
SetThink ( &CBaseEntity::SUB_Remove );
pev->nextthink = gpGlobals->time;
}
}

if ( gpGlobals->time - m_flFlameTime >= 0.3 )
{
//pev->velocity = pev->velocity / RANDOM_FLOAT( 2,3);
if ( pev->movetype != MOVETYPE_TOSS )
{
pev->movetype = MOVETYPE_TOSS;
pev->gravity = RANDOM_FLOAT( 0.4 , 0.5 );
//pev->gravity = RANDOM_FLOAT(-4,-1);
}

}
}

void CFireBall :: Smoke( void )
{
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
WRITE_BYTE( TE_SMOKE );
WRITE_COORD( pev->origin.x + RANDOM_FLOAT( -16, 16 ));
WRITE_COORD( pev->origin.y + RANDOM_FLOAT( -16, 16 ));
WRITE_COORD( pev->origin.z + RANDOM_FLOAT( 32, 16 ));
WRITE_SHORT( g_sModelIndexSteam );
WRITE_BYTE( RANDOM_FLOAT( 32 , 36 ));
WRITE_BYTE( 35 ); // framerate
MESSAGE_END();
}

void CFireBall :: Precache( void )
{
PRECACHE_MODEL( FIRE_BALL_SPRITE );
PRECACHE_MODEL( FIRE_BALL_SPRITE2 );
PRECACHE_MODEL( FIRE_BALL_SPRITE3 );
m_iFlametrail = PRECACHE_MODEL("sprites/smoke.spr");
}

CFireBall *CFireBall::CreateFireBall( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, CFlamethrower *pLauncher )
{
CFireBall *pFireBall = GetClassPtr( (CFireBall *)NULL );

UTIL_SetOrigin( pFireBall->pev, vecOrigin );
pFireBall->pev->angles = vecAngles;
pFireBall->Spawn();
pFireBall->SetTouch( &CFireBall :: TouchThink );
pFireBall->m_pLauncher = pLauncher;// remember what RPG fired me.
pFireBall->pev->owner = pOwner->edict();
pFireBall->pev->nextthink = gpGlobals->time;
pFireBall->SetThink( &CFireBall::AnimateThink );

return pFireBall;
}

void CFireBall :: TouchThink ( CBaseEntity *pOther )
{
TraceResult tr;

if ( !pOther->pev->takedamage )
{
return;
}
else
{
return;
}
//if ( pOther->pev->health <= 0 )
// return;
//pOther->TakeDamage ( pev, pev, gSkillData.plrDmgFlame, DMG_BURN );
//Boom();
SetThink ( &CBaseEntity::SUB_Remove );
pev->nextthink = gpGlobals->time;
}
#endif

//=========================================================
// Flamethrower
//=========================================================

LINK_ENTITY_TO_CLASS( weapon_flamethrower, CFlamethrower );

void CFlamethrower::Spawn( )
{
//pev->classname = MAKE_STRING("weapon_flamethrower"); // hack to allow for old names
Precache( );
m_iId = WEAPON_FLAMETHROWER;
SET_MODEL(ENT(pev), "models/w_flamethrower.mdl");

m_iDefaultAmmo = FLAMETHROWER_DEFAULT_GIVE;

FallInit();// get ready to fall down.
}

void CFlamethrower::Precache( void )
{
PRECACHE_MODEL("models/v_flamethrower.mdl");
PRECACHE_MODEL("models/w_flamethrower.mdl");
PRECACHE_MODEL("models/p_flamethrower.mdl");

PRECACHE_MODEL("sprites/flame_idle.spr");

PRECACHE_MODEL( FIRE_BEAM_SPRITE );

PRECACHE_SOUND("items/9mmclip1.wav");

UTIL_PrecacheOther( "ft_fireball" );

PRECACHE_SOUND ("weapons/357_cock1.wav");

m_usThrowerFire = PRECACHE_EVENT( 1, "events/thrower_start.sc" );
m_usThrowerStop = PRECACHE_EVENT( 1, "events/thrower_stop.sc" );
m_usThrowerFlame = PRECACHE_EVENT( 1, "events/thrower_flame.sc" );
}

int CFlamethrower::GetItemInfo(ItemInfo *p)
{
p->pszName = STRING(pev->classname);
p->pszAmmo1 = "uranium";
p->iMaxAmmo1 = URANIUM_MAX_CARRY;
p->pszAmmo2 = NULL;
p->iMaxAmmo2 = -1;
p->iMaxClip = WEAPON_NOCLIP;
p->iSlot = 5;
p->iPosition = 1;
p->iId = m_iId = WEAPON_FLAMETHROWER;
p->iFlags = 0;
p->iWeight = FLAMETHROWER_WEIGHT;

return 1;
}

int CFlamethrower::AddToPlayer( CBasePlayer *pPlayer )
{
if ( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
{
MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
WRITE_BYTE( m_iId );
MESSAGE_END();
return TRUE;
}
return FALSE;
}

BOOL CFlamethrower::Deploy( )
{
return DefaultDeploy( "models/v_flamethrower.mdl", "models/p_flamethrower.mdl", FLAME_DRAW, "shotgun" );
}

void CFlamethrower::Holster( int skiplocal /* = 0 */ )
{
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 16/30;
SendWeaponAnim( FLAME_HOLSTER );
}
void CFlamethrower::PrimaryAttack()
{
// don't fire underwater
if (m_pPlayer->pev->waterlevel == 3)
{
PlayEmptySound( );
m_flNextPrimaryAttack = 0.15;
return;
}

int flags;
#if defined( CLIENT_WEAPONS )
flags = FEV_NOTHOST;
#else
flags = 0;
#endif

if ( m_iStartThrow == 1 )
{
if ( gpGlobals->time - m_flThrowTime >= 0.2 )
{
Throw();
}
else
{
//StartThrow();
Throw();
//m_iFlameRange = m_iFlameRange + 12;
}
}
else
{
//StartThrow();
Throw();
m_flThrowTime = gpGlobals->time;
m_iStartThrow = 1;
m_iThrowCount = 0;
//m_iFlameRange = m_iFlameRange + 12;
}

m_flTimeWeaponIdle = m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.03;
}

void CFlamethrower::StartThrow()
{
#ifndef CLIENT_DLL
ALERT ( at_console, "start throwing \n" );
#endif
}

void CFlamethrower::Throw()
{
float degree = 0.03;
Vector vecAiming = gpGlobals->v_forward;
Vector vecDir = gpGlobals->v_forward + Vector( RANDOM_FLOAT( -degree, degree ), RANDOM_FLOAT( -degree, degree ), RANDOM_FLOAT( -degree, degree ) );

if ( m_iStartThrow == 0 && m_iFlameRange != 38 )
m_iFlameRange = 38;

UTIL_MakeVectors( m_pPlayer->pev->v_angle );

//m_pPlayer-> // if player crouched??
Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_right * 4 + gpGlobals->v_up * -8; // + gpGlobals->v_up * -9; //+ gpGlobals->v_forward * 32

TraceResult tr;
UTIL_TraceLine ( vecSrc, vecSrc + vecAiming * m_iFlameRange, dont_ignore_monsters, ENT(m_pPlayer->pev), &tr );

#ifndef CLIENT_DLL
ALERT ( at_console, "throwing \n" );
CFireBall *pFireBall = CFireBall::CreateFireBall( tr.vecEndPos, m_pPlayer->pev->v_angle, m_pPlayer, this );//+ gpGlobals->v_right * RANDOM_FLOAT(-5,5) + gpGlobals->v_up * RANDOM_FLOAT(-5,5)

UTIL_MakeVectors( m_pPlayer->pev->v_angle );// RpgRocket::Create stomps on globals, so remake.
//pRocket->pev->velocity = pRocket->pev->velocity + gpGlobals->v_forward * DotProduct( m_pPlayer->pev->velocity, gpGlobals->v_forward );
pFireBall->pev->velocity = ( vecDir * RANDOM_FLOAT( 600, 750) ) + ( gpGlobals->v_forward * DotProduct( m_pPlayer->pev->velocity, gpGlobals->v_forward ) ); //throw direction + random speed + speed of player
#endif
}

void CFlamethrower::StopThrow()
{
#ifndef CLIENT_DLL
ALERT ( at_console, "stop throwing \n" );
#endif

m_flThrowTime = 0;
m_iStartThrow = 0;
m_iThrowCount = 0;
}

void CFlamethrower::WeaponIdle( void )
{
ResetEmptySound( );

m_pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );

if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase() )
return;

if ( m_iStartThrow == 1 )
{
StopThrow();
}

int iAnim;
switch ( RANDOM_LONG( 0, 1 ) )
{
case 0:
iAnim = FLAME_IDLE1;
break;

default:
case 1:
iAnim = FLAME_IDLE1;
break;
}

SendWeaponAnim( iAnim );
}

Post a comment
Sign in or join with:

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.

Level
96%
Gamer
7
Avatar
Avatar
Last Online
Country
Germany Germany
Gender
Male
Friends
Become friends
Member watch
Follow
Blog
Browse
Blogs
Report
Report
Views
81 (1 today)
Share
Got it!

We have recently updated our privacy policy and terms of use in-line with GDPR requirements. More Info?