Well you see, i tried to replicate the quake nail of Deathmatch Classic to create this weapon... So you will see enough copy paste of the code triying to replicate it on the HL base code. Some of the functions for the nail projectiles where already on the Client files, so i dont know how much this causes the main problem. I don't even think this weapon shoots even, i really need someone to diagnose this terribleness.
nailgun.cpp
#if !defined( OEM_BUILD ) && !defined( HLDEMO_BUILD )
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "player.h"
#include "decals.h"
#include "gamerules.h"
enum ngun_e {
NGUN_IDLE1 = 0,
NGUN_FIDGETSWAY,
NGUN_FIDGETSHAKE,
NGUN_DOWN,
NGUN_UP,
NGUN_SHOOT
};
enum firemode_e
{
FIREMODE_TRACK = 0,
FIREMODE_FAST
};
#ifndef CLIENT_DLL
LINK_ENTITY_TO_CLASS(quake_nail, CQuakeNail);
//=========================================================
CQuakeNail* CQuakeNail::CreateNail(Vector vecOrigin, Vector vecAngles, CBaseEntity* pOwner)
{
CQuakeNail* pNail = GetClassPtr((CQuakeNail*)NULL);
UTIL_SetOrigin(pNail->pev, vecOrigin);
pNail->pev->velocity = vecAngles * 1000;
pNail->pev->angles = UTIL_VecToAngles(vecAngles);
pNail->pev->owner = pOwner->edict();
pNail->Spawn();
pNail->pev->classname = MAKE_STRING("spike");
// don't send to clients.
pNail->pev->effects |= EF_NODRAW;
return pNail;
}
CQuakeNail* CQuakeNail::CreateSuperNail(Vector vecOrigin, Vector vecAngles, CBaseEntity* pOwner)
{
CQuakeNail* pNail = CreateNail(vecOrigin, vecAngles, pOwner);
pNail->pev->classname = MAKE_STRING("superspike");
// Super nails simply do more damage
pNail->pev->dmg = 18;
return pNail;
}
void CQuakeNail::Precache(void)
{
PRECACHE_MODEL("models/nail.mdl");
}
//=========================================================
void CQuakeNail::Spawn(void)
{
Precache();
// Setup
pev->movetype = MOVETYPE_FLYMISSILE;
pev->solid = SOLID_BBOX;
// Safety removal
pev->nextthink = gpGlobals->time + 6;
SetThink(&CQuakeNail::SUB_Remove);
// Touch
SetTouch(&CQuakeNail::NailTouch);
// Model
SET_MODEL(ENT(pev), "models/nail.mdl");
UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0));
UTIL_SetOrigin(pev, pev->origin);
// Damage
pev->dmg = 9;
}
//=========================================================
void CQuakeNail::NailTouch(CBaseEntity* pOther)
{
if (pOther->pev->solid == SOLID_TRIGGER)
return;
// Remove if we've hit skybrush
if (UTIL_PointContents(pev->origin) == CONTENT_SKY)
{
UTIL_Remove(this);
return;
}
// Hit something that bleeds
if (pOther->pev->takedamage)
{
CBaseEntity* pOwner = CBaseEntity::Instance(pev->owner);
if (g_pGameRules->PlayerRelationship(pOther, pOwner) != GR_TEAMMATE)
SpawnBlood(pev->origin, pOther->BloodColor(), pev->dmg);
pOther->TakeDamage(pev, pOwner->pev, pev->dmg, DMG_GENERIC);
}
else
{
if (pOther->pev->solid == SOLID_BSP || pOther->pev->movetype == MOVETYPE_PUSHSTEP)
{
TraceResult tr;
tr.vecEndPos = pev->origin;
tr.pHit = pOther->edict();
//Arent we doing this client side?
//UTIL_GunshotDecalTrace( &tr, DECAL_GUNSHOT1 + RANDOM_LONG( 0, 4 ) );
}
}
UTIL_Remove(this);
}
#endif
LINK_ENTITY_TO_CLASS(weapon_nailgun, CNailGun);
void CNailGun::Spawn()
{
Precache();
m_iId = WEAPON_NAILGUN;
SET_MODEL(ENT(pev), "models/w_hgun.mdl");
m_iDefaultAmmo = NAILGUN_DEFAULT_GIVE;
m_iFirePhase = 0;
pev->solid = SOLID_TRIGGER;
FallInit();// get ready to fall down.
}
void CNailGun::Precache(void)
{
PRECACHE_MODEL("models/v_tfc_nailgun.mdl");
PRECACHE_MODEL("models/w_hgun.mdl");
PRECACHE_MODEL("models/p_nailgun.mdl");
PRECACHE_SOUND("weapons/airgun_1.wav");
m_usNailFire = PRECACHE_EVENT(1, "events/wpn/Tf_nail.sc");
UTIL_PrecacheOther("nail");
}
int CNailGun::AddToPlayer(CBasePlayer* pPlayer)
{
if (CBasePlayerWeapon::AddToPlayer(pPlayer))
{
#ifndef CLIENT_DLL
if (g_pGameRules->IsMultiplayer())
{
// in multiplayer, all hivehands come full.
pPlayer->m_rgAmmo[PrimaryAmmoIndex()] = NAILGUN_MAX_CARRY;
}
#endif
MESSAGE_BEGIN(MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev);
WRITE_BYTE(m_iId);
MESSAGE_END();
return TRUE;
}
return FALSE;
}
int CNailGun::GetItemInfo(ItemInfo* p)
{
p->pszName = STRING(pev->classname);
p->pszAmmo1 = "9mm";
p->iMaxAmmo1 = NAILGUN_MAX_CARRY;
p->pszAmmo2 = NULL;
p->iMaxAmmo2 = -1;
p->iMaxClip = WEAPON_NOCLIP;
p->iSlot = 1;
p->iPosition = 3;
p->iId = m_iId = WEAPON_NAILGUN;
p->iFlags = 0;
p->iWeight = NAILGUN_WEIGHT;
return 1;
}
BOOL CNailGun::Deploy()
{
return DefaultDeploy("models/v_tfc_nailgun.mdl", "models/p_nailgun.mdl", NGUN_UP, "mp5",1);
}
void CNailGun::PrimaryAttack()
{
Reload();
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
{
PlayEmptySound();
return;
}
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME;
m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH;
PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usNailFire, 0, (float*)&g_vecZero, (float*)&g_vecZero, 0, 0, 0, 0, 0, 0);
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
m_flTimeWeaponIdle = 10;
m_flNextPrimaryAttack = 0.1;
}
void CNailGun::WeaponIdle(void)
{
Reload();
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
return;
int iAnim;
float flRand = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 0, 1);
if (flRand <= 0.75)
{
iAnim = NGUN_IDLE1;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 30.0 / 16 * (2);
}
else if (flRand <= 0.875)
{
iAnim = NGUN_FIDGETSWAY;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 40.0 / 16.0;
}
else
{
iAnim = NGUN_FIDGETSHAKE;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 35.0 / 16.0;
}
SendWeaponAnim(iAnim);
}
#endif
weapons.h
//constant items
/Blah blah blah code/
#define WEAPON_NAILGUN 16
// weapon weight factors (for auto-switching) (-1 = noswitch)
/Blah blah blah code/
#define NAILGUN_WEIGHT 10
// weapon clip/carry ammo capacities
/Blah blah blah code/
#define NAILGUN_MAX_CARRY 100
// Max clip section
/Blah blah blah code/
#define NAILGUN_MAX_CLIP WEAPON_NOCLIP
// the default amount of ammo that comes with each gun when it spawns
/Blah blah blah code/
#define NAILGUN_DEFAULT_GIVE 50
(Didnt write the ammo given to a player by an ammo item)
/Blah blah blah class code/
class CNailGun : 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);
BOOL Deploy(void);
void WeaponIdle(void);
int m_iFirePhase;// don't save me.
virtual BOOL UseDecrement(void)
{
#if defined( CLIENT_WEAPONS )
return TRUE;
#else
return FALSE;
#endif
}
private:
unsigned short m_usNailFire;
};
class CQuakeNail : public CBaseEntity
{
public:
void Spawn(void);
void Precache(void);
static CQuakeNail* CreateNail(Vector vecOrigin, Vector vecAngles, CBaseEntity* pOwner);
static CQuakeNail* CreateSuperNail(Vector vecOrigin, Vector vecAngles, CBaseEntity* pOwner);
void EXPORT NailTouch(CBaseEntity* pOther);
};