mirror of
https://github.com/Gigaslav/HL2Overcharged.git
synced 2026-01-02 17:48:11 +03:00
768 lines
24 KiB
C++
768 lines
24 KiB
C++
//========= Overcharged 2019. ============//
|
|
//
|
|
// Purpose: Shock trooper instant grenade
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#include "cbase.h"
|
|
#include "grenade_strooper_instant.h"
|
|
#include "soundent.h"
|
|
#include "decals.h"
|
|
#include "shake.h"
|
|
#include "smoke_trail.h"
|
|
#include "vstdlib/random.h"
|
|
#include "engine/IEngineSound.h"
|
|
#include "world.h"
|
|
#include "BloodDripsGreen.h"
|
|
#include "hl2_shareddefs.h"
|
|
#include "te_effect_dispatch.h"
|
|
|
|
#include "IEffects.h"
|
|
|
|
|
|
extern short g_sModelIndexFireball;
|
|
extern short g_sModelIndexWExplosion;
|
|
#define SPRITE "particles/particle_glow/particle_glow_03.vmt"
|
|
//extern ConVar sk_plr_dmg_instant_grenade;
|
|
//ConVar sk_plr_dmg_instant_grenade("sk_plr_dmg_instant_grenade", "40", FCVAR_NONE);
|
|
//ConVar sk_max_instant_grenade("sk_max_instant_grenade", "10", FCVAR_NONE);
|
|
|
|
/*ConVar sk_spore_launcher_sprite_r("sk_spore_launcher_sprite_r", "0");
|
|
ConVar sk_spore_launcher_sprite_g("sk_spore_launcher_sprite_g", "0");
|
|
ConVar sk_spore_launcher_sprite_b("sk_spore_launcher_sprite_b", "0");
|
|
ConVar sk_spore_launcher_sprite_a("sk_spore_launcher_sprite_a", "0");
|
|
ConVar sk_spore_launcher_sprite_scale("sk_spore_launcher_sprite_scale", "0");*/
|
|
//extern ConVar sk_max_instant_grenade;
|
|
//extern ConVar sk_instant_grenade_radius;
|
|
|
|
BEGIN_DATADESC(CSporeLauncherBouncedProjectile)
|
|
// SR-BUGBUG: These are borked!!!!
|
|
// float m_fSpawnTime;
|
|
|
|
// Function pointers
|
|
DEFINE_ENTITYFUNC( grenade_strooper_instantTouch ),
|
|
DEFINE_THINKFUNC(Think),
|
|
DEFINE_FIELD( m_fSpawnTime, FIELD_TIME ),
|
|
DEFINE_FIELD(lifetime, FIELD_FLOAT),
|
|
END_DATADESC()
|
|
|
|
LINK_ENTITY_TO_CLASS(spore_launcher_bounced_projectile, CSporeLauncherBouncedProjectile);
|
|
|
|
CSporeLauncherBouncedProjectile *CSporeLauncherBouncedProjectile::SporeCreate(const Vector &vecOrigin, const Vector &vecFwd, const QAngle &angAngles, CBaseEntity *pentOwner)
|
|
{
|
|
// Create a new entity with CShockRifleProjectile private data
|
|
CSporeLauncherBouncedProjectile *Sphere = (CSporeLauncherBouncedProjectile *)CreateEntityByName("spore_launcher_bounced_projectile");
|
|
|
|
UTIL_SetOrigin(Sphere, vecOrigin);
|
|
Sphere->SetAbsAngles(angAngles);
|
|
|
|
Vector vel = (vecOrigin + vecFwd) * cvar->FindVar("oc_sporegenerator_projectile_impulse")->GetFloat();
|
|
Sphere->SetAbsVelocity(vel);
|
|
Sphere->Spawn();
|
|
Sphere->SetOwnerEntity(pentOwner);
|
|
|
|
return Sphere;
|
|
}
|
|
|
|
bool CSporeLauncherBouncedProjectile::CreateSprites(void)
|
|
{
|
|
//DispatchParticleEffect("hunter_flechette_trail", PATTACH_ABSORIGIN_FOLLOW, this);
|
|
//DispatchParticleEffect("Shockrifle_projectile", PATTACH_ABSORIGIN_FOLLOW, this);
|
|
|
|
|
|
|
|
// Create the dust effect in place
|
|
m_hSpitEffectA = (CParticleSystem *)CreateEntityByName("info_particle_system");
|
|
if (m_hSpitEffectA != NULL)
|
|
{
|
|
// Setup our basic parameters
|
|
m_hSpitEffectA->KeyValue("start_active", "1");
|
|
m_hSpitEffectA->KeyValue("effect_name", "antlion_spit_trail");
|
|
m_hSpitEffectA->SetParent(this);
|
|
m_hSpitEffectA->SetLocalOrigin(vec3_origin);
|
|
DispatchSpawn(m_hSpitEffectA);
|
|
if (gpGlobals->curtime > 0.5f)
|
|
m_hSpitEffectA->Activate();
|
|
}
|
|
|
|
/*m_hSpitEffectC = (CParticleSystem *)CreateEntityByName("info_particle_system");
|
|
if (m_hSpitEffectC != NULL)
|
|
{
|
|
// Setup our basic parameters
|
|
m_hSpitEffectC->KeyValue("start_active", "1");
|
|
m_hSpitEffectC->KeyValue("effect_name", "Spore_launcher_acid_glow");
|
|
m_hSpitEffectC->SetParent(this);
|
|
m_hSpitEffectC->SetAbsOrigin(GetAbsOrigin());
|
|
m_hSpitEffectC->SetLocalOrigin(GetAbsOrigin());
|
|
//m_hSpitEffectC->SetLocalOrigin(GetAbsOrigin());
|
|
//DispatchSpawn(m_hSpitEffectC);
|
|
//if (gpGlobals->curtime > 0.5f)
|
|
m_hSpitEffectC->FollowEntity(this, true);
|
|
m_hSpitEffectC->Activate();
|
|
}*/
|
|
if (m_hSpitEffectC == NULL)
|
|
{
|
|
m_hSpitEffectC = CSprite::SpriteCreate(SPRITE, GetAbsOrigin(), false);
|
|
|
|
if (m_hSpitEffectC == NULL)
|
|
{
|
|
// We were unable to create the sprite
|
|
Assert(0);
|
|
return false;
|
|
}
|
|
m_hSpitEffectC->SetParent(this);
|
|
m_hSpitEffectC->FollowEntity(this);
|
|
//m_hSpitEffectC->SetAttachment(pOwner->GetViewModel(), LookupAttachment("laser"));
|
|
m_hSpitEffectC->SetTransparency(kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation);
|
|
m_hSpitEffectC->SetBrightness(/*sk_spore_launcher_sprite_a.GetInt()*/40, 0.5f);
|
|
m_hSpitEffectC->SetColor(/*sk_spore_launcher_sprite_r.GetInt()*/45, /*sk_spore_launcher_sprite_g.GetInt()*/180, /*sk_spore_launcher_sprite_b.GetInt()*/60);
|
|
m_hSpitEffectC->SetScale(/*sk_spore_launcher_sprite_scale.GetFloat()*/0.5f, 0.5f);
|
|
m_hSpitEffectC->TurnOn();
|
|
}
|
|
else
|
|
{
|
|
m_hSpitEffectC->TurnOn();
|
|
/*m_hSpitEffectC->SetScale(0.25f, 0.25f);
|
|
m_hSpitEffectC->SetBrightness(255);*/
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CSporeLauncherBouncedProjectile::Spawn(void)
|
|
{
|
|
Precache( );
|
|
SetSolid(SOLID_BBOX);
|
|
AddSolidFlags(FSOLID_NOT_STANDABLE);//
|
|
SetCollisionGroup(HL2COLLISION_GROUP_SPIT);
|
|
//SetCollisionGroup(COLLISION_GROUP_INTERACTIVE_DEBRIS | COLLISION_GROUP_INTERACTIVE | COLLISION_GROUP_PLAYER | COLLISION_GROUP_NPC);//
|
|
//SetMoveType( MOVETYPE_FLY );
|
|
SetMoveType(MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE);//
|
|
AddFlag( FL_GRENADE );
|
|
AddEFlags(EFL_FORCE_CHECK_TRANSMIT);
|
|
SetModel("models/spitball_medium.mdl");
|
|
|
|
UTIL_SetSize(this, Vector(2, 2, 2), Vector(2, 2, 2));
|
|
//DispatchParticleEffect("grenade_spit_trail", PATTACH_ABSORIGIN_FOLLOW, this);
|
|
CreateSprites();
|
|
//DispatchParticleEffect("Spore_launcher_acid_glow", PATTACH_ABSORIGIN_FOLLOW, this);
|
|
//SetUse( &CBaseGrenade::DetonateUse );
|
|
SetTouch(&CSporeLauncherBouncedProjectile::grenade_strooper_instantTouch);
|
|
SetThink(&CSporeLauncherBouncedProjectile::Think);
|
|
SetNextThink(gpGlobals->curtime);
|
|
|
|
m_flDamage = cvar->FindVar("sk_plr_dmg_spore_acid_bounce")->GetFloat();
|
|
m_DmgRadius = cvar->FindVar("sk_spore_acid_radius")->GetFloat();
|
|
m_takedamage = DAMAGE_YES;
|
|
m_bIsLive = true;
|
|
m_iHealth = 1;
|
|
|
|
SetGravity( UTIL_ScaleForGravity( 350 ) ); // use a lower gravity for grenades to make them easier to see //400
|
|
SetFriction( 0.8 );
|
|
|
|
//SetSequence( 0 );
|
|
|
|
|
|
//m_fSpawnTime = gpGlobals->curtime;
|
|
startVelocity = GetAbsVelocity();
|
|
velocity = 1.0f;
|
|
}
|
|
|
|
|
|
void CSporeLauncherBouncedProjectile::Event_Killed(CBaseEntity *pInflictor, CBaseEntity *pAttacker, float flDamage, int bitsDamageType)
|
|
{
|
|
Detonate( );
|
|
}
|
|
|
|
|
|
void CSporeLauncherBouncedProjectile::grenade_strooper_instantTouch(CBaseEntity *pOther)
|
|
{
|
|
if (pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS | FSOLID_TRIGGER))
|
|
{
|
|
// Some NPCs are triggers that can take damage (like antlion grubs). We should hit them.
|
|
if ((pOther->m_takedamage == DAMAGE_NO) || (pOther->m_takedamage == DAMAGE_EVENTS_ONLY))
|
|
return;
|
|
}
|
|
|
|
// Don't hit other spit
|
|
if (pOther->GetCollisionGroup() == HL2COLLISION_GROUP_SPIT)
|
|
return;
|
|
|
|
if (!pOther->IsSolid())
|
|
return;
|
|
|
|
//DevMsg("Touch\n");
|
|
// If I'm live go ahead and blow up
|
|
if (GetOwnerEntity() && pOther == GetOwnerEntity()->GetOwnerEntity())
|
|
{
|
|
StopParticleEffects(this);
|
|
UTIL_Remove(m_hSpitEffectA);
|
|
UTIL_Remove(m_hSpitEffectC);
|
|
UTIL_Remove(this);
|
|
return;
|
|
}
|
|
|
|
if (pOther && (pOther->IsNPC() || pOther->IsPlayer()))//(m_bIsLive)
|
|
{
|
|
Detonate();
|
|
}
|
|
else
|
|
{
|
|
velocity -= 0.1f;
|
|
|
|
trace_t tr;
|
|
tr = CBaseEntity::GetTouchTrace();
|
|
Vector abs = GetAbsVelocity() * 4 * velocity;//GetAbsVelocity() * velocity;
|
|
if (VectorLength(startVelocity)*4 > VectorLength(abs))
|
|
SetAbsVelocity(abs);
|
|
else
|
|
SetAbsVelocity(GetAbsVelocity());
|
|
|
|
//DevMsg("VectorLength absvel: %.2f \n", VectorLength(GetAbsVelocity()));
|
|
if (VectorLength(GetAbsVelocity()) <= 250.f)
|
|
{
|
|
Detonate();
|
|
}
|
|
|
|
//DevMsg("y: %.2f \n", GetAbsVelocity().y);
|
|
//DevMsg("z: %.2f \n", GetAbsVelocity().z);
|
|
if ((tr.m_pEnt != GetWorldEntity()) || (tr.hitbox != 0))
|
|
{
|
|
// non-world needs smaller decals
|
|
//UTIL_DecalTrace(&tr, "SpitSplat");
|
|
UTIL_DecalTrace(&tr, "YellowBlood");
|
|
}
|
|
else
|
|
{
|
|
//UTIL_DecalTrace(&tr, "SpitSplat");
|
|
UTIL_DecalTrace(&tr, "YellowBlood");
|
|
}
|
|
|
|
CPASAttenuationFilter filter(this);
|
|
EmitSound(filter, entindex(), "Weapon_spore_acid.bounce");
|
|
EmitSound(filter, entindex(), "Weapon_spore_acid.hit");
|
|
}
|
|
}
|
|
|
|
void CSporeLauncherBouncedProjectile::Detonate(void)
|
|
{
|
|
if (!m_bIsLive)
|
|
{
|
|
return;
|
|
}
|
|
m_bIsLive = false;
|
|
m_takedamage = DAMAGE_NO;
|
|
|
|
/*CPASFilter filter( GetAbsOrigin() );
|
|
|
|
te->Explosion( filter, 0.0,
|
|
&GetAbsOrigin(),
|
|
GetWaterLevel() == 0 ? g_sModelIndexFireball : g_sModelIndexWExplosion,
|
|
(m_flDamage - 50) * .60,
|
|
15,
|
|
TE_EXPLFLAG_NONE,
|
|
m_DmgRadius,
|
|
m_flDamage );*/
|
|
|
|
trace_t tr;
|
|
tr = CBaseEntity::GetTouchTrace();
|
|
|
|
/*if ( (tr.m_pEnt != GetWorldEntity()) || (tr.hitbox != 0) )
|
|
{
|
|
// non-world needs smaller decals
|
|
UTIL_DecalTrace( &tr, "SmallScorch");
|
|
}
|
|
else
|
|
{
|
|
UTIL_DecalTrace( &tr, "Scorch" );
|
|
}*/
|
|
for (int i = 0; i < cvar->FindVar("sk_spore_acid_maxdrips")->GetFloat(); i++)
|
|
{
|
|
Vector vecSpawn;
|
|
vecSpawn = this->WorldSpaceCenter();
|
|
/*vecSpawn.x += random->RandomFloat(-0.2, 0.2);
|
|
vecSpawn.y += random->RandomFloat(-12.1, 12.4);*/
|
|
//vecSpawn.z += 40;// random->RandomFloat(-20.1, 20.2);
|
|
Vector vecVelocity;
|
|
QAngle angles;
|
|
angles.x = random->RandomFloat(-360, 360);
|
|
angles.y = random->RandomFloat(-360, 360);
|
|
angles.z = random->RandomFloat(-360, 360);
|
|
AngleVectors(angles, &vecVelocity);
|
|
|
|
vecVelocity *= random->RandomFloat(150, 300);
|
|
vecVelocity += GetAbsVelocity();
|
|
|
|
CBloodDripsGreen *pGrenade = (CBloodDripsGreen*)CreateEntityByName("BloodDripsGreen");
|
|
//pGrenade->SetAbsOrigin(vecTraceDir);
|
|
pGrenade->SetLocalOrigin(vecSpawn);
|
|
pGrenade->SetAbsAngles(RandomAngle(-360, 360));
|
|
DispatchSpawn(pGrenade);
|
|
pGrenade->SetOwnerEntity(this);
|
|
pGrenade->SetAbsVelocity(vecVelocity);
|
|
|
|
}
|
|
//CSoundEnt::InsertSound ( SOUND_COMBAT, GetAbsOrigin(), BASEGRENADE_EXPLOSION_VOLUME, 3.0 );
|
|
lifetime = 0.f;
|
|
|
|
RadiusDamage(CTakeDamageInfo(this, GetThrower(), m_flDamage, DMG_BULLET), GetAbsOrigin(), cvar->FindVar("sk_spore_acid_radius")->GetFloat(), CLASS_NONE, NULL);
|
|
|
|
CPASAttenuationFilter filter2( this );
|
|
EmitSound( filter2, entindex(), "Weapon_spore_acid.impact" );
|
|
|
|
/*if ( GetWaterLevel() == 0 )
|
|
{
|
|
int sparkCount = random->RandomInt( 0,3 );
|
|
QAngle angles;
|
|
VectorAngles( tr.plane.normal, angles );
|
|
|
|
for ( int i = 0; i < sparkCount; i++ )
|
|
Create( "spark_shower", GetAbsOrigin(), angles, NULL );
|
|
}*/
|
|
float Radius = 110;
|
|
CPASFilter filter(GetAbsOrigin());
|
|
te->DynamicLight(filter, 0.0, &GetAbsOrigin(), random->RandomInt(10, 25), random->RandomInt(190, 255), random->RandomInt(25, 55), 3, Radius, random->RandomInt(0.018, 0.23), Radius / 0.5);//OverCharged
|
|
|
|
DispatchParticleEffect("grenade_spit", GetAbsOrigin(), GetAbsAngles());
|
|
/*if (GetEnemy()->IsPlayer())
|
|
{
|
|
// Do a lighter-weight effect if we just hit a player
|
|
DispatchParticleEffect("grenade_spit_player", GetAbsOrigin(), GetAbsAngles());
|
|
}
|
|
else
|
|
{
|
|
DispatchParticleEffect("grenade_spit", GetAbsOrigin(), GetAbsAngles());
|
|
}*/
|
|
StopParticleEffects(this);
|
|
//m_hSpitEffectA->StopParticleSystem();
|
|
UTIL_Remove(m_hSpitEffectA);
|
|
UTIL_Remove(m_hSpitEffectC);
|
|
UTIL_Remove( this );
|
|
}
|
|
|
|
void CSporeLauncherBouncedProjectile::Think(void)
|
|
{
|
|
//DevMsg("VectorLength absvel: %.2f \n", VectorLength(GetAbsVelocity()));
|
|
//DevMsg("lifetime: %.2f \n", lifetime);
|
|
if (lifetime < cvar->FindVar("sk_spore_acid_lifetime")->GetFloat())
|
|
{
|
|
lifetime++;
|
|
}
|
|
else
|
|
{
|
|
Detonate();
|
|
lifetime = 0;
|
|
}
|
|
|
|
// Set us up to think again shortly
|
|
SetNextThink(gpGlobals->curtime + 0.01f);
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CSporeLauncherBouncedProjectile::Precache(void)
|
|
{
|
|
BaseClass::Precache();
|
|
|
|
PrecacheModel( "models/grenade.mdl" );
|
|
PrecacheModel("models/spitball_large.mdl");
|
|
PrecacheModel("models/spitball_medium.mdl");
|
|
PrecacheModel("models/spitball_small.mdl");
|
|
PrecacheModel(SPRITE);
|
|
PrecacheScriptSound("GrenadeSpit.Hit");
|
|
PrecacheParticleSystem("Spore_launcher_acid_glow");
|
|
PrecacheParticleSystem("grenade_spit_player");
|
|
PrecacheParticleSystem("grenade_spit");
|
|
PrecacheParticleSystem("grenade_spit_trail");
|
|
PrecacheScriptSound( "grenade_strooper_instant.Detonate" );
|
|
PrecacheScriptSound("Weapon_spore_acid.hit");
|
|
PrecacheScriptSound("Weapon_spore_acid.bounce");
|
|
PrecacheScriptSound("Weapon_spore_acid.impact");
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define BOLT_SKIN_NORMAL 0
|
|
#define BOLT_SKIN_GLOW 1
|
|
#define BOLT_MODEL oc_grenade_spore_launcher_model.GetString() //"models/ShockRifle.mdl"
|
|
|
|
ConVar oc_grenade_spore_launcher_model("oc_grenade_spore_launcher_model", "models/spitball_small.mdl", FCVAR_REPLICATED | FCVAR_ARCHIVE, "Shock rifle projectile model.");
|
|
ConVar sk_plr_dmg_spore_launcher("sk_plr_dmg_spore_launcher", "30");
|
|
ConVar sk_npc_dmg_spore_launcher("sk_npc_dmg_spore_launcher", "30");
|
|
|
|
LINK_ENTITY_TO_CLASS(spore_launcher_projectile, CSporeLauncherProjectile);
|
|
|
|
BEGIN_DATADESC(CSporeLauncherProjectile)
|
|
// Function Pointers
|
|
DEFINE_FUNCTION(BubbleThink),
|
|
DEFINE_FUNCTION(BoltTouch),
|
|
|
|
// These are recreated on reload, they don't need storage
|
|
DEFINE_FIELD(m_hSpitEffectB, FIELD_EHANDLE),
|
|
|
|
END_DATADESC()
|
|
|
|
IMPLEMENT_SERVERCLASS_ST(CSporeLauncherProjectile, DT_SporeLauncherProjectile)
|
|
END_SEND_TABLE()
|
|
|
|
CSporeLauncherProjectile *CSporeLauncherProjectile::BoltCreate(const Vector &vecOrigin, const QAngle &angAngles, int iDamage, CBasePlayer *pentOwner)
|
|
{
|
|
// Create a new entity with CShockRifleProjectile private data
|
|
CSporeLauncherProjectile *pSporeLauncherProjectile = (CSporeLauncherProjectile *)CreateEntityByName("spore_launcher_projectile");
|
|
UTIL_SetOrigin(pSporeLauncherProjectile, vecOrigin);
|
|
pSporeLauncherProjectile->SetAbsAngles(angAngles);
|
|
pSporeLauncherProjectile->Spawn();
|
|
pSporeLauncherProjectile->SetOwnerEntity(pentOwner);
|
|
|
|
pSporeLauncherProjectile->m_iDamage = iDamage;
|
|
|
|
return pSporeLauncherProjectile;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
CSporeLauncherProjectile::~CSporeLauncherProjectile(void)
|
|
{
|
|
/*if (m_pGlowSprite)
|
|
{
|
|
UTIL_Remove(m_pGlowSprite);
|
|
}*/
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool CSporeLauncherProjectile::CreateVPhysics(void)
|
|
{
|
|
// Create the object in the physics system
|
|
VPhysicsInitNormal(SOLID_BBOX, FSOLID_NOT_STANDABLE, false);
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
unsigned int CSporeLauncherProjectile::PhysicsSolidMaskForEntity() const
|
|
{
|
|
return (BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_HITBOX) & ~CONTENTS_GRATE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool CSporeLauncherProjectile::CreateSprites(void)
|
|
{
|
|
//DispatchParticleEffect("hunter_flechette_trail", PATTACH_ABSORIGIN_FOLLOW, this);
|
|
//DispatchParticleEffect("Shockrifle_projectile", PATTACH_ABSORIGIN_FOLLOW, this);
|
|
|
|
|
|
|
|
// Create the dust effect in place
|
|
m_hSpitEffectD = (CParticleSystem *)CreateEntityByName("info_particle_system");
|
|
if (m_hSpitEffectD != NULL)
|
|
{
|
|
// Setup our basic parameters
|
|
m_hSpitEffectD->KeyValue("start_active", "1");
|
|
m_hSpitEffectD->KeyValue("effect_name", "antlion_spit_trail");
|
|
m_hSpitEffectD->SetParent(this);
|
|
m_hSpitEffectD->SetLocalOrigin(vec3_origin);
|
|
DispatchSpawn(m_hSpitEffectD);
|
|
if (gpGlobals->curtime > 0.5f)
|
|
m_hSpitEffectD->Activate();
|
|
}
|
|
|
|
/*m_hSpitEffectB = (CParticleSystem *)CreateEntityByName("info_particle_system");
|
|
if (m_hSpitEffectB != NULL)
|
|
{
|
|
// Setup our basic parameters
|
|
m_hSpitEffectB->KeyValue("start_active", "1");
|
|
m_hSpitEffectB->KeyValue("effect_name", "Spore_launcher_acid_glow");
|
|
m_hSpitEffectB->SetParent(this);
|
|
m_hSpitEffectB->SetAbsOrigin(GetAbsOrigin());
|
|
m_hSpitEffectB->SetLocalOrigin(GetAbsOrigin());
|
|
//m_hSpitEffectB->SetLocalOrigin(vec3_origin);
|
|
//DispatchSpawn(m_hSpitEffectB);
|
|
//if (gpGlobals->curtime > 0.5f)
|
|
m_hSpitEffectB->FollowEntity(this, true);
|
|
m_hSpitEffectB->Activate();
|
|
}*/
|
|
if (m_hSpitEffectB == NULL)
|
|
{
|
|
m_hSpitEffectB = CSprite::SpriteCreate(SPRITE, GetAbsOrigin(), false);
|
|
|
|
if (m_hSpitEffectB == NULL)
|
|
{
|
|
// We were unable to create the sprite
|
|
Assert(0);
|
|
return false;
|
|
}
|
|
m_hSpitEffectB->SetParent(this);
|
|
m_hSpitEffectB->FollowEntity(this);
|
|
//m_hSpitEffectB->SetAttachment(pOwner->GetViewModel(), LookupAttachment("laser"));
|
|
m_hSpitEffectB->SetTransparency(kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation);
|
|
m_hSpitEffectB->SetBrightness(/*sk_spore_launcher_sprite_a.GetInt()*/40, 0.5f);
|
|
m_hSpitEffectB->SetColor(/*sk_spore_launcher_sprite_r.GetInt()*/45, /*sk_spore_launcher_sprite_g.GetInt()*/180, /*sk_spore_launcher_sprite_b.GetInt()*/60);
|
|
m_hSpitEffectB->SetScale(/*sk_spore_launcher_sprite_scale.GetFloat()*/0.5f, 0.5f);
|
|
m_hSpitEffectB->TurnOn();
|
|
}
|
|
else
|
|
{
|
|
m_hSpitEffectB->TurnOn();
|
|
/*m_hSpitEffectB->SetScale(0.25f, 0.25f);
|
|
m_hSpitEffectB->SetBrightness(255);*/
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CSporeLauncherProjectile::Spawn(void)
|
|
{
|
|
Precache();
|
|
|
|
SetModel(BOLT_MODEL);
|
|
SetMoveType(MOVETYPE_FLY, MOVECOLLIDE_FLY_CUSTOM);
|
|
UTIL_SetSize(this, -Vector(10, 10, 10), Vector(10, 10, 10));
|
|
SetSolid(SOLID_BBOX);
|
|
SetModelScale(1.5f, 0.0f);
|
|
m_flDamage = cvar->FindVar("sk_plr_dmg_spore_acid")->GetFloat();
|
|
UpdateWaterState();
|
|
//DispatchParticleEffect("grenade_spit_trail", PATTACH_ABSORIGIN_FOLLOW, this);
|
|
|
|
SetTouch(&CSporeLauncherProjectile::BoltTouch);
|
|
|
|
SetThink(&CSporeLauncherProjectile::BubbleThink);
|
|
SetNextThink(gpGlobals->curtime + 0.02f);
|
|
|
|
CreateSprites();
|
|
|
|
// Make us glow until we've hit the wall
|
|
m_nSkin = BOLT_SKIN_GLOW;
|
|
}
|
|
|
|
|
|
void CSporeLauncherProjectile::Precache(void)
|
|
{
|
|
PrecacheModel(BOLT_MODEL);
|
|
PrecacheParticleSystem("Shockrifle_sparks");
|
|
PrecacheParticleSystem("hunter_flechette_trail");
|
|
PrecacheModel("models/grenade.mdl");
|
|
PrecacheModel("models/spitball_large.mdl");
|
|
PrecacheModel("models/spitball_medium.mdl");
|
|
PrecacheModel("models/spitball_small.mdl");
|
|
PrecacheModel(SPRITE);
|
|
PrecacheScriptSound("GrenadeSpit.Hit");
|
|
PrecacheParticleSystem("Spore_launcher_acid_glow");
|
|
PrecacheParticleSystem("grenade_spit_player");
|
|
PrecacheParticleSystem("grenade_spit");
|
|
PrecacheParticleSystem("grenade_spit_trail");
|
|
PrecacheScriptSound("grenade_strooper_instant.Detonate");
|
|
PrecacheScriptSound("Weapon_spore_acid.hit");
|
|
PrecacheScriptSound("Weapon_spore_acid.bounce");
|
|
PrecacheScriptSound("Weapon_spore_acid.impact");
|
|
BaseClass::Precache();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *pOther -
|
|
//-----------------------------------------------------------------------------
|
|
void CSporeLauncherProjectile::BoltTouch(CBaseEntity *pOther)
|
|
{
|
|
if (pOther == GetOwnerEntity())
|
|
return;
|
|
|
|
if (Q_strstr(STRING(MAKE_STRING(pOther->GetClassname())), "trigger"))
|
|
return;
|
|
|
|
if (pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS | FSOLID_TRIGGER))
|
|
{
|
|
// Some NPCs are triggers that can take damage (like antlion grubs). We should hit them.
|
|
if ((pOther->m_takedamage == DAMAGE_NO) || (pOther->m_takedamage == DAMAGE_EVENTS_ONLY))
|
|
{
|
|
Detonate();
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Don't hit other spit
|
|
if (pOther->GetCollisionGroup() == HL2COLLISION_GROUP_SPIT)
|
|
{
|
|
Detonate();
|
|
return;
|
|
}
|
|
|
|
if (pOther == GetOwnerEntity()->GetOwnerEntity())
|
|
{
|
|
m_hSpitEffectD->StopParticleSystem();
|
|
UTIL_Remove(m_hSpitEffectB);
|
|
UTIL_Remove(m_hSpitEffectD);
|
|
StopParticleEffects(this);
|
|
UTIL_Remove(this);
|
|
return;
|
|
}
|
|
// We want to collide with water
|
|
const trace_t *pTrace = &CBaseEntity::GetTouchTrace();
|
|
|
|
// copy out some important things about this trace, because the first TakeDamage
|
|
// call below may cause another trace that overwrites the one global pTrace points
|
|
// at.
|
|
bool bHitWater = ((pTrace->contents & CONTENTS_WATER) != 0);
|
|
CBaseEntity *const pTraceEnt = pTrace->m_pEnt;
|
|
const Vector tracePlaneNormal = pTrace->plane.normal;
|
|
|
|
if (bHitWater)
|
|
{
|
|
// Splash!
|
|
/*CEffectData data;
|
|
data.m_fFlags = 0;
|
|
data.m_vOrigin = pTrace->endpos;
|
|
data.m_vNormal = Vector(0, 0, 1);
|
|
data.m_flScale = 8.0f;
|
|
|
|
DispatchEffect("watersplash", data);*/
|
|
StopParticleEffects(this);
|
|
}
|
|
else
|
|
{
|
|
// Make a splat decal
|
|
UTIL_DecalTrace(pTrace, "SpitSplat");
|
|
}
|
|
|
|
// Part normal damage, part poison damage
|
|
float poisonratio = cvar->FindVar("sk_bullsquid_grenade_poison_ratio")->GetFloat();
|
|
|
|
// Take direct damage if hit
|
|
// NOTE: assume that pTrace is invalidated from this line forward!
|
|
if (pTraceEnt)
|
|
{
|
|
pTraceEnt->TakeDamage(CTakeDamageInfo(this, this, m_flDamage * (1.0f - poisonratio), DMG_ACID));
|
|
pTraceEnt->TakeDamage(CTakeDamageInfo(this, this, m_flDamage * poisonratio, DMG_POISON));
|
|
}
|
|
float m_DmgRadius = cvar->FindVar("sk_spore_acid_radius")->GetFloat();
|
|
CSoundEnt::InsertSound(SOUND_DANGER, GetAbsOrigin(), m_DmgRadius * 2.0f, 0.5f, this);
|
|
|
|
QAngle vecAngles;
|
|
VectorAngles(tracePlaneNormal, vecAngles);
|
|
|
|
if (pOther->IsPlayer() || bHitWater)
|
|
{
|
|
// Do a lighter-weight effect if we just hit a player
|
|
DispatchParticleEffect("grenade_spit_player", GetAbsOrigin(), vecAngles);
|
|
}
|
|
else
|
|
{
|
|
DispatchParticleEffect("grenade_spit", GetAbsOrigin(), vecAngles);
|
|
}
|
|
|
|
Detonate();
|
|
}
|
|
|
|
void CSporeLauncherProjectile::Detonate(void)
|
|
{
|
|
|
|
m_takedamage = DAMAGE_NO;
|
|
|
|
trace_t tr;
|
|
tr = CBaseEntity::GetTouchTrace();
|
|
|
|
/*if ( (tr.m_pEnt != GetWorldEntity()) || (tr.hitbox != 0) )
|
|
{
|
|
// non-world needs smaller decals
|
|
UTIL_DecalTrace( &tr, "SmallScorch");
|
|
}
|
|
else
|
|
{
|
|
UTIL_DecalTrace( &tr, "Scorch" );
|
|
}*/
|
|
for (int i = 0; i < cvar->FindVar("sk_spore_acid_maxdrips")->GetFloat(); i++)
|
|
{
|
|
Vector vecSpawn;
|
|
vecSpawn = this->WorldSpaceCenter();
|
|
/*vecSpawn.x += random->RandomFloat(-0.2, 0.2);
|
|
vecSpawn.y += random->RandomFloat(-12.1, 12.4);*/
|
|
//vecSpawn.z += 40;// random->RandomFloat(-20.1, 20.2);
|
|
Vector vecVelocity;
|
|
QAngle angles;
|
|
angles.x = random->RandomFloat(-360, 360);
|
|
angles.y = random->RandomFloat(-360, 360);
|
|
angles.z = random->RandomFloat(-360, 360);
|
|
AngleVectors(angles, &vecVelocity);
|
|
|
|
vecVelocity *= random->RandomFloat(150, 300);
|
|
vecVelocity -= GetAbsVelocity()/14;
|
|
|
|
|
|
CBloodDripsGreen *pGrenade = (CBloodDripsGreen*)CreateEntityByName("BloodDripsGreen");
|
|
//pGrenade->SetAbsOrigin(vecTraceDir);
|
|
pGrenade->SetLocalOrigin(vecSpawn);
|
|
pGrenade->SetAbsAngles(RandomAngle(-360, 360));
|
|
DispatchSpawn(pGrenade);
|
|
pGrenade->SetOwnerEntity(this);
|
|
pGrenade->SetAbsVelocity(vecVelocity);
|
|
|
|
}
|
|
//CSoundEnt::InsertSound ( SOUND_COMBAT, GetAbsOrigin(), BASEGRENADE_EXPLOSION_VOLUME, 3.0 );
|
|
|
|
|
|
RadiusDamage(CTakeDamageInfo(this, this, m_flDamage, DMG_BULLET), GetAbsOrigin(), cvar->FindVar("sk_spore_acid_radius")->GetFloat(), CLASS_NONE, NULL);
|
|
|
|
CPASAttenuationFilter filter1(this);
|
|
EmitSound(filter1, entindex(), "Weapon_spore_acid.hit");
|
|
EmitSound(filter1, entindex(), "Weapon_spore_acid.impact");
|
|
|
|
|
|
float Radius = 110;
|
|
CPASFilter filter(GetAbsOrigin());
|
|
te->DynamicLight(filter, 0.0, &GetAbsOrigin(), random->RandomInt(10, 25), random->RandomInt(190, 255), random->RandomInt(25, 55), 3, Radius, random->RandomInt(0.018, 0.23), Radius / 0.5);//OverCharged
|
|
/*if ( GetWaterLevel() == 0 )
|
|
{
|
|
int sparkCount = random->RandomInt( 0,3 );
|
|
QAngle angles;
|
|
VectorAngles( tr.plane.normal, angles );
|
|
|
|
for ( int i = 0; i < sparkCount; i++ )
|
|
Create( "spark_shower", GetAbsOrigin(), angles, NULL );
|
|
}*/
|
|
|
|
|
|
DispatchParticleEffect("grenade_spit", GetAbsOrigin(), GetAbsAngles());
|
|
m_hSpitEffectD->StopParticleSystem();
|
|
UTIL_Remove(m_hSpitEffectB);
|
|
UTIL_Remove(m_hSpitEffectD);
|
|
StopParticleEffects(this);
|
|
UTIL_Remove(this);
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CSporeLauncherProjectile::BubbleThink(void)
|
|
{
|
|
QAngle angNewAngles;
|
|
|
|
VectorAngles(GetAbsVelocity(), angNewAngles);
|
|
SetAbsAngles(angNewAngles);
|
|
|
|
SetNextThink(gpGlobals->curtime + 0.02f);
|
|
|
|
if (GetAbsVelocity().Length() <= 0)
|
|
Detonate();
|
|
|
|
/*if (GetWaterLevel() == 0)
|
|
return;
|
|
//DispatchParticleEffect("Shockrifle_sparks", PATTACH_ABSORIGIN, NULL);
|
|
|
|
UTIL_Remove(this);*/ // BriJee OVR : Little trick to get entity killed in water
|
|
}
|
|
|