Browse Source

Make spore behavior match original. Remove redundant declarations (#229)

opforfixed
Roman Chistokhodov 3 years ago committed by GitHub
parent
commit
310493aaeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      dlls/gearbox/gearbox_effects.cpp
  2. 26
      dlls/gearbox/gearbox_weapons.h
  3. 108
      dlls/gearbox/spore_ammo.cpp
  4. 454
      dlls/gearbox/sporegrenade.cpp
  5. 56
      dlls/gearbox/sporegrenade.h
  6. 20
      dlls/gearbox/sporelauncher.cpp
  7. 2
      dlls/gearbox/strooper.cpp
  8. 15
      dlls/weapons.cpp
  9. 3
      dlls/weapons.h

12
dlls/gearbox/gearbox_effects.cpp

@ -18,6 +18,10 @@
#include "cbase.h" #include "cbase.h"
#include "monsters.h" #include "monsters.h"
#include "effects.h" #include "effects.h"
#include "weapons.h"
#include "displacerball.h"
#include "shock.h"
#include "sporegrenade.h"
//========================================================= //=========================================================
// CPitwormGibShooter // CPitwormGibShooter
@ -176,10 +180,6 @@ void CPitwormGibShooter::ShootThink()
pev->nextthink = gpGlobals->time + 0.1; pev->nextthink = gpGlobals->time + 0.1;
} }
#include "displacerball.h"
#include "shock.h"
#include "sporegrenade.h"
enum enum
{ {
BLOWERCANNON_SPOREROCKET = 1, BLOWERCANNON_SPOREROCKET = 1,
@ -298,10 +298,10 @@ void CBlowerCannon::BlowerCannonThink( void )
switch (m_iWeapType) switch (m_iWeapType)
{ {
case BLOWERCANNON_SPOREROCKET: case BLOWERCANNON_SPOREROCKET:
CSporeGrenade::ShootContact(pev, pev->origin, gpGlobals->v_forward * 1500); CSpore::CreateSpore(pev->origin, angles, this, CSpore::ROCKET, false, false);
break; break;
case BLOWERCANNON_SPOREGRENADE: case BLOWERCANNON_SPOREGRENADE:
CSporeGrenade::ShootTimed(pev, pev->origin, gpGlobals->v_forward * 700, false); CSpore::CreateSpore(pev->origin, angles, this, CSpore::GRENADE, false, false);
break; break;
case BLOWERCANNON_SHOCKBEAM: case BLOWERCANNON_SHOCKBEAM:
CShock::Shoot(pev, pev->angles, pev->origin, gpGlobals->v_forward * 2000); CShock::Shoot(pev, pev->angles, pev->origin, gpGlobals->v_forward * 2000);

26
dlls/gearbox/gearbox_weapons.h

@ -1,26 +0,0 @@
/***
*
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* 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.
*
****/
#ifndef GEARBOX_WEAPONS_H
#define GEARBOX_WEAPONS_H
extern DLL_GLOBAL short g_sModelIndexSpore1;
extern DLL_GLOBAL short g_sModelIndexSpore2;
extern DLL_GLOBAL short g_sModelIndexSpore3;
extern DLL_GLOBAL short g_sModelIndexBigSpit;
extern DLL_GLOBAL short g_sModelIndexTinySpit;
#endif // GEARBOX_WEAPONS_H

108
dlls/gearbox/spore_ammo.cpp

@ -28,20 +28,13 @@ class CSporeAmmo : public CBaseEntity
public: public:
void Spawn( void ); void Spawn( void );
void Precache( void ); void Precache( void );
void EXPORT BornThink ( void );
void EXPORT IdleThink ( void ); void EXPORT IdleThink ( void );
void EXPORT AmmoTouch ( CBaseEntity *pOther ); void EXPORT AmmoTouch ( CBaseEntity *pOther );
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); 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; } virtual int SizeForGrapple() { return GRAPPLE_FIXED; }
int m_iExplode; int m_iExplode;
BOOL borntime;
float m_flTimeSporeIdle;
}; };
@ -58,13 +51,6 @@ typedef enum
LINK_ENTITY_TO_CLASS( ammo_spore, CSporeAmmo ) LINK_ENTITY_TO_CLASS( ammo_spore, CSporeAmmo )
TYPEDESCRIPTION CSporeAmmo::m_SaveData[] =
{
DEFINE_FIELD( CSporeAmmo, m_flTimeSporeIdle, FIELD_TIME ),
DEFINE_FIELD( CSporeAmmo, borntime, FIELD_BOOLEAN ),
};
IMPLEMENT_SAVERESTORE( CSporeAmmo, CBaseEntity )
void CSporeAmmo :: Precache( void ) void CSporeAmmo :: Precache( void )
{ {
PRECACHE_MODEL("models/spore_ammo.mdl"); PRECACHE_MODEL("models/spore_ammo.mdl");
@ -83,23 +69,22 @@ void CSporeAmmo :: Spawn( void )
pev->takedamage = DAMAGE_YES; pev->takedamage = DAMAGE_YES;
pev->solid = SOLID_BBOX; pev->solid = SOLID_BBOX;
pev->movetype = MOVETYPE_NONE; pev->movetype = MOVETYPE_NONE;
pev->framerate = 1.0; pev->framerate = 1.0f;
pev->animtime = gpGlobals->time + 0.1; pev->health = 1.0f;
pev->animtime = gpGlobals->time;
pev->sequence = SPOREAMMO_IDLE1; pev->sequence = SPOREAMMO_SPAWNDOWN;
pev->body = 1; pev->body = 1;
Vector vecOrigin = pev->origin; pev->origin.z += 16;
vecOrigin.z += 16; UTIL_SetOrigin( pev, pev->origin );
UTIL_SetOrigin( pev, vecOrigin );
pev->angles.x -= 90;// :3 pev->angles.x -= 90;// :3
SetThink (&CSporeAmmo::IdleThink); SetThink (&CSporeAmmo::IdleThink);
SetTouch (&CSporeAmmo::AmmoTouch); SetTouch (&CSporeAmmo::AmmoTouch);
m_flTimeSporeIdle = gpGlobals->time + 20; pev->nextthink = gpGlobals->time + 4;
pev->nextthink = gpGlobals->time + 0.1;
} }
//========================================================= //=========================================================
@ -107,7 +92,7 @@ void CSporeAmmo :: Spawn( void )
//========================================================= //=========================================================
int CSporeAmmo::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) int CSporeAmmo::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType )
{ {
if (!borntime) // rigth '!borntime' // blast in anytime 'borntime || !borntime' if (pev->body != 0)
{ {
Vector vecSrc = pev->origin + gpGlobals->v_forward * -32; Vector vecSrc = pev->origin + gpGlobals->v_forward * -32;
@ -135,68 +120,57 @@ int CSporeAmmo::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, flo
vecLaunchDir.y += RANDOM_FLOAT( -20, 20 ); vecLaunchDir.y += RANDOM_FLOAT( -20, 20 );
vecLaunchDir.z += RANDOM_FLOAT( -20, 20 ); vecLaunchDir.z += RANDOM_FLOAT( -20, 20 );
CSpore* pSpore = CSpore::CreateSpore(pev->origin, vecLaunchDir, this, CSpore::GRENADE, false, true);
UTIL_MakeVectors( vecLaunchDir ); UTIL_MakeVectors( vecLaunchDir );
CSporeGrenade::ShootTimed(pevAttacker, vecSrc, gpGlobals->v_forward * 800, false); pSpore->pev->velocity = gpGlobals->v_forward * 800;
pev->framerate = 1.0; pev->frame = 0;
pev->animtime = gpGlobals->time + 0.1; pev->animtime = gpGlobals->time + 0.1;
pev->sequence = SPOREAMMO_SNATCHDOWN; pev->sequence = SPOREAMMO_SNATCHDOWN;
pev->body = 0; pev->body = 0;
borntime = 1; pev->nextthink = gpGlobals->time + 0.66f;
m_flTimeSporeIdle = gpGlobals->time + 1;
SetThink (&CSporeAmmo::IdleThink); SetThink (&CSporeAmmo::IdleThink);
return 1; return 1;
} }
return 0; return 0;
} }
//=========================================================
// Thinking begin
//=========================================================
void CSporeAmmo :: BornThink ( void )
{
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 CSporeAmmo :: IdleThink ( void ) void CSporeAmmo :: IdleThink ( void )
{ {
switch (pev->sequence)
pev->nextthink = gpGlobals->time + 0.1; {
if ( m_flTimeSporeIdle > gpGlobals->time ) case SPOREAMMO_SPAWNDOWN:
return; {
pev->sequence = SPOREAMMO_IDLE1;
if (borntime) pev->animtime = gpGlobals->time;
pev->frame = 0;
break;
}
case SPOREAMMO_SNATCHDOWN:
{ {
pev->sequence = SPOREAMMO_IDLE; pev->sequence = SPOREAMMO_IDLE;
pev->animtime = gpGlobals->time;
m_flTimeSporeIdle = gpGlobals->time + 10; pev->frame = 0;
SetThink(&CSporeAmmo::BornThink); pev->nextthink = gpGlobals->time + 10.0f;
return; break;
} }
else case SPOREAMMO_IDLE:
{ {
pev->sequence = SPOREAMMO_IDLE1; pev->body = 1;
pev->sequence = SPOREAMMO_SPAWNDOWN;
pev->animtime = gpGlobals->time;
pev->frame = 0;
pev->nextthink = gpGlobals->time + 4.0f;
break;
}
default:
break;
} }
} }
void CSporeAmmo :: AmmoTouch ( CBaseEntity *pOther ) void CSporeAmmo :: AmmoTouch ( CBaseEntity *pOther )
{ {
if ( !pOther->IsPlayer() ) if ( !pOther->IsPlayer() || pev->body == 0 )
return;
if (borntime)
return; return;
int bResult = (pOther->GiveAmmo( AMMO_SPORE_GIVE, "spores", SPORE_MAX_CARRY ) != -1); int bResult = (pOther->GiveAmmo( AMMO_SPORE_GIVE, "spores", SPORE_MAX_CARRY ) != -1);
@ -204,12 +178,10 @@ void CSporeAmmo :: AmmoTouch ( CBaseEntity *pOther )
{ {
EMIT_SOUND(ENT(pev), CHAN_ITEM, "weapons/spore_ammo.wav", 1, ATTN_NORM); EMIT_SOUND(ENT(pev), CHAN_ITEM, "weapons/spore_ammo.wav", 1, ATTN_NORM);
pev->framerate = 1.0; pev->frame = 0;
pev->animtime = gpGlobals->time + 0.1; pev->animtime = gpGlobals->time;
pev->sequence = SPOREAMMO_SNATCHDOWN; pev->sequence = SPOREAMMO_SNATCHDOWN;
pev->body = 0; pev->body = 0;
borntime = 1; pev->nextthink = gpGlobals->time + 0.66f;
m_flTimeSporeIdle = gpGlobals->time + 1;
SetThink (&CSporeAmmo::IdleThink);
} }
} }

454
dlls/gearbox/sporegrenade.cpp

@ -25,335 +25,301 @@
#include "gamerules.h" #include "gamerules.h"
#include "decals.h" #include "decals.h"
#include "sporegrenade.h" #include "sporegrenade.h"
#include "gearbox_weapons.h"
LINK_ENTITY_TO_CLASS(spore, CSporeGrenade) LINK_ENTITY_TO_CLASS(spore, CSpore)
TYPEDESCRIPTION CSporeGrenade::m_SaveData[] = TYPEDESCRIPTION CSpore::m_SaveData[] =
{ {
DEFINE_FIELD(CSporeGrenade, m_pSporeGlow, FIELD_CLASSPTR), DEFINE_FIELD(CSpore, m_SporeType, FIELD_INTEGER),
DEFINE_FIELD(CSpore, m_flIgniteTime, FIELD_TIME),
DEFINE_FIELD(CSpore, m_bIsAI, FIELD_BOOLEAN),
DEFINE_FIELD(CSpore, m_hSprite, FIELD_EHANDLE)
}; };
IMPLEMENT_SAVERESTORE(CSporeGrenade, CBaseMonster) IMPLEMENT_SAVERESTORE(CSpore, CGrenade)
int gSporeExplode, gSporeExplodeC; int gSporeExplode, gSporeExplodeC;
void CSporeGrenade::Precache(void) void CSpore::Precache(void)
{ {
PRECACHE_MODEL("models/spore.mdl"); PRECACHE_MODEL("models/spore.mdl");
PRECACHE_MODEL("sprites/glow02.spr"); PRECACHE_MODEL("sprites/glow01.spr");
g_sModelIndexTinySpit = PRECACHE_MODEL("sprites/tinyspit.spr");
gSporeExplode = PRECACHE_MODEL ("sprites/spore_exp_01.spr"); m_iBlow = PRECACHE_MODEL("sprites/spore_exp_01.spr");
gSporeExplodeC = PRECACHE_MODEL ("sprites/spore_exp_c_01.spr"); m_iBlowSmall = PRECACHE_MODEL("sprites/spore_exp_c_01.spr");
m_iSpitSprite = m_iTrail = PRECACHE_MODEL("sprites/tinyspit.spr");
PRECACHE_SOUND("weapons/splauncher_bounce.wav"); PRECACHE_SOUND("weapons/splauncher_bounce.wav");
PRECACHE_SOUND("weapons/splauncher_impact.wav"); PRECACHE_SOUND("weapons/splauncher_impact.wav");
} }
void CSporeGrenade::Explode(TraceResult *pTrace) void CSpore::Spawn()
{ {
pev->solid = SOLID_NOT;// intangible Precache();
pev->takedamage = DAMAGE_NO;
if (m_SporeType == GRENADE)
pev->movetype = MOVETYPE_BOUNCE;
else
pev->movetype = MOVETYPE_FLY;
pev->solid = SOLID_BBOX;
// Pull out of the wall a bit SET_MODEL(edict(), "models/spore.mdl");
if (pTrace->flFraction != 1.0)
UTIL_SetSize(pev, g_vecZero, g_vecZero);
UTIL_SetOrigin(pev, pev->origin);
SetThink(&CSpore::FlyThink);
if (m_SporeType == GRENADE)
{
SetTouch(&CSpore::MyBounceTouch);
if (!m_bPuked)
{
pev->angles.x -= RANDOM_LONG(-5, 5) + 30;
}
}
else
{ {
pev->origin = pTrace->vecEndPos + (pTrace->vecPlaneNormal * (pev->dmg - 24) * 0.6); SetTouch(&CSpore::RocketTouch);
} }
Vector vecSpraySpot = pTrace->vecEndPos; UTIL_MakeVectors(pev->angles);
float flSpraySpeed = RANDOM_LONG(10, 15);
// If the trace is pointing up, then place if (!m_bIsAI)
// spawn position a few units higher. {
if (pTrace->vecPlaneNormal.z > 0) if (m_SporeType != GRENADE)
{ {
vecSpraySpot = vecSpraySpot + (pTrace->vecPlaneNormal * 8); pev->velocity = gpGlobals->v_forward * 1200;
flSpraySpeed *= 2; // Double the speed to make them fly higher
// in the air.
} }
// Spawn small particles at the explosion origin. pev->gravity = 1;
SpawnExplosionParticles( }
vecSpraySpot, // position
pTrace->vecPlaneNormal, // direction
g_sModelIndexTinySpit, // modelindex
RANDOM_LONG(40, 50), // count
flSpraySpeed, // speed
RANDOM_FLOAT(600, 640)); // noise
MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
WRITE_BYTE( TE_SPRITE );
WRITE_COORD( pev->origin.x );
WRITE_COORD( pev->origin.y );
WRITE_COORD( pev->origin.z );
WRITE_SHORT( RANDOM_LONG( 0, 1 ) ? gSporeExplode : gSporeExplodeC );
WRITE_BYTE( 25 ); // scale * 10
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);
CSoundEnt::InsertSound(bits_SOUND_COMBAT, pev->origin, NORMAL_EXPLOSION_VOLUME, 3.0);
entvars_t *pevOwner;
if (pev->owner)
pevOwner = VARS(pev->owner);
else else
pevOwner = NULL; {
pev->gravity = 0.5;
pev->friction = 0.7;
}
pev->owner = NULL; // can't traceline attack owner if this is set pev->dmg = gSkillData.plrDmgSpore;
RadiusDamage(pev, pevOwner, pev->dmg, CLASS_NONE, DMG_BLAST); m_flIgniteTime = gpGlobals->time;
// Place a decal on the surface that was hit. pev->nextthink = gpGlobals->time + 0.01;
UTIL_DecalTrace(pTrace, DECAL_SPR_SPLT1 + RANDOM_LONG(0, 2));
UTIL_Remove(this); CSprite* sprite = CSprite::SpriteCreate("sprites/glow01.spr", pev->origin, false);
} if (sprite) {
sprite->SetTransparency(kRenderTransAdd, 180, 180, 40, 100, kRenderFxDistort);
sprite->SetScale(0.8);
sprite->SetAttachment(edict(), 0);
m_hSprite = sprite;
}
void CSporeGrenade::Detonate(void) m_fRegisteredSound = false;
{
TraceResult tr;
Vector vecSpot = pev->origin + Vector(0, 0, 8);
UTIL_TraceLine(vecSpot, vecSpot + Vector(0, 0, -40), ignore_monsters, ENT(pev), &tr);
Explode(&tr); m_flSoundDelay = gpGlobals->time;
} }
void CSpore::BounceSound()
void CSporeGrenade::BounceSound(void)
{ {
DangerSound(); //Nothing
EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/splauncher_bounce.wav", 0.25, ATTN_NORM);
} }
void CSporeGrenade::DangerSound() void CSpore::IgniteThink()
{ {
CSoundEnt::InsertSound(bits_SOUND_DANGER, pev->origin + pev->velocity * 0.5, pev->velocity.Length(), 0.2); SetThink(NULL);
} SetTouch(NULL);
void CSporeGrenade::TumbleThink(void) if (m_hSprite)
{
if (!IsInWorld())
{ {
UTIL_Remove(this); UTIL_Remove(m_hSprite);
return; m_hSprite = 0;
} }
pev->nextthink = gpGlobals->time + 0.1; EMIT_SOUND(edict(), CHAN_WEAPON, "weapons/splauncher_impact.wav", VOL_NORM, ATTN_NORM);
if (pev->dmgtime - 1 < gpGlobals->time) const Vector vecDir = pev->velocity.Normalize();
{
CSoundEnt::InsertSound(bits_SOUND_DANGER, pev->origin + pev->velocity * (pev->dmgtime - gpGlobals->time), 400, 0.1);
}
if (pev->dmgtime <= gpGlobals->time) TraceResult tr;
{
SetThink(&CSporeGrenade::Detonate); UTIL_TraceLine(
} pev->origin, pev->origin + vecDir * (m_SporeType == GRENADE ? 64 : 32),
dont_ignore_monsters, edict(), &tr);
UTIL_DecalTrace(&tr, DECAL_SPR_SPLT1 + RANDOM_LONG(0, 2));
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, pev->origin);
WRITE_BYTE(TE_SPRITE_SPRAY);
WRITE_COORD( pev->origin.x );
WRITE_COORD( pev->origin.y );
WRITE_COORD( pev->origin.z );
WRITE_COORD( tr.vecPlaneNormal.x );
WRITE_COORD( tr.vecPlaneNormal.y );
WRITE_COORD( tr.vecPlaneNormal.z );
WRITE_SHORT(m_iSpitSprite);
WRITE_BYTE(100);
WRITE_BYTE(40);
WRITE_BYTE(180);
MESSAGE_END();
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, pev->origin);
WRITE_BYTE(TE_DLIGHT);
WRITE_COORD( pev->origin.x );
WRITE_COORD( pev->origin.y );
WRITE_COORD( pev->origin.z );
WRITE_BYTE(10);
WRITE_BYTE(15);
WRITE_BYTE(220);
WRITE_BYTE(40);
WRITE_BYTE(5);
WRITE_BYTE(10);
MESSAGE_END();
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, pev->origin);
WRITE_BYTE(TE_SPRITE);
WRITE_COORD( pev->origin.x );
WRITE_COORD( pev->origin.y );
WRITE_COORD( pev->origin.z );
WRITE_SHORT(RANDOM_LONG(0, 1) ? m_iBlow : m_iBlowSmall);
WRITE_BYTE(20);
WRITE_BYTE(128);
MESSAGE_END();
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, pev->origin);
WRITE_BYTE(TE_SPRITE_SPRAY);
WRITE_COORD( pev->origin.x );
WRITE_COORD( pev->origin.y );
WRITE_COORD( pev->origin.z );
WRITE_COORD(RANDOM_FLOAT(-1, 1));
WRITE_COORD(1);
WRITE_COORD(RANDOM_FLOAT(-1, 1));
WRITE_SHORT(m_iTrail);
WRITE_BYTE(2);
WRITE_BYTE(20);
WRITE_BYTE(80);
MESSAGE_END();
::RadiusDamage(pev->origin, pev, VARS(pev->owner), pev->dmg, 200, CLASS_NONE, DMG_ALWAYSGIB | DMG_BLAST);
// Spawn particles. SetThink(&CSpore::SUB_Remove);
SpawnTrailParticles(
pev->origin, // position pev->nextthink = gpGlobals->time;
-pev->velocity.Normalize(), // dir
g_sModelIndexTinySpit, // modelindex
RANDOM_LONG( 2, 4 ), // count
RANDOM_FLOAT(10, 15), // speed
RANDOM_FLOAT(2, 3) * 100); // noise ( client will divide by 100 )
} }
// void CSpore::FlyThink()
// Contact grenade, explode when it touches something
//
void CSporeGrenade::ExplodeTouch(CBaseEntity *pOther)
{ {
TraceResult tr; const float flDelay = m_bIsAI ? 4.0 : 2.0;
Vector vecSpot;// trace starts here!
if (m_SporeType != GRENADE || (gpGlobals->time <= m_flIgniteTime + flDelay))
{
Vector velocity = pev->velocity.Normalize();
pev->enemy = pOther->edict(); MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, pev->origin);
WRITE_BYTE(TE_SPRITE_SPRAY);
WRITE_COORD( pev->origin.x );
WRITE_COORD( pev->origin.y );
WRITE_COORD( pev->origin.z );
WRITE_COORD( velocity.x );
WRITE_COORD( velocity.y );
WRITE_COORD( velocity.z );
WRITE_SHORT(m_iTrail);
WRITE_BYTE(2);
WRITE_BYTE(20);
WRITE_BYTE(80);
MESSAGE_END();
}
else
{
SetThink(&CSpore::IgniteThink);
}
vecSpot = pev->origin - pev->velocity.Normalize() * 32; pev->nextthink = gpGlobals->time + 0.03;
UTIL_TraceLine(vecSpot, vecSpot + pev->velocity.Normalize() * 64, ignore_monsters, ENT(pev), &tr); }
Explode(&tr); void CSpore::GibThink()
{
//Nothing
} }
void CSporeGrenade::DangerSoundThink(void) void CSpore::RocketTouch(CBaseEntity* pOther)
{ {
if (!IsInWorld()) if (pOther->pev->takedamage != DAMAGE_NO)
{ {
UTIL_Remove(this); pOther->TakeDamage(pev, VARS(pev->owner), gSkillData.plrDmgSpore, DMG_GENERIC);
return;
} }
DangerSound(); IgniteThink();
pev->nextthink = gpGlobals->time + 0.2;
// Spawn particles.
SpawnTrailParticles(
pev->origin, // position
-pev->velocity.Normalize(), // dir
g_sModelIndexTinySpit, // modelindex
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) void CSpore::MyBounceTouch(CBaseEntity* pOther)
{ {
if ( !pOther->pev->takedamage ) if (pOther->pev->takedamage == DAMAGE_NO)
{ {
if (!(pev->flags & FL_ONGROUND)) { if (pOther->edict() != pev->owner)
if (pev->dmg_save < gpGlobals->time) { {
BounceSound(); if (gpGlobals->time > m_flSoundDelay)
pev->dmg_save = gpGlobals->time + 0.1; {
} CSoundEnt::InsertSound(bits_SOUND_DANGER, pev->origin, (int)(pev->dmg * 2.5f), 0.3);
} else {
pev->velocity = pev->velocity * 0.9; m_flSoundDelay = gpGlobals->time + 1.0;
} }
if (pev->flags & FL_SWIM)
if ((pev->flags & FL_ONGROUND) != 0)
{ {
pev->velocity = pev->velocity * 0.5; pev->velocity = pev->velocity * 0.5;
} }
else
{
EMIT_SOUND_DYN(edict(), CHAN_VOICE, "weapons/splauncher_bounce.wav", 0.25, ATTN_NORM, 0, PITCH_NORM);
}
}
} }
else else
{ {
TraceResult tr = UTIL_GetGlobalTrace(); pOther->TakeDamage(pev, VARS(pev->owner), gSkillData.plrDmgSpore, DMG_GENERIC);
Explode(&tr);
IgniteThink();
} }
} }
void CSporeGrenade::Spawn(void) CSpore* CSpore::CreateSpore(const Vector& vecOrigin, const Vector& vecAngles, CBaseEntity* pOwner, SporeType sporeType, bool bIsAI, bool bPuked)
{ {
Precache(); CSpore* pSpore = GetClassPtr<CSpore>(NULL);
pev->classname = MAKE_STRING("spore");
pev->movetype = MOVETYPE_BOUNCE;
pev->solid = SOLID_BBOX;
SET_MODEL(ENT(pev), "models/spore.mdl"); UTIL_SetOrigin(pSpore->pev, vecOrigin);
UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0));
//pev->gravity = 0.5; pSpore->m_SporeType = sporeType;
pev->dmg = gSkillData.plrDmgSpore; if (bIsAI)
m_pSporeGlow = CSprite::SpriteCreate("sprites/glow02.spr", pev->origin, FALSE);
if (m_pSporeGlow)
{ {
m_pSporeGlow->SetTransparency(kRenderGlow, 150, 158, 19, 155, kRenderFxNoDissipation); pSpore->pev->velocity = vecAngles;
m_pSporeGlow->SetAttachment(edict(), 0);
m_pSporeGlow->SetScale(.75f);
}
}
CBaseEntity* CSporeGrenade::ShootTimed(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, bool ai) pSpore->pev->angles = UTIL_VecToAngles(vecAngles);
{
CSporeGrenade *pGrenade = GetClassPtr((CSporeGrenade *)NULL);
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
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; else
pGrenade->SetThink(&CSporeGrenade::TumbleThink);
pGrenade->pev->nextthink = gpGlobals->time + 0.1;
if (lifetime < 0.1)
{ {
pGrenade->pev->nextthink = gpGlobals->time; pSpore->pev->angles = vecAngles;
pGrenade->pev->velocity = Vector(0, 0, 0);
} }
return pGrenade; pSpore->m_bIsAI = bIsAI;
} pSpore->m_bPuked = bPuked;
CBaseEntity *CSporeGrenade::ShootContact(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity) pSpore->Spawn();
{
CSporeGrenade *pGrenade = GetClassPtr((CSporeGrenade *)NULL);
UTIL_SetOrigin(pGrenade->pev, vecStart);
pGrenade->Spawn();
pGrenade->pev->movetype = MOVETYPE_FLY;
pGrenade->pev->velocity = vecVelocity;
pGrenade->pev->angles = UTIL_VecToAngles(pGrenade->pev->velocity);
pGrenade->pev->owner = ENT(pevOwner);
// make monsters afraid of it while in the air
pGrenade->SetThink(&CSporeGrenade::DangerSoundThink);
pGrenade->pev->nextthink = gpGlobals->time;
// Explode on contact
pGrenade->SetTouch(&CSporeGrenade::ExplodeTouch);
pGrenade->pev->gravity = 0.5;
pGrenade->pev->friction = 0.7;
return pGrenade;
}
void CSporeGrenade::SpawnTrailParticles(const Vector& origin, const Vector& direction, int modelindex, int count, float speed, float noise)
{
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, origin);
WRITE_BYTE(TE_SPRITE_SPRAY);
WRITE_COORD(origin.x); // pos
WRITE_COORD(origin.y);
WRITE_COORD(origin.z);
WRITE_COORD(direction.x); // dir
WRITE_COORD(direction.y);
WRITE_COORD(direction.z);
WRITE_SHORT(modelindex); // model
WRITE_BYTE(count); // count
WRITE_BYTE(speed); // speed
WRITE_BYTE(noise); // noise ( client will divide by 100 )
MESSAGE_END();
}
void CSporeGrenade::SpawnExplosionParticles(const Vector& origin, const Vector& direction, int modelindex, int count, float speed, float noise) pSpore->pev->owner = pOwner->edict();
{ pSpore->pev->classname = MAKE_STRING("spore");
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, origin); return pSpore;
WRITE_BYTE(TE_SPRITE_SPRAY);
WRITE_COORD(origin.x); // pos
WRITE_COORD(origin.y);
WRITE_COORD(origin.z);
WRITE_COORD(direction.x); // dir
WRITE_COORD(direction.y);
WRITE_COORD(direction.z);
WRITE_SHORT(modelindex); // model
WRITE_BYTE(count); // count
WRITE_BYTE(speed); // speed
WRITE_BYTE(noise); // noise ( client will divide by 100 )
MESSAGE_END();
} }
void CSporeGrenade::UpdateOnRemove() void CSpore::UpdateOnRemove()
{ {
CBaseMonster::UpdateOnRemove(); CGrenade::UpdateOnRemove();
if (m_pSporeGlow) if (m_hSprite)
{ {
UTIL_Remove(m_pSporeGlow); UTIL_Remove(m_hSprite);
m_pSporeGlow = NULL; m_hSprite = 0;
} }
} }

56
dlls/gearbox/sporegrenade.h

@ -17,36 +17,54 @@
#define SPORE_GRENADE_H #define SPORE_GRENADE_H
// Contact/Timed spore grenade // Contact/Timed spore grenade
class CSporeGrenade : public CBaseMonster class CSpore : public CGrenade
{ {
public: public:
virtual int Save(CSave &save); enum SporeType
virtual int Restore(CRestore &restore); {
ROCKET = 1,
GRENADE = 2
};
public:
#ifndef CLIENT_DLL
int Save(CSave& save);
int Restore(CRestore& restore);
static TYPEDESCRIPTION m_SaveData[]; static TYPEDESCRIPTION m_SaveData[];
#endif
void Precache();
void Spawn();
void UpdateOnRemove();
void Precache(void); void BounceSound();
void Spawn(void);
static CBaseEntity *ShootTimed(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, bool ai); void EXPORT IgniteThink();
static CBaseEntity *ShootContact(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity); void EXPORT FlyThink();
void EXPORT GibThink();
void EXPORT RocketTouch(CBaseEntity* pOther);
void EXPORT MyBounceTouch(CBaseEntity* pOther);
void Explode(TraceResult *pTrace); static CSpore* CreateSpore(
const Vector& vecOrigin, const Vector& vecAngles, CBaseEntity* pOwner,
SporeType sporeType, bool bIsAI, bool bPuked);
void EXPORT BounceTouch(CBaseEntity *pOther); private:
void EXPORT ExplodeTouch(CBaseEntity *pOther); int m_iBlow;
void EXPORT DangerSoundThink(void); int m_iBlowSmall;
void EXPORT Detonate(void);
void EXPORT TumbleThink(void);
void BounceSound(void); int m_iSpitSprite;
void DangerSound(); int m_iTrail;
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(); SporeType m_SporeType;
float m_flIgniteTime;
float m_flSoundDelay;
CSprite* m_pSporeGlow; BOOL m_bIsAI;
EHANDLE m_hSprite;
BOOL m_bPuked;
}; };
#endif // SPORE_GRENADE_H #endif // SPORE_GRENADE_H

20
dlls/gearbox/sporelauncher.cpp

@ -134,12 +134,16 @@ void CSporelauncher::PrimaryAttack()
// m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH; // m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH;
m_pPlayer->SetAnimation(PLAYER_ATTACK1); m_pPlayer->SetAnimation(PLAYER_ATTACK1);
UTIL_MakeVectors( m_pPlayer->pev->v_angle ); Vector vecAngles = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle;
UTIL_MakeVectors(vecAngles);
Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -8; Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -8;
#if !CLIENT_DLL #if !CLIENT_DLL
UTIL_MakeVectors( m_pPlayer->pev->v_angle ); CSpore* pSpore = CSpore::CreateSpore(vecSrc, vecAngles, m_pPlayer, CSpore::ROCKET, false, false);
CSporeGrenade::ShootContact( m_pPlayer->pev, vecSrc, gpGlobals->v_forward * 1500 );
UTIL_MakeVectors(vecAngles);
pSpore->pev->velocity = pSpore->pev->velocity + DotProduct(pSpore->pev->velocity, gpGlobals->v_forward) * gpGlobals->v_forward;
#endif #endif
PLAYBACK_EVENT_FULL( PLAYBACK_EVENT_FULL(
@ -198,12 +202,16 @@ void CSporelauncher::SecondaryAttack(void)
// player "shoot" animation // player "shoot" animation
m_pPlayer->SetAnimation(PLAYER_ATTACK1); m_pPlayer->SetAnimation(PLAYER_ATTACK1);
UTIL_MakeVectors( m_pPlayer->pev->v_angle ); Vector vecAngles = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle;
UTIL_MakeVectors(vecAngles);
Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -8; Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -8;
#if !CLIENT_DLL #if !CLIENT_DLL
UTIL_MakeVectors( m_pPlayer->pev->v_angle ); CSpore* pSpore = CSpore::CreateSpore( vecSrc, vecAngles, m_pPlayer, CSpore::GRENADE, false, false);
CSporeGrenade::ShootTimed(m_pPlayer->pev, vecSrc, gpGlobals->v_forward * 1000, false);
UTIL_MakeVectors(vecAngles);
pSpore->pev->velocity = m_pPlayer->pev->velocity + 800 * gpGlobals->v_forward;
#endif #endif
PLAYBACK_EVENT_FULL( PLAYBACK_EVENT_FULL(

2
dlls/gearbox/strooper.cpp

@ -313,7 +313,7 @@ void CStrooper::HandleAnimEvent(MonsterEvent_t *pEvent)
{ {
UTIL_MakeVectors(pev->angles); UTIL_MakeVectors(pev->angles);
// CGrenade::ShootTimed( pev, pev->origin + gpGlobals->v_forward * 34 + Vector (0, 0, 32), m_vecTossVelocity, 3.5 ); // CGrenade::ShootTimed( pev, pev->origin + gpGlobals->v_forward * 34 + Vector (0, 0, 32), m_vecTossVelocity, 3.5 );
CSporeGrenade::ShootTimed(pev, pev->origin + Vector(0,0,98), m_vecTossVelocity, 3.5); CSpore::CreateSpore(pev->origin + Vector(0, 0, 98), m_vecTossVelocity, this, CSpore::GRENADE, true, false);
m_fThrowGrenade = FALSE; m_fThrowGrenade = FALSE;
m_flNextGrenadeCheck = gpGlobals->time + 6;// wait six seconds before even looking again to see if a grenade can be thrown. m_flNextGrenadeCheck = gpGlobals->time + 6;// wait six seconds before even looking again to see if a grenade can be thrown.

15
dlls/weapons.cpp

@ -30,7 +30,6 @@
#include "soundent.h" #include "soundent.h"
#include "decals.h" #include "decals.h"
#include "gamerules.h" #include "gamerules.h"
#include "gearbox_weapons.h"
extern CGraph WorldGraph; extern CGraph WorldGraph;
extern int gEvilImpulse101; extern int gEvilImpulse101;
@ -47,13 +46,6 @@ DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model
DLL_GLOBAL short g_sModelIndexBloodDrop;// holds the sprite index for the initial blood DLL_GLOBAL short g_sModelIndexBloodDrop;// holds the sprite index for the initial blood
DLL_GLOBAL short g_sModelIndexBloodSpray;// holds the sprite index for splattered blood DLL_GLOBAL short g_sModelIndexBloodSpray;// holds the sprite index for splattered blood
DLL_GLOBAL short g_sModelIndexSpore1; // holds the index for the spore explosion 1
DLL_GLOBAL short g_sModelIndexSpore2; // holds the index for the spore explosion 2
DLL_GLOBAL short g_sModelIndexSpore3; // holds the index for the spore explosion 3
DLL_GLOBAL short g_sModelIndexBigSpit; // holds the index for the bullsquid big spit.
DLL_GLOBAL short g_sModelIndexTinySpit; // holds the index for the bullsquid tiny spit.
ItemInfo CBasePlayerItem::ItemInfoArray[MAX_WEAPONS]; ItemInfo CBasePlayerItem::ItemInfoArray[MAX_WEAPONS];
AmmoInfo CBasePlayerItem::AmmoInfoArray[MAX_AMMO_SLOTS]; AmmoInfo CBasePlayerItem::AmmoInfoArray[MAX_AMMO_SLOTS];
@ -418,13 +410,6 @@ void W_Precache( void )
// Used by spore grenades. // Used by spore grenades.
PRECACHE_MODEL( "models/spore.mdl" ); PRECACHE_MODEL( "models/spore.mdl" );
g_sModelIndexSpore1 = PRECACHE_MODEL( "sprites/spore_exp_01.spr" );
g_sModelIndexSpore2 = PRECACHE_MODEL( "sprites/spore_exp_b_01.spr" );
g_sModelIndexSpore3 = PRECACHE_MODEL( "sprites/spore_exp_c_01.spr" );
g_sModelIndexBigSpit = PRECACHE_MODEL( "sprites/bigspit.spr" );
g_sModelIndexTinySpit = PRECACHE_MODEL( "sprites/tinyspit.spr" );
PRECACHE_SOUND( "weapons/splauncher_impact.wav" );//explosion aftermaths PRECACHE_SOUND( "weapons/splauncher_impact.wav" );//explosion aftermaths
PRECACHE_SOUND( "weapons/spore_hit1.wav" );//sporegrenade PRECACHE_SOUND( "weapons/spore_hit1.wav" );//sporegrenade

3
dlls/weapons.h

@ -427,9 +427,6 @@ extern DLL_GLOBAL short g_sModelIndexSpore1;
extern DLL_GLOBAL short g_sModelIndexSpore2; extern DLL_GLOBAL short g_sModelIndexSpore2;
extern DLL_GLOBAL short g_sModelIndexSpore3; extern DLL_GLOBAL short g_sModelIndexSpore3;
extern DLL_GLOBAL short g_sModelIndexBigSpit;
extern DLL_GLOBAL short g_sModelIndexTinySpit;
extern void ClearMultiDamage(void); extern void ClearMultiDamage(void);
extern void ApplyMultiDamage(entvars_t* pevInflictor, entvars_t* pevAttacker ); extern void ApplyMultiDamage(entvars_t* pevInflictor, entvars_t* pevAttacker );
extern void AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType); extern void AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType);

Loading…
Cancel
Save