Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

397 lines
9.0 KiB

/*
Copyright (c) 1999, Cold Ice Modification.
This code has been written by SlimShady ( darcuri@optonline.net )
Use, distribution, and modification of this source code and/or resulting
object code is restricted to non-commercial enhancements to products from
Valve LLC. All other use, distribution, or modification is prohibited
without written permission from Valve LLC and from the Cold Ice team.
Please if you use this code in any public form, please give us credit.
*/
#include "extdll.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 "effects.h"
#include "customentity.h"
#define RAILGUN_PRIMARY_FIRE_VOLUME 450
#define RAIL_BEAM_SPRITE "sprites/xbeam1.spr"
enum railgun_e {
GAUSS_IDLE = 0,
GAUSS_IDLE2,
GAUSS_FIDGET,
GAUSS_SPINUP,
GAUSS_SPIN,
GAUSS_FIRE,
GAUSS_FIRE2,
GAUSS_HOLSTER,
GAUSS_DRAW
};
class CRailgun : public CBasePlayerWeapon
{
public:
void Spawn( void );
void Precache( void );
int iItemSlot( void ) { return 4; }
int GetItemInfo(ItemInfo *p);
int AddToPlayer( CBasePlayer *pPlayer );
BOOL Deploy( void );
void Holster( void );
void PrimaryAttack( void );
void SecondaryAttack( void );
void WeaponIdle( void );
void StartFire( void );
void Fire( Vector vecOrigSrc, Vector vecDirShooting, float flDamage );
int m_iBalls;
int m_iGlow;
int m_iBeam;
// rail, rail, rail
void CreateTrail(Vector,Vector);
void EXPORT DestroyTrail(void);
void EXPORT UpdateTrail(void);
int current_phase;
CBeam* m_pBeam, *m_inBeam, *m_lBeam;
};
LINK_ENTITY_TO_CLASS( weapon_railgun, CRailgun );
LINK_ENTITY_TO_CLASS( weapon_gauss, CRailgun );
//=========================================================
//=========================================================
void CRailgun::Spawn( )
{
pev->classname = MAKE_STRING("weapon_railgun");
Precache( );
m_iId = WEAPON_RAILGUN;
SET_MODEL(ENT(pev), "models/wmodels/w_railgun.mdl");
m_iDefaultAmmo = RAILGUN_DEFAULT_GIVE;
FallInit();
}
void CRailgun::Precache( void )
{
PRECACHE_MODEL("models/wmodels/w_railgun.mdl");
PRECACHE_MODEL("models/vmodels/v_railgun.mdl");
PRECACHE_MODEL("models/pmodels/p_railgun.mdl");
PRECACHE_SOUND("weapons/railgun1.wav");
PRECACHE_MODEL( RAIL_BEAM_SPRITE );
m_iGlow = PRECACHE_MODEL ( "sprites/blueflare1.spr" );
m_iBalls = PRECACHE_MODEL( "sprites/blueflare1.spr" );
m_iBeam = PRECACHE_MODEL ( "sprites/smoke.spr" );
}
int CRailgun::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;
}
int CRailgun::GetItemInfo(ItemInfo *p)
{
p->pszName = STRING(pev->classname);
p->pszAmmo1 = "slug";
p->iMaxAmmo1 = RAILGUN_MAX_CARRY;
p->pszAmmo2 = NULL;
p->iMaxAmmo2 = -1;
p->iMaxClip = WEAPON_NOCLIP;
p->iSlot = 3;
p->iPosition = 2;
p->iId = m_iId = WEAPON_RAILGUN;
p->iFlags = 0;
p->iWeight = RAILGUN_WEIGHT;
return 1;
}
BOOL CRailgun::Deploy( )
{
return DefaultDeploy( "models/vmodels/v_railgun.mdl", "models/pmodels/p_railgun.mdl", GAUSS_DRAW, "gauss" );
}
void CRailgun::Holster( )
{
m_pPlayer->m_flNextAttack = gpGlobals->time + 0.5;
SendWeaponAnim( GAUSS_HOLSTER );
}
void CRailgun::PrimaryAttack()
{
if (m_pPlayer->pev->waterlevel == 3)
{
PlayEmptySound( );
m_flNextSecondaryAttack = m_flNextPrimaryAttack = gpGlobals->time + 0.15;
return;
}
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] < 2)
{
PlayEmptySound( );
m_pPlayer->m_flNextAttack = gpGlobals->time + 0.5;
return;
}
m_pPlayer->m_iWeaponVolume = LOUD_GUN_VOLUME;
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= 2;
StartFire();
m_flTimeWeaponIdle = gpGlobals->time + 1.0;
m_flNextPrimaryAttack = gpGlobals->time + 1.0;
}
void CRailgun::SecondaryAttack()
{
}
void CRailgun::CreateTrail(Vector a,Vector b)
{
current_phase = 0;
m_pBeam = CBeam::BeamCreate( RAIL_BEAM_SPRITE, 40 );
m_pBeam->PointsInit(a,b);
m_pBeam->SetFlags( BEAM_FSINE );
m_pBeam->SetColor( 0, 113, 230 );
m_pBeam->LiveForTime( 1 );
m_pBeam->SetScrollRate ( 10 );
m_pBeam->pev->spawnflags |= SF_BEAM_TEMPORARY;
m_inBeam = CBeam::BeamCreate( RAIL_BEAM_SPRITE, 20 );
m_inBeam->PointsInit(a,b);
m_inBeam->SetFlags( BEAM_FSINE );
m_inBeam->SetColor( 200, 200, 200 );
m_inBeam->pev->spawnflags |= SF_BEAM_TEMPORARY;
m_inBeam->LiveForTime( 1 );
m_inBeam->SetScrollRate ( 10 );
m_lBeam = CBeam::BeamCreate( RAIL_BEAM_SPRITE, 50 );
m_lBeam->PointsInit(a,b);
m_lBeam->SetFlags( BEAM_FSINE );
m_lBeam->SetColor( 200, 200, 200 );
m_lBeam->SetScrollRate ( 10 );
m_lBeam->pev->spawnflags |= SF_BEAM_TEMPORARY;
m_lBeam->LiveForTime( 1 );
UpdateTrail();
}
void CRailgun::UpdateTrail()
{
m_pBeam->SetNoise( 10 + current_phase * 2 );
m_pBeam->SetBrightness( 200 - current_phase * 20 );
m_inBeam->SetNoise( 5 + current_phase );
m_inBeam->SetBrightness( 200 - current_phase * 20 );
m_lBeam->SetNoise( 0 );
m_lBeam->SetBrightness( 200 );
current_phase++;
if(current_phase == 8)
{
SetThink(DestroyTrail);
}
else
{
SetThink(UpdateTrail);
}
pev->nextthink=gpGlobals->time + 0.1;
}
void CRailgun::DestroyTrail()
{
current_phase = 0;
if ( m_pBeam )
{
UTIL_Remove( m_pBeam );
m_pBeam = NULL;
}
if ( m_inBeam )
{
UTIL_Remove( m_inBeam );
m_inBeam = NULL;
}
if ( m_lBeam )
{
UTIL_Remove( m_lBeam );
m_inBeam = NULL;
}
}
void CRailgun::StartFire( void )
{
float flDamage;
UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle );
Vector vecAiming = gpGlobals->v_forward;
Vector vecSrc = m_pPlayer->GetGunPosition( );
flDamage = gSkillData.plrDmgRailgun;
m_pPlayer->pev->punchangle.x = -2;
float flZVel = m_pPlayer->pev->velocity.z;
SendWeaponAnim( GAUSS_FIRE2 );
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/railgun1.wav", 0.5 + flDamage * (1.0 / 400.0), ATTN_NORM, 0, 85 + RANDOM_LONG(0,0x1f));
Fire( vecSrc, vecAiming, flDamage );
}
void CRailgun::Fire( Vector vecOrigSrc, Vector vecDir, float flDamage )
{
m_pPlayer->m_iWeaponVolume = RAILGUN_PRIMARY_FIRE_VOLUME;
Vector vecSrc = vecOrigSrc;
Vector vecDest = vecSrc + vecDir * 8192;
edict_t *pentIgnore;
TraceResult tr, beam_tr;
pentIgnore = ENT( m_pPlayer->pev );
UTIL_TraceLine(vecSrc, vecDest, dont_ignore_monsters, pentIgnore, &tr);
CreateTrail(vecSrc + gpGlobals->v_up * -8 + gpGlobals->v_right * 3 ,tr.vecEndPos);
UTIL_TraceLine(vecSrc, vecDest, dont_ignore_monsters, pentIgnore, &tr);
if (tr.fAllSolid)
return;
CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
if (pEntity == NULL)
return;
if (pEntity->pev->takedamage)
{
ClearMultiDamage();
pEntity->TraceAttack( m_pPlayer->pev, flDamage, vecDir, &tr, DMG_BULLET | DMG_ALWAYSGIB );
ApplyMultiDamage(m_pPlayer->pev, m_pPlayer->pev);
}
else
{
// Make some balls and a decal
DecalGunshot( &tr, BULLET_MONSTER_12MM );
MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, tr.vecEndPos );
WRITE_BYTE( TE_GLOWSPRITE );
WRITE_COORD( tr.vecEndPos.x); // pos
WRITE_COORD( tr.vecEndPos.y);
WRITE_COORD( tr.vecEndPos.z);
WRITE_SHORT( m_iGlow ); // model
WRITE_BYTE( 20 ); // life * 10
WRITE_BYTE( 3 ); // size * 10
WRITE_BYTE( 200 ); // brightness
MESSAGE_END();
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, tr.vecEndPos );
WRITE_BYTE( TE_SPRITETRAIL );
WRITE_COORD( tr.vecEndPos.x );
WRITE_COORD( tr.vecEndPos.y );
WRITE_COORD( tr.vecEndPos.z );
WRITE_COORD( tr.vecEndPos.x + tr.vecPlaneNormal.x );
WRITE_COORD( tr.vecEndPos.y + tr.vecPlaneNormal.y );
WRITE_COORD( tr.vecEndPos.z + tr.vecPlaneNormal.z );
WRITE_SHORT( m_iBalls ); // model
WRITE_BYTE( 8 ); // count
WRITE_BYTE( 6 ); // life * 10
WRITE_BYTE( RANDOM_LONG( 1, 2 ) ); // size * 10
WRITE_BYTE( 10 ); // amplitude * 0.1
WRITE_BYTE( 20 ); // speed * 100
MESSAGE_END();
}
vecSrc = tr.vecEndPos + vecDir;
pentIgnore = ENT( pEntity->pev );
}
void CRailgun::WeaponIdle( void )
{
ResetEmptySound( );
if (m_flTimeWeaponIdle > gpGlobals->time)
return;
int iAnim;
float flRand = RANDOM_FLOAT(0, 1);
if (flRand <= 0.5)
{
iAnim = GAUSS_IDLE;
m_flTimeWeaponIdle = gpGlobals->time + RANDOM_FLOAT ( 10, 15 );
}
else if (flRand <= 0.75)
{
iAnim = GAUSS_IDLE2;
m_flTimeWeaponIdle = gpGlobals->time + RANDOM_FLOAT ( 10, 15 );
}
else
{
iAnim = GAUSS_FIDGET;
m_flTimeWeaponIdle = gpGlobals->time + 3;
}
return;
SendWeaponAnim( iAnim );
}
class CRailgunAmmo : public CBasePlayerAmmo
{
void Spawn( void )
{
Precache( );
SET_MODEL(ENT(pev), "models/w_gaussammo.mdl");
CBasePlayerAmmo::Spawn( );
}
void Precache( void )
{
PRECACHE_MODEL ("models/w_gaussammo.mdl");
PRECACHE_SOUND("items/9mmclip1.wav");
}
BOOL AddAmmo( CBaseEntity *pOther )
{
if (pOther->GiveAmmo( AMMO_RAILSLUG_GIVE, "slug", RAILGUN_MAX_CARRY ) != -1)
{
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM);
return TRUE;
}
return FALSE;
}
};
LINK_ENTITY_TO_CLASS( ammo_railslug, CRailgunAmmo );