From b1c7892f2315dd5c3dfaa9ad63994626ce50249c Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 31 Jul 2019 00:42:13 +0300 Subject: [PATCH] Update spore launcher --- dlls/gearbox/spore_ammo.cpp | 308 +++++++++++++++++---------------- dlls/gearbox/sporegrenade.cpp | 263 +++++++++------------------- dlls/gearbox/sporegrenade.h | 24 +-- dlls/gearbox/sporelauncher.cpp | 147 ++++------------ dlls/player.cpp | 2 +- 5 files changed, 286 insertions(+), 458 deletions(-) diff --git a/dlls/gearbox/spore_ammo.cpp b/dlls/gearbox/spore_ammo.cpp index 0af6f3df..893c3ac7 100644 --- a/dlls/gearbox/spore_ammo.cpp +++ b/dlls/gearbox/spore_ammo.cpp @@ -21,187 +21,195 @@ #include "nodes.h" #include "player.h" #include "gamerules.h" -#include "xen.h" +#include "sporegrenade.h" -class CSporeFruit : public CActAnimating +class CSporeAmmo : public CBaseEntity { public: - void Spawn(void); - void Precache(void); - void Touch(CBaseEntity *pOther); - void Think(void); - - virtual int Save(CSave &save); - virtual int Restore(CRestore &restore); - static TYPEDESCRIPTION m_SaveData[]; - - BOOL m_fAmmoReady; - -private: - + void Spawn( void ); + void Precache( void ); + void EXPORT BornThink ( void ); + void EXPORT IdleThink ( void ); + void EXPORT AmmoTouch ( CBaseEntity *pOther ); + int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); + + int Save( CSave &save ); + int Restore( CRestore &restore ); + static TYPEDESCRIPTION m_SaveData[]; + + virtual int SizeForGrapple() { return GRAPPLE_FIXED; } + + int m_iExplode; + BOOL borntime; + float m_flTimeSporeIdle; }; -LINK_ENTITY_TO_CLASS(spore_fruit, CSporeFruit); -TYPEDESCRIPTION CSporeFruit::m_SaveData[] = +typedef enum +{ + SPOREAMMO_IDLE = 0, + SPOREAMMO_SPAWNUP, + SPOREAMMO_SNATCHUP, + SPOREAMMO_SPAWNDOWN, + SPOREAMMO_SNATCHDOWN, + SPOREAMMO_IDLE1, + SPOREAMMO_IDLE2, +} SPOREAMMO; + +LINK_ENTITY_TO_CLASS( ammo_spore, CSporeAmmo ) + +TYPEDESCRIPTION CSporeAmmo::m_SaveData[] = { - DEFINE_FIELD(CSporeFruit, m_fAmmoReady, FIELD_BOOLEAN), + DEFINE_FIELD( CSporeAmmo, m_flTimeSporeIdle, FIELD_TIME ), + DEFINE_FIELD( CSporeAmmo, borntime, FIELD_BOOLEAN ), }; +IMPLEMENT_SAVERESTORE( CSporeAmmo, CBaseEntity ) -IMPLEMENT_SAVERESTORE(CSporeFruit, CActAnimating); - -void CSporeFruit::Spawn(void) +void CSporeAmmo :: Precache( void ) { - Precache(); - + PRECACHE_MODEL("models/spore_ammo.mdl"); + m_iExplode = PRECACHE_MODEL ("sprites/spore_exp_c_01.spr"); + PRECACHE_SOUND("weapons/spore_ammo.wav"); + UTIL_PrecacheOther ( "spore" ); +} +//========================================================= +// Spawn +//========================================================= +void CSporeAmmo :: Spawn( void ) +{ + Precache( ); SET_MODEL(ENT(pev), "models/spore_ammo.mdl"); - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_TRIGGER; - UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 8)); - SetActivity(ACT_IDLE); - pev->nextthink = gpGlobals->time + 0.1; - pev->frame = 0; - - // idle - // spawnup - // snatchup - // spawndn - // snatchdn - // idle2 - // idle3 - - int i; - int seq = LookupSequence("idle"); - if (seq != -1) - { - for (i = 0; i < ACT_FLINCH_RIGHTLEG; i++) - { - if (seq == LookupActivity(i)) - { - break; - } - } - } + UTIL_SetSize(pev, Vector( -16, -16, -16 ), Vector( 16, 16, 16 )); + pev->takedamage = DAMAGE_YES; + pev->solid = SOLID_BBOX; + pev->movetype = MOVETYPE_NONE; + pev->framerate = 1.0; + pev->animtime = gpGlobals->time + 0.1; - seq = LookupSequence("spawnup"); - if (seq != -1) - { - for (i = 0; i < ACT_FLINCH_RIGHTLEG; i++) - { - if (seq == LookupActivity(i)) - { - break; - } - } - } + pev->sequence = SPOREAMMO_IDLE1; + pev->body = 1; - seq = LookupSequence("snatchup"); - if (seq != -1) - { - for (i = 0; i < ACT_FLINCH_RIGHTLEG; i++) - { - if (seq == LookupActivity(i)) - { - break; - } - } - } + Vector vecOrigin = pev->origin; + vecOrigin.z += 16; + UTIL_SetOrigin( pev, vecOrigin ); - seq = LookupSequence("spawndn"); - if (seq != -1) - { - for (i = 0; i < ACT_FLINCH_RIGHTLEG; i++) - { - if (seq == LookupActivity(i)) - { - break; - } - } - } + pev->angles.x -= 90;// :3 - seq = LookupSequence("snatchdn"); - if (seq != -1) - { - for (i = 0; i < ACT_FLINCH_RIGHTLEG; i++) - { - if (seq == LookupActivity(i)) - { - break; - } - } - } + SetThink (&CSporeAmmo::IdleThink); + SetTouch (&CSporeAmmo::AmmoTouch); - seq = LookupSequence("idle2"); - if (seq != -1) - { - for (i = 0; i < ACT_FLINCH_RIGHTLEG; i++) - { - if (seq == LookupActivity(i)) - { - break; - } - } - } + m_flTimeSporeIdle = gpGlobals->time + 20; + pev->nextthink = gpGlobals->time + 0.1; +} - seq = LookupSequence("idle3"); - if (seq != -1) +//========================================================= +// Override all damage +//========================================================= +int CSporeAmmo::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) +{ + if (!borntime) // rigth '!borntime' // blast in anytime 'borntime || !borntime' { - for (i = 0; i < ACT_FLINCH_RIGHTLEG; i++) - { - if (seq == LookupActivity(i)) - { - break; - } - } + Vector vecSrc = pev->origin + gpGlobals->v_forward * -32; + + MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); + WRITE_BYTE( TE_EXPLOSION ); // This makes a dynamic light and the explosion sprites/sound + WRITE_COORD( vecSrc.x ); // Send to PAS because of the sound + WRITE_COORD( vecSrc.y ); + WRITE_COORD( vecSrc.z ); + WRITE_SHORT( m_iExplode ); + WRITE_BYTE( 25 ); // scale * 10 + WRITE_BYTE( 12 ); // framerate + WRITE_BYTE( TE_EXPLFLAG_NOSOUND ); + MESSAGE_END(); + + + //ALERT( at_console, "angles %f %f %f\n", pev->angles.x, pev->angles.y, pev->angles.z ); + + Vector angles = pev->angles; + angles.x -= 90; + angles.y += 180; + + Vector vecLaunchDir = angles; + + vecLaunchDir.x += RANDOM_FLOAT( -20, 20 ); + vecLaunchDir.y += RANDOM_FLOAT( -20, 20 ); + vecLaunchDir.z += RANDOM_FLOAT( -20, 20 ); + + UTIL_MakeVectors( vecLaunchDir ); + CSporeGrenade::ShootTimed(pevAttacker, vecSrc, gpGlobals->v_forward * 800, false); + + pev->framerate = 1.0; + pev->animtime = gpGlobals->time + 0.1; + pev->sequence = SPOREAMMO_SNATCHDOWN; + pev->body = 0; + borntime = 1; + m_flTimeSporeIdle = gpGlobals->time + 1; + SetThink (&CSporeAmmo::IdleThink); + return 1; } - + return 0; } -void CSporeFruit::Precache(void) +//========================================================= +// Thinking begin +//========================================================= +void CSporeAmmo :: BornThink ( void ) { - PRECACHE_MODEL("models/spore_ammo.mdl"); + pev->nextthink = gpGlobals->time + 0.1; + + if ( m_flTimeSporeIdle > gpGlobals->time ) + return; + + pev->sequence = SPOREAMMO_SPAWNDOWN; + pev->framerate = 1.0; + pev->animtime = gpGlobals->time + 0.1; + pev->body = 1; + borntime = 0; + SetThink (&CSporeAmmo::IdleThink); + + m_flTimeSporeIdle = gpGlobals->time + 16; } -void CSporeFruit::Think(void) +void CSporeAmmo :: IdleThink ( void ) { - StudioFrameAdvance(); + pev->nextthink = gpGlobals->time + 0.1; + if ( m_flTimeSporeIdle > gpGlobals->time ) + return; + + if (borntime) + { + pev->sequence = SPOREAMMO_IDLE; - switch (GetActivity()) + m_flTimeSporeIdle = gpGlobals->time + 10; + SetThink(&CSporeAmmo::BornThink); + return; + } + else { - case ACT_CROUCH: - if (m_fSequenceFinished) - { - SetActivity(ACT_CROUCHIDLE); - } - break; - - case ACT_CROUCHIDLE: - if (gpGlobals->time > pev->dmgtime) - { - SetActivity(ACT_STAND); - } - break; - - case ACT_STAND: - if (m_fSequenceFinished) - SetActivity(ACT_IDLE); - break; - - case ACT_IDLE: - default: - break; + pev->sequence = SPOREAMMO_IDLE1; } } - -void CSporeFruit::Touch(CBaseEntity *pOther) +void CSporeAmmo :: AmmoTouch ( CBaseEntity *pOther ) { - if (pOther->IsPlayer()) + if ( !pOther->IsPlayer() ) + return; + + if (borntime) + return; + + int bResult = (pOther->GiveAmmo( AMMO_SPORE_GIVE, "spores", SPORE_MAX_CARRY ) != -1); + if (bResult) { - if (GetActivity() == ACT_IDLE || GetActivity() == ACT_STAND) - { - SetActivity(ACT_CROUCH); - } + EMIT_SOUND(ENT(pev), CHAN_ITEM, "weapons/spore_ammo.wav", 1, ATTN_NORM); + + pev->framerate = 1.0; + pev->animtime = gpGlobals->time + 0.1; + pev->sequence = SPOREAMMO_SNATCHDOWN; + pev->body = 0; + borntime = 1; + m_flTimeSporeIdle = gpGlobals->time + 1; + SetThink (&CSporeAmmo::IdleThink); } -} \ No newline at end of file +} diff --git a/dlls/gearbox/sporegrenade.cpp b/dlls/gearbox/sporegrenade.cpp index faf2ddc6..67cc81a8 100644 --- a/dlls/gearbox/sporegrenade.cpp +++ b/dlls/gearbox/sporegrenade.cpp @@ -27,33 +27,31 @@ #include "sporegrenade.h" #include "gearbox_weapons.h" -LINK_ENTITY_TO_CLASS(monster_spore, CSporeGrenade); +LINK_ENTITY_TO_CLASS(spore, CSporeGrenade) TYPEDESCRIPTION CSporeGrenade::m_SaveData[] = { DEFINE_FIELD(CSporeGrenade, m_pSporeGlow, FIELD_CLASSPTR), - DEFINE_FIELD(CSporeGrenade, m_flNextSpriteTrailSpawn, FIELD_TIME), }; -IMPLEMENT_SAVERESTORE(CSporeGrenade, CGrenade); +IMPLEMENT_SAVERESTORE(CSporeGrenade, CBaseMonster) int gSporeExplode, gSporeExplodeC; void CSporeGrenade::Precache(void) { + PRECACHE_MODEL("models/spore.mdl"); PRECACHE_MODEL("sprites/glow02.spr"); + g_sModelIndexTinySpit = PRECACHE_MODEL("sprites/tinyspit.spr"); gSporeExplode = PRECACHE_MODEL ("sprites/spore_exp_01.spr"); gSporeExplodeC = PRECACHE_MODEL ("sprites/spore_exp_c_01.spr"); + PRECACHE_SOUND("weapons/splauncher_bounce.wav"); + PRECACHE_SOUND("weapons/splauncher_impact.wav"); } -// UNDONE: temporary scorching for PreAlpha - find a less sleazy permenant solution. -void CSporeGrenade::Explode(TraceResult *pTrace, int bitsDamageType) +void CSporeGrenade::Explode(TraceResult *pTrace) { - //float flRndSound;// sound randomizer - - pev->model = iStringNull;//invisible pev->solid = SOLID_NOT;// intangible - pev->takedamage = DAMAGE_NO; // Pull out of the wall a bit @@ -93,6 +91,19 @@ void CSporeGrenade::Explode(TraceResult *pTrace, int bitsDamageType) WRITE_BYTE( 155 ); // framerate MESSAGE_END(); + MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin ); + WRITE_BYTE(TE_DLIGHT); + WRITE_COORD( pev->origin.x ); // X + WRITE_COORD( pev->origin.y ); // Y + WRITE_COORD( pev->origin.z ); // Z + WRITE_BYTE( 12 ); // radius * 0.1 + WRITE_BYTE( 0 ); // r + WRITE_BYTE( 180 ); // g + WRITE_BYTE( 0 ); // b + WRITE_BYTE( 20 ); // time * 10 + WRITE_BYTE( 20 ); // decay * 0.1 + MESSAGE_END( ); + // Play explode sound. EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/splauncher_impact.wav", 1, ATTN_NORM); @@ -105,72 +116,37 @@ void CSporeGrenade::Explode(TraceResult *pTrace, int bitsDamageType) pev->owner = NULL; // can't traceline attack owner if this is set - RadiusDamage(pev, pevOwner, pev->dmg, CLASS_NONE, bitsDamageType); + RadiusDamage(pev, pevOwner, pev->dmg, CLASS_NONE, DMG_BLAST); // Place a decal on the surface that was hit. +#if FEATURE_OPFOR_DECALS + UTIL_DecalTrace(pTrace, DECAL_SPR_SPLT1 + RANDOM_LONG(0, 2)); +#else UTIL_DecalTrace(pTrace, DECAL_YBLOOD5 + RANDOM_LONG(0, 1)); +#endif - pev->effects |= EF_NODRAW; - SetThink(&CSporeGrenade::Smoke); - pev->velocity = g_vecZero; - pev->nextthink = gpGlobals->time + 0.3; - - if (m_pSporeGlow) - { - UTIL_Remove(m_pSporeGlow); - m_pSporeGlow = NULL; - } -} - -void CSporeGrenade::Smoke(void) -{ - if (UTIL_PointContents(pev->origin) == CONTENTS_WATER) - { - UTIL_Bubbles(pev->origin - Vector(64, 64, 64), pev->origin + Vector(64, 64, 64), 100); - } UTIL_Remove(this); } -void CSporeGrenade::Killed(entvars_t *pevAttacker, int iGib) -{ - Detonate(); -} - -// Timed grenade, this think is called when time runs out. -void CSporeGrenade::DetonateUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) -{ - SetThink(&CSporeGrenade::Detonate); - pev->nextthink = gpGlobals->time; -} - -void CSporeGrenade::PreDetonate(void) -{ - CSoundEnt::InsertSound(bits_SOUND_DANGER, pev->origin, 400, 0.3); - - SetThink(&CSporeGrenade::Detonate); - pev->nextthink = gpGlobals->time + 1; -} - void CSporeGrenade::Detonate(void) { TraceResult tr; - Vector vecSpot;// trace starts here! - - vecSpot = pev->origin + Vector(0, 0, 8); + Vector vecSpot = pev->origin + Vector(0, 0, 8); UTIL_TraceLine(vecSpot, vecSpot + Vector(0, 0, -40), ignore_monsters, ENT(pev), &tr); - Explode(&tr, DMG_BLAST); + Explode(&tr); } void CSporeGrenade::BounceSound(void) { - switch (RANDOM_LONG(0, 2)) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/spore_hit1.wav", 0.25, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/spore_hit2.wav", 0.25, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/spore_hit3.wav", 0.25, ATTN_NORM); break; - } + DangerSound(); + EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/splauncher_bounce.wav", 0.25, ATTN_NORM); +} + +void CSporeGrenade::DangerSound() +{ + CSoundEnt::InsertSound(bits_SOUND_DANGER, pev->origin + pev->velocity * 0.5, pev->velocity.Length(), 0.2); } void CSporeGrenade::TumbleThink(void) @@ -181,7 +157,6 @@ void CSporeGrenade::TumbleThink(void) return; } - StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.1; if (pev->dmgtime - 1 < gpGlobals->time) @@ -193,25 +168,20 @@ void CSporeGrenade::TumbleThink(void) { SetThink(&CSporeGrenade::Detonate); } - if (pev->waterlevel != 0) - { - pev->velocity = pev->velocity * 0.5; - pev->framerate = 0.2; - } // Spawn particles. SpawnTrailParticles( pev->origin, // position -pev->velocity.Normalize(), // dir g_sModelIndexTinySpit, // modelindex - RANDOM_LONG( 5, 10 ), // count + RANDOM_LONG( 2, 4 ), // count RANDOM_FLOAT(10, 15), // speed RANDOM_FLOAT(2, 3) * 100); // noise ( client will divide by 100 ) } // // Contact grenade, explode when it touches something -// +// void CSporeGrenade::ExplodeTouch(CBaseEntity *pOther) { TraceResult tr; @@ -222,11 +192,9 @@ void CSporeGrenade::ExplodeTouch(CBaseEntity *pOther) vecSpot = pev->origin - pev->velocity.Normalize() * 32; UTIL_TraceLine(vecSpot, vecSpot + pev->velocity.Normalize() * 64, ignore_monsters, ENT(pev), &tr); - Explode(&tr, DMG_BLAST); + Explode(&tr); } - - void CSporeGrenade::DangerSoundThink(void) { if (!IsInWorld()) @@ -235,127 +203,57 @@ void CSporeGrenade::DangerSoundThink(void) return; } - CSoundEnt::InsertSound(bits_SOUND_DANGER, pev->origin + pev->velocity * 0.5, pev->velocity.Length(), 0.2); + DangerSound(); pev->nextthink = gpGlobals->time + 0.2; - if (pev->waterlevel != 0) - { - pev->velocity = pev->velocity * 0.5; - } - // Spawn particles. SpawnTrailParticles( pev->origin, // position -pev->velocity.Normalize(), // dir g_sModelIndexTinySpit, // modelindex - RANDOM_LONG(5, 10), // count + RANDOM_LONG( 5, 10), // count RANDOM_FLOAT(10, 15), // speed RANDOM_FLOAT(2, 3) * 100); // noise ( client will divide by 100 ) } void CSporeGrenade::BounceTouch(CBaseEntity *pOther) { -#if 0 - // don't hit the guy that launched this grenade - if (pOther->edict() == pev->owner) - return; -#endif - - // only do damage if we're moving fairly fast - if (m_flNextAttack < gpGlobals->time && pev->velocity.Length() > 100) + if ( !pOther->pev->takedamage ) { - entvars_t *pevOwner = VARS(pev->owner); - if (pevOwner) - { - TraceResult tr = UTIL_GetGlobalTrace(); - ClearMultiDamage(); - pOther->TraceAttack(pevOwner, 1, gpGlobals->v_forward, &tr, DMG_CLUB); - ApplyMultiDamage(pev, pevOwner); + if (!(pev->flags & FL_ONGROUND)) { + if (pev->dmg_save < gpGlobals->time) { + BounceSound(); + pev->dmg_save = gpGlobals->time + 0.1; + } + } else { + pev->velocity = pev->velocity * 0.9; } - m_flNextAttack = gpGlobals->time + 1.0; // debounce - } - - Vector vecTestVelocity; - // pev->avelocity = Vector (300, 300, 300); - - // this is my heuristic for modulating the grenade velocity because grenades dropped purely vertical - // or thrown very far tend to slow down too quickly for me to always catch just by testing velocity. - // trimming the Z velocity a bit seems to help quite a bit. - vecTestVelocity = pev->velocity; - vecTestVelocity.z *= 1.25; // 0.45 - - if (!m_fRegisteredSound && vecTestVelocity.Length() <= 60) - { - //ALERT( at_console, "Grenade Registered!: %f\n", vecTestVelocity.Length() ); - - // grenade is moving really slow. It's probably very close to where it will ultimately stop moving. - // go ahead and emit the danger sound. - - // register a radius louder than the explosion, so we make sure everyone gets out of the way - CSoundEnt::InsertSound(bits_SOUND_DANGER, pev->origin, pev->dmg / 0.4, 0.3); - m_fRegisteredSound = TRUE; - } - - if (pev->flags & FL_ONGROUND) - { - // add a bit of static friction - pev->velocity = pev->velocity * 0.01; - - pev->sequence = RANDOM_LONG(1, 1); - } - else - { - // play bounce sound - BounceSound(); - } - pev->framerate = pev->velocity.Length() / 200.0; - if (pev->framerate > 1.0) - pev->framerate = 1; - else if (pev->framerate < 0.5) - pev->framerate = 0; -} - - -void CSporeGrenade::SlideTouch(CBaseEntity *pOther) -{ - // don't hit the guy that launched this grenade - if (pOther->edict() == pev->owner) - return; - - // pev->avelocity = Vector (300, 300, 300); - - if (pev->flags & FL_ONGROUND) - { - // add a bit of static friction - pev->velocity = pev->velocity * 0.95; - - if (pev->velocity.x != 0 || pev->velocity.y != 0) + if (pev->flags & FL_SWIM) { - // maintain sliding sound + pev->velocity = pev->velocity * 0.5; } } else { - BounceSound(); + TraceResult tr = UTIL_GetGlobalTrace(); + Explode(&tr); } } void CSporeGrenade::Spawn(void) { + Precache(); + pev->classname = MAKE_STRING("spore"); pev->movetype = MOVETYPE_BOUNCE; - + pev->solid = SOLID_BBOX; SET_MODEL(ENT(pev), "models/spore.mdl"); UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0)); - pev->gravity = 0.5; // 0.5 - pev->friction = 0.2; // 0.8 + //pev->gravity = 0.5; pev->dmg = gSkillData.plrDmgSpore; - m_fRegisteredSound = FALSE; - - m_flNextSpriteTrailSpawn = gpGlobals->time; m_pSporeGlow = CSprite::SpriteCreate("sprites/glow02.spr", pev->origin, FALSE); @@ -367,65 +265,54 @@ void CSporeGrenade::Spawn(void) } } -CGrenade * CSporeGrenade::ShootTimed(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time) +CBaseEntity* CSporeGrenade::ShootTimed(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, bool ai) { CSporeGrenade *pGrenade = GetClassPtr((CSporeGrenade *)NULL); - pGrenade->Spawn(); UTIL_SetOrigin(pGrenade->pev, vecStart); + pGrenade->Spawn(); pGrenade->pev->velocity = vecVelocity; pGrenade->pev->angles = UTIL_VecToAngles(pGrenade->pev->velocity); pGrenade->pev->owner = ENT(pevOwner); pGrenade->SetTouch(&CSporeGrenade::BounceTouch); // Bounce if touched - // Take one second off of the desired detonation time and set the think to PreDetonate. PreDetonate - // will insert a DANGER sound into the world sound list and delay detonation for one second so that - // the grenade explodes after the exact amount of time specified in the call to ShootTimed(). - - pGrenade->pev->dmgtime = gpGlobals->time + time; + float lifetime = 2.0; + if (ai) { + lifetime = 4.0; + pGrenade->pev->gravity = 0.5; + pGrenade->pev->friction = 0.9; + } + pGrenade->pev->dmgtime = gpGlobals->time + lifetime; pGrenade->SetThink(&CSporeGrenade::TumbleThink); pGrenade->pev->nextthink = gpGlobals->time + 0.1; - if (time < 0.1) + if (lifetime < 0.1) { pGrenade->pev->nextthink = gpGlobals->time; pGrenade->pev->velocity = Vector(0, 0, 0); } - pGrenade->pev->sequence = RANDOM_LONG(3, 6); - pGrenade->pev->framerate = 1.0; - - // Tumble through the air - // pGrenade->pev->avelocity.x = -400; - - pGrenade->pev->gravity = 0.5; - pGrenade->pev->friction = 0.2; // 0.8 - - SET_MODEL(ENT(pGrenade->pev), "models/spore.mdl"); - pGrenade->pev->dmg = gSkillData.plrDmgSpore; - return pGrenade; } -CGrenade *CSporeGrenade::ShootContact(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity) +CBaseEntity *CSporeGrenade::ShootContact(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity) { CSporeGrenade *pGrenade = GetClassPtr((CSporeGrenade *)NULL); + UTIL_SetOrigin(pGrenade->pev, vecStart); pGrenade->Spawn(); pGrenade->pev->movetype = MOVETYPE_FLY; - UTIL_SetOrigin(pGrenade->pev, vecStart); pGrenade->pev->velocity = vecVelocity; pGrenade->pev->angles = UTIL_VecToAngles(pGrenade->pev->velocity); pGrenade->pev->owner = ENT(pevOwner); - // make monsters afaid of it while in the air + // make monsters afraid of it while in the air pGrenade->SetThink(&CSporeGrenade::DangerSoundThink); pGrenade->pev->nextthink = gpGlobals->time; - // Tumble in air - // Explode on contact pGrenade->SetTouch(&CSporeGrenade::ExplodeTouch); - pGrenade->pev->dmg = gSkillData.plrDmgSpore; + pGrenade->pev->gravity = 0.5; + pGrenade->pev->friction = 0.7; return pGrenade; } @@ -464,3 +351,13 @@ void CSporeGrenade::SpawnExplosionParticles(const Vector& origin, const Vector& WRITE_BYTE(noise); // noise ( client will divide by 100 ) MESSAGE_END(); } + +void CSporeGrenade::UpdateOnRemove() +{ + CBaseMonster::UpdateOnRemove(); + if (m_pSporeGlow) + { + UTIL_Remove(m_pSporeGlow); + m_pSporeGlow = NULL; + } +} diff --git a/dlls/gearbox/sporegrenade.h b/dlls/gearbox/sporegrenade.h index 9d9515f8..2782fa0c 100644 --- a/dlls/gearbox/sporegrenade.h +++ b/dlls/gearbox/sporegrenade.h @@ -16,9 +16,8 @@ #ifndef SPORE_GRENADE_H #define SPORE_GRENADE_H - // Contact/Timed spore grenade -class CSporeGrenade : public CGrenade +class CSporeGrenade : public CBaseMonster { public: virtual int Save(CSave &save); @@ -29,30 +28,25 @@ public: void Precache(void); void Spawn(void); - static CGrenade *ShootTimed(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time); - static CGrenade *ShootContact(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity); + static CBaseEntity *ShootTimed(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, bool ai); + static CBaseEntity *ShootContact(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity); - void Explode(TraceResult *pTrace, int bitsDamageType); - void EXPORT Smoke(void); + void Explode(TraceResult *pTrace); - void EXPORT BounceTouch(CBaseEntity *pOther); - void EXPORT SlideTouch(CBaseEntity *pOther); + void EXPORT BounceTouch(CBaseEntity *pOther); void EXPORT ExplodeTouch(CBaseEntity *pOther); void EXPORT DangerSoundThink(void); - void EXPORT PreDetonate(void); void EXPORT Detonate(void); - void EXPORT DetonateUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); void EXPORT TumbleThink(void); - void EXPORT FlyThink(void); - virtual void BounceSound(void); - virtual int BloodColor(void) { return DONT_BLEED; } - virtual void Killed(entvars_t *pevAttacker, int iGib); + void BounceSound(void); + void DangerSound(); static void SpawnTrailParticles(const Vector& origin, const Vector& direction, int modelindex, int count, float speed, float noise); static void SpawnExplosionParticles(const Vector& origin, const Vector& direction, int modelindex, int count, float speed, float noise); + void UpdateOnRemove(); + CSprite* m_pSporeGlow; - float m_flNextSpriteTrailSpawn; }; #endif // SPORE_GRENADE_H diff --git a/dlls/gearbox/sporelauncher.cpp b/dlls/gearbox/sporelauncher.cpp index 20f886bf..ab09f5df 100644 --- a/dlls/gearbox/sporelauncher.cpp +++ b/dlls/gearbox/sporelauncher.cpp @@ -21,8 +21,9 @@ #include "nodes.h" #include "player.h" #include "gamerules.h" -#include "xen.h" +#ifndef CLIENT_DLL #include "sporegrenade.h" +#endif // special deathmatch shotgun spreads #define VECTOR_CONE_DM_SHOTGUN Vector( 0.08716, 0.04362, 0.00 )// 10 degrees by 5 degrees @@ -40,7 +41,7 @@ enum sporelauncher_e { SPLAUNCHER_IDLE2 }; -LINK_ENTITY_TO_CLASS(weapon_sporelauncher, CSporelauncher); +LINK_ENTITY_TO_CLASS(weapon_sporelauncher, CSporelauncher) void CSporelauncher::Spawn() { @@ -71,7 +72,7 @@ void CSporelauncher::Precache(void) PRECACHE_MODEL("sprites/bigspit.spr"); m_iSquidSpitSprite = PRECACHE_MODEL("sprites/tinyspit.spr"); - UTIL_PrecacheOther("monster_spore"); + UTIL_PrecacheOther("spore"); m_usSporeFire = PRECACHE_EVENT(1, "events/spore.sc"); } @@ -92,7 +93,7 @@ int CSporelauncher::AddToPlayer(CBasePlayer *pPlayer) int CSporelauncher::GetItemInfo(ItemInfo *p) { p->pszName = STRING(pev->classname); - p->pszAmmo1 = "Spores"; + p->pszAmmo1 = "spores"; p->iMaxAmmo1 = SPORE_MAX_CARRY; p->pszAmmo2 = NULL; p->iMaxAmmo2 = -1; @@ -115,21 +116,8 @@ BOOL CSporelauncher::Deploy() void CSporelauncher::PrimaryAttack() { - // don't fire underwater - if (m_pPlayer->pev->waterlevel == 3) - { - PlayEmptySound(); - m_flNextPrimaryAttack = GetNextAttackDelay(0.15); - return; - } - if (m_iClip <= 0) - { - Reload(); - if (m_iClip == 0) - PlayEmptySound(); return; - } m_pPlayer->m_iWeaponVolume = LOUD_GUN_VOLUME; m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH; @@ -145,38 +133,26 @@ void CSporelauncher::PrimaryAttack() // m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH; - - Vector vecSrc = m_pPlayer->GetGunPosition(); - Vector vecAiming = m_pPlayer->GetAutoaimVector(AUTOAIM_5DEGREES); - - Vector vecDir; - Vector vecVel; - - UTIL_MakeVectors(m_pPlayer->pev->v_angle); - - vecSrc = vecSrc + gpGlobals->v_forward * 16; - vecSrc = vecSrc + gpGlobals->v_right * 8; - vecSrc = vecSrc + gpGlobals->v_up * -12; - - vecVel = gpGlobals->v_forward * 900; - vecDir = gpGlobals->v_forward + gpGlobals->v_right + gpGlobals->v_up; - vecDir = vecDir; + m_pPlayer->SetAnimation(PLAYER_ATTACK1); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); + Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -8; #ifndef CLIENT_DLL - CSporeGrenade::ShootContact(m_pPlayer->pev, vecSrc, vecVel); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); + CSporeGrenade::ShootContact( m_pPlayer->pev, vecSrc, gpGlobals->v_forward * 1500 ); #endif PLAYBACK_EVENT_FULL( flags, - m_pPlayer->edict(), - m_usSporeFire, - 0.0, - (float *)&g_vecZero, - (float *)&g_vecZero, - vecDir.x, - vecDir.y, - *(int*)&vecDir.z, - m_iSquidSpitSprite, + m_pPlayer->edict(), + m_usSporeFire, + 0.0, + (float *)&g_vecZero, + (float *)&g_vecZero, + vecSrc.x, + vecSrc.y, + *(int*)&vecSrc.z, + m_iSquidSpitSprite, 0, TRUE); @@ -202,20 +178,8 @@ void CSporelauncher::PrimaryAttack() void CSporelauncher::SecondaryAttack(void) { - // don't fire underwater - if (m_pPlayer->pev->waterlevel == 3) - { - PlayEmptySound(); - m_flNextPrimaryAttack = GetNextAttackDelay(0.15); - return; - } - if (m_iClip <= 0) - { - Reload(); - PlayEmptySound(); return; - } m_pPlayer->m_iWeaponVolume = LOUD_GUN_VOLUME; m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH; @@ -230,43 +194,30 @@ void CSporelauncher::SecondaryAttack(void) flags = 0; #endif - m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH; + //m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH; // player "shoot" animation m_pPlayer->SetAnimation(PLAYER_ATTACK1); - - Vector vecSrc = m_pPlayer->GetGunPosition(); - Vector vecAiming = m_pPlayer->GetAutoaimVector(AUTOAIM_2DEGREES); - - Vector vecDir; - Vector vecVel; - - UTIL_MakeVectors(m_pPlayer->pev->v_angle); - - vecSrc = vecSrc + gpGlobals->v_forward * 16; - vecSrc = vecSrc + gpGlobals->v_right * 8; - vecSrc = vecSrc + gpGlobals->v_up * -12; - - vecVel = gpGlobals->v_forward * 800; - vecDir = gpGlobals->v_forward + gpGlobals->v_right + gpGlobals->v_up; - vecDir = vecDir; + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); + Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -8; #ifndef CLIENT_DLL - CSporeGrenade::ShootTimed(m_pPlayer->pev, vecSrc, vecVel, RANDOM_FLOAT(5, 6)); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); + CSporeGrenade::ShootTimed(m_pPlayer->pev, vecSrc, gpGlobals->v_forward * 1000, false); #endif PLAYBACK_EVENT_FULL( - flags, + flags, m_pPlayer->edict(), - m_usSporeFire, - 0.0, + m_usSporeFire, + 0.0, (float *)&g_vecZero, (float *)&g_vecZero, - vecDir.x, - vecDir.y, - *(int*)&vecDir.z, + vecSrc.x, + vecSrc.y, + *(int*)&vecSrc.z, m_iSquidSpitSprite, - 0, + 0, 0); if (!m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) @@ -366,45 +317,23 @@ void CSporelauncher::WeaponIdle(void) { int iAnim; float flRand = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 0, 1); - if (flRand <= 0.5) + if (flRand <= 0.4) { iAnim = SPLAUNCHER_IDLE; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f; } - else + else if (flRand <= 0.8) { iAnim = SPLAUNCHER_IDLE2; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 4.0f; } + else + { + iAnim = SPLAUNCHER_FIDGET; + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 4.0f; + } SendWeaponAnim(iAnim); } } } - - -class CSporeAmmo : public CBasePlayerAmmo -{ - void Spawn(void) - { - Precache(); - SET_MODEL(ENT(pev), "models/spore.mdl"); - CBasePlayerAmmo::Spawn(); - } - void Precache(void) - { - PRECACHE_MODEL("models/spore.mdl"); - PRECACHE_SOUND("weapons/spore_ammo.wav"); - } - BOOL AddAmmo(CBaseEntity *pOther) - { - int bResult = (pOther->GiveAmmo(AMMO_SPORE_GIVE, "Spores", SPORE_MAX_CARRY) != -1); - if (bResult) - { - EMIT_SOUND(ENT(pev), CHAN_ITEM, "weapons/spore_ammo.wav", 1, ATTN_NORM); - } - return bResult; - } -}; - -LINK_ENTITY_TO_CLASS(ammo_spore, CSporeAmmo); diff --git a/dlls/player.cpp b/dlls/player.cpp index c3575ba0..d98c4363 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -1132,7 +1132,7 @@ void CBasePlayer::TabulateAmmo() ammo_556 = AmmoInventory( GetAmmoIndex( "556" ) ); ammo_762 = AmmoInventory( GetAmmoIndex( "762" ) ); ammo_shocks = AmmoInventory( GetAmmoIndex( "Shocks" ) ); - ammo_spores = AmmoInventory( GetAmmoIndex( "Spores" ) ); + ammo_spores = AmmoInventory( GetAmmoIndex( "spores" ) ); } /*