Files
HL2Overcharged/game/server/BloodEmitter.cpp
2025-05-21 21:20:08 +03:00

495 lines
14 KiB
C++

#include "cbase.h"
#include "BloodEmitter.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"
#define BOLT_SKIN_NORMAL 0
#define BOLT_SKIN_GLOW 1
#define BOLT_MODEL oc_blood_drip_model.GetString() //"models/ShockRifle.mdl"
ConVar oc_blood_drip_model("oc_blood_drip_model", "models/spitball_small.mdl", FCVAR_REPLICATED | FCVAR_ARCHIVE, "Shock rifle projectile model.");
ConVar oc_blood_drip_maxcount("oc_blood_drip_maxcount", "0", FCVAR_ARCHIVE);
extern short g_sModelIndexFireball;
extern short g_sModelIndexWExplosion;
#define SPRITE "particles/particle_glow/particle_glow_03.vmt"
#if 0
LINK_ENTITY_TO_CLASS(blood_emitter, CBloodEmitter);
BEGIN_DATADESC(CBloodEmitter)
// Function Pointers
DEFINE_FUNCTION(BubbleThink),
//DEFINE_FUNCTION(BoltTouch),
// These are recreated on reload, they don't need storage
DEFINE_FIELD(m_hSpitEffectDD, FIELD_EHANDLE),
END_DATADESC()
//IMPLEMENT_SERVERCLASS_ST(CBloodEmitter, DT_BloodEmitter)
//END_SEND_TABLE()
CBloodEmitter *CBloodEmitter::BoltCreate(const Vector &vecOrigin, const QAngle &angAngles, int iDamage, CBasePlayer *pentOwner)
{
// Create a new entity with CShockRifleProjectile private data
CBloodEmitter *pBloodEmitter = (CBloodEmitter *)CreateEntityByName("blood_emitter");
UTIL_SetOrigin(pBloodEmitter, vecOrigin);
pBloodEmitter->SetAbsAngles(angAngles);
pBloodEmitter->Spawn();
pBloodEmitter->SetOwnerEntity(pentOwner);
pBloodEmitter->m_iDamage = iDamage;
return pBloodEmitter;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CBloodEmitter::~CBloodEmitter(void)
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
/*bool CBloodEmitter::CreateVPhysics(void)
{
// Create the object in the physics system
VPhysicsInitNormal(SOLID_BBOX, FSOLID_NOT_STANDABLE, false);
return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
unsigned int CBloodEmitter::PhysicsSolidMaskForEntity() const
{
return (BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_HITBOX) & ~CONTENTS_GRATE;
}*/
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CBloodEmitter::CreateSprites(void)
{
// Create the dust effect in place
m_hSpitEffectDD = (CParticleSystem *)CreateEntityByName("info_particle_system");
if (m_hSpitEffectDD != NULL)
{
// Setup our basic parameters
m_hSpitEffectDD->KeyValue("start_active", "1");
m_hSpitEffectDD->KeyValue("effect_name", "antlion_spit_trail");
m_hSpitEffectDD->SetParent(this);
m_hSpitEffectDD->SetLocalOrigin(vec3_origin);
DispatchSpawn(m_hSpitEffectDD);
if (gpGlobals->curtime > 0.5f)
m_hSpitEffectDD->Activate();
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBloodEmitter::Spawn(void)
{
Precache();
SetSolid(SOLID_NONE);
SetMoveType(MOVETYPE_NONE);
//SetSolidFlags(FSOLID_NOT_STANDABLE);
Vector SizeMin(0.2, 0.2, 0.2), SizeMax(1, 1, 1);
SetModel(BOLT_MODEL);
//SetModelScale(random->RandomFloat(0.01, 1), 0.0f);
UTIL_SetSize(this, SizeMin, SizeMax);
SetUse(&CBaseGrenade::DetonateUse);
SetTouch(&CBloodDripsGreen::BloodDripsGreenTouch);
SetNextThink(gpGlobals->curtime + 0.1f);
m_takedamage = DAMAGE_NO;
m_iHealth = 1;
//SetGravity(UTIL_ScaleForGravity(DRIPS_GRAVITY));
//SetFriction(0.8f);
//SetCollisionGroup(COLLISION_GROUP_NONE);
//AddEFlags(EFL_FORCE_CHECK_TRANSMIT);
// We're self-illuminating, so we don't take or give shadows
//AddEffects(EF_NOSHADOW | EF_NORECEIVESHADOW);
//SetTouch(&CBloodEmitter::BoltTouch);
SetThink(&CBloodEmitter::BubbleThink);
SetNextThink(gpGlobals->curtime + 0.02f);
CreateSprites();
// Make us glow until we've hit the wall
//m_nSkin = BOLT_SKIN_GLOW;
touched = true;
b_count = 0;
}
void CBloodEmitter::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();
}
#if 0
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pOther -
//-----------------------------------------------------------------------------
void CBloodEmitter::BoltTouch(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;
}
if (pOther->GetCollisionGroup() == HL2COLLISION_GROUP_SPIT)
return;
const trace_t *pTrace = &CBaseEntity::GetTouchTrace();
//bool bHitWater = ((pTrace->contents & CONTENTS_WATER) != 0);
//CBaseEntity *const pTraceEnt = pTrace->m_pEnt;
const Vector tracePlaneNormal = pTrace->plane.normal;
QAngle vecAngles;
VectorAngles(tracePlaneNormal, vecAngles);
touched = true;
//Detonate();
}
void CBloodEmitter::Detonate(void)
{
m_takedamage = DAMAGE_NO;
trace_t tr;
tr = CBaseEntity::GetTouchTrace();
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
DispatchParticleEffect("grenade_spit", GetAbsOrigin(), GetAbsAngles());
m_hSpitEffectDD->StopParticleSystem();
UTIL_Remove(m_hSpitEffectDD);
StopParticleEffects(this);
UTIL_Remove(this);
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBloodEmitter::BubbleThink(void)
{
//QAngle angNewAngles;
//VectorAngles(GetAbsVelocity(), angNewAngles);
//SetAbsAngles(angNewAngles);
if (false)//(touched)
{
CreateChildDrips();
b_count++;
if (b_count >= oc_blood_drip_maxcount.GetInt())
{
touched = false;
b_count = 0;
UTIL_Remove(this);
}
}
SetNextThink(gpGlobals->curtime + 4.2f);
/*if (GetWaterLevel() == 0)
return;
//DispatchParticleEffect("Shockrifle_sparks", PATTACH_ABSORIGIN, NULL);
UTIL_Remove(this);*/ // BriJee OVR : Little trick to get entity killed in water
}
void CBloodEmitter::CreateChildDrips()
{
Vector vecSpawn;
vecSpawn = this->WorldSpaceCenter();
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->SetModelScale(0.01f);
pGrenade->SetLocalOrigin(vecSpawn);
pGrenade->SetAbsAngles(RandomAngle(-360, 360));
DispatchSpawn(pGrenade);
pGrenade->SetOwnerEntity(this);
pGrenade->SetAbsVelocity(vecVelocity);
}
#endif
LINK_ENTITY_TO_CLASS(blood_emitter, CBloodEmitter);
/*BEGIN_DATADESC(CEndPoint)
// Function Pointers
DEFINE_FUNCTION(Spawn),
END_DATADESC()*/
//IMPLEMENT_SERVERCLASS_ST(CEndPoint, DT_EndPoint)
//END_SEND_TABLE()
CBloodEmitter *CBloodEmitter::DispatchImpactSound(const Vector &end)
{
CBloodEmitter *pPoint = (CBloodEmitter *)(CreateEntityByName("blood_emitter"));
UTIL_SetOrigin(pPoint, end);
//pPoint->SetAbsAngles(QAngle(0, 0, 0));
pPoint->Spawn();
//pPoint->SetOwnerEntity(pPoint);
return pPoint;
}
void CBloodEmitter::Precache(void)
{
//PrecacheModel("models/weapons/v_smg1_mmod.mdl");
//PrecacheScriptSound("Weapon_Gluon.Hit");
}
/*bool CBloodEmitter::CreateVPhysics(void)
{
VPhysicsInitNormal(SOLID_BBOX, FSOLID_NOT_STANDABLE, false);
return true;
}*/
void CBloodEmitter::Spawn(void)
{
Precache();
PrecacheModel("models/weapons/MAGS/w_rif_ak47_mag.mdl");
SetModel("models/weapons/MAGS/w_rif_ak47_mag.mdl");
SetMoveType(MOVETYPE_VPHYSICS);
SetSolid(SOLID_VPHYSICS);
SetCollisionGroup(COLLISION_GROUP_DEBRIS);
AddSpawnFlags(SF_PHYSBOX_ASLEEP);
UTIL_SetSize(this, Vector(-3, -3, -3), Vector(3, 3, 3));
SetThink(&CBloodEmitter::BubbleThink);
SetNextThink(gpGlobals->curtime + 0.02f);
//EmitSound("Weapon_Gluon.Hit");
CreateVPhysics();
thisPhysics = VPhysicsGetObject();
//UTIL_Remove(this);
touched = true;
b_count = 0;
}
void CBloodEmitter::BubbleThink(void)
{
if (touched)
{
//CreateChildDrips();
Vector origin = EyePosition();
Vector forward, rt, up;
QAngle angles = GetLocalAngles();
//AngleVectors(angles, &forward, &rt, &up);
GetVectors(&forward, &rt, &up);
origin += forward;
origin += rt;
origin += up;
forward *= 5.f;
CEffectData data;
data.m_vOrigin = origin;
data.m_vNormal = origin + forward;
data.m_vAngles = angles;
data.m_nAttachmentIndex = composeColor;
DispatchEffect("BloodDrips", data);
b_count++;
if (b_count >= oc_blood_drip_maxcount.GetInt())
{
touched = false;
b_count = 0;
UTIL_Remove(this);
}
}
SetNextThink(gpGlobals->curtime + timeThink);
}
void CBloodEmitter::CreateChildDrips()
{
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(10, 500);
vecVelocity -= GetAbsVelocity() / 14;
direction = direction * 0.9;
if (composeColor == 0)
{
CBloodDripsGreen *pGrenade = (CBloodDripsGreen*)CreateEntityByName("BloodDrips");
//pGrenade->SetAbsOrigin(vecTraceDir);
pGrenade->SetModelScale(0.01f);
VectorAngles(GetAbsOrigin(), angle);
pGrenade->SetAbsOrigin(GetAbsOrigin());
pGrenade->SetAbsAngles(angle);
DispatchSpawn(pGrenade);
//pGrenade->SetParent(this->GetParent());
//pGrenade->SetOwnerEntity(this->GetParent());
//pGrenade->ApplyLocalVelocityImpulse(this->GetLocalOrigin()*random->RandomInt(15, 35));
pGrenade->ApplyLocalVelocityImpulse(direction*random->RandomInt(15, 35));
}
else if (composeColor == 1 || composeColor == 2)
{
CBloodDripsGreen *pGrenade = (CBloodDripsGreen*)CreateEntityByName("BloodDripsGreen");
pGrenade->SetModelScale(0.01f);
VectorAngles(GetAbsOrigin(), angle);
pGrenade->SetAbsOrigin(GetAbsOrigin());
pGrenade->SetAbsAngles(angle);
DispatchSpawn(pGrenade);
//pGrenade->SetParent(this->GetParent());
//pGrenade->SetOwnerEntity(this->GetParent());
//pGrenade->ApplyLocalVelocityImpulse(this->GetLocalOrigin()*random->RandomInt(15, 35));
pGrenade->ApplyLocalVelocityImpulse(direction*random->RandomInt(15, 35));
}
else if (composeColor >= 3)
{
int rndmInt = random->RandomInt(0, 1);
if (rndmInt)
{
CBloodDripsGreen *pGrenade = (CBloodDripsGreen*)CreateEntityByName("BloodDrips");
//pGrenade->SetAbsOrigin(vecTraceDir);
pGrenade->SetModelScale(0.01f);
VectorAngles(GetAbsOrigin(), angle);
pGrenade->SetAbsOrigin(GetAbsOrigin());
pGrenade->SetAbsAngles(angle);
DispatchSpawn(pGrenade);
//pGrenade->SetParent(this->GetParent());
//pGrenade->SetOwnerEntity(this->GetParent());
//pGrenade->ApplyLocalVelocityImpulse(this->GetLocalOrigin()*random->RandomInt(15, 35));
pGrenade->ApplyLocalVelocityImpulse(direction*random->RandomInt(15, 35));
}
else
{
CBloodDripsGreen *pGrenade = (CBloodDripsGreen*)CreateEntityByName("BloodDripsGreen");
pGrenade->SetModelScale(0.01f);
VectorAngles(GetAbsOrigin(), angle);
pGrenade->SetAbsOrigin(GetAbsOrigin());
pGrenade->SetAbsAngles(angle);
DispatchSpawn(pGrenade);
//pGrenade->SetParent(this->GetParent());
//pGrenade->SetOwnerEntity(this->GetParent());
//pGrenade->ApplyLocalVelocityImpulse(this->GetLocalOrigin()*random->RandomInt(15, 35));
pGrenade->ApplyLocalVelocityImpulse(direction*random->RandomInt(15, 35));
}
}
}