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

285 lines
8.6 KiB
C++

#include "cbase.h"
#include "NPCEvent.h"
#include "basehlcombatweapon_shared.h"
#include "basecombatcharacter.h"
#include "AI_BaseNPC.h"
#include "player.h"
#include "gamerules.h"
#include "in_buttons.h"
#include "soundent.h"
#include "game.h"
#include "vstdlib/random.h"
#include "engine/IEngineSound.h"
#include "IEffects.h"
#include "te_effect_dispatch.h"
#include "sprite.h"
#include "spritetrail.h"
#include "beam_shared.h"
#include "rumble_shared.h"
#include "gamestats.h"
#include "decals.h"
#include "particle_parse.h"
#include "grenade_spit.h"
#include "particle_system.h"
#include "effect_dispatch_data.h"
#include "WaterBulletDynamic.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
LINK_ENTITY_TO_CLASS(water_bullet_dynamic, CWaterBulletDynamic);
BEGIN_DATADESC(CWaterBulletDynamic)
// Function Pointers
DEFINE_FUNCTION(BubbleThink),
DEFINE_FUNCTION(BoltTouch),
// These are recreated on reload, they don't need storage
DEFINE_FIELD(m_Spite, FIELD_EHANDLE),
DEFINE_FIELD(m_Sprite, FIELD_EHANDLE),
//DEFINE_FIELD( m_pGlowTrail, FIELD_EHANDLE ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST(CWaterBulletDynamic, DT_WaterBulletDynamic)
SendPropInt(SENDINFO(underWater), 1, SPROP_UNSIGNED),
END_SEND_TABLE()
CWaterBulletDynamic *CWaterBulletDynamic::BoltCreate(const Vector &vecOrigin, const QAngle &angAngles, int iDamage, CBaseEntity *pentOwner)
{
// Create a new entity with CShockRifleProjectile private data
CWaterBulletDynamic *pWaterBulletDynamic = (CWaterBulletDynamic *)CreateEntityByName("water_bullet_dynamic");
UTIL_SetOrigin(pWaterBulletDynamic, vecOrigin);
pWaterBulletDynamic->SetAbsAngles(angAngles);
pWaterBulletDynamic->Spawn();
pWaterBulletDynamic->SetOwnerEntity(pentOwner);
pWaterBulletDynamic->m_iDamage = iDamage;
return pWaterBulletDynamic;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CWaterBulletDynamic::~CWaterBulletDynamic(void)
{
if (m_Spite)
{
UTIL_Remove(m_Spite);
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
/*bool CWaterBulletDynamic::CreateVPhysics(void)
{
// Create the object in the physics system
VPhysicsInitNormal(SOLID_BBOX, FSOLID_NOT_STANDABLE, false);
return true;
}*/
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/*unsigned int CWaterBulletDynamic::PhysicsSolidMaskForEntity() const
{
//return (BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_HITBOX) & ~CONTENTS_GRATE;
return (BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_DETAIL);
}*/
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWaterBulletDynamic::CreateSprites(void)
{
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWaterBulletDynamic::Spawn(void)
{
Precache();
//m_pIgnoreList = new CTraceFilterSimpleList(COLLISION_GROUP_NONE);
//m_pIgnoreList->AddEntityToIgnore(this);
SetModel("models/weapons/w_bullet.mdl");
SetMoveType(MOVETYPE_FLY, MOVECOLLIDE_FLY_CUSTOM);
UTIL_SetSize(this, -Vector(10, 10, 10), Vector(10, 10, 10));
SetSolid(SOLID_CUSTOM);
SetCollisionGroup(COLLISION_GROUP_INTERACTIVE_DEBRIS | COLLISION_GROUP_PLAYER);
//SetModelScale(0.1f, 0.0f);
//AddEffects( EF_NODRAW ); // BriJee OVR : Little trick, nodraw model
//AddEffects( EF_NOSHADOW );
SetGravity(200);
SetTouch(&CWaterBulletDynamic::BoltTouch);
SetThink(&CWaterBulletDynamic::BubbleThink);
SetNextThink(gpGlobals->curtime + 0.02f);
underWater = true;
AbsAngles = GetAbsAngles();
}
void CWaterBulletDynamic::Precache(void)
{
PrecacheModel("models/weapons/w_bullet.mdl");
PrecacheParticleSystem("Shockrifle_sparks");
//PrecacheModel( "sprites/light_glow02_noz.vmt" );
//PrecacheParticleSystem( "hunter_flechette_trail_striderbuster" );
PrecacheParticleSystem("hunter_flechette_trail");
BaseClass::Precache();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pOther -
//-----------------------------------------------------------------------------
void CWaterBulletDynamic::BoltTouch(CBaseEntity *pOther)
{
//if (pOther == this)
//SetSolid(SOLID_BBOX);
if (GetOwnerEntity() && (pOther == GetOwnerEntity()))
return;
if (AllocPooledString(pOther->GetClassname()) == AllocPooledString("water_bullet_dynamic"))
return;
if (!pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS))
return;
trace_t tr2;
Vector vForward;
AngleVectors(GetAbsAngles(), &vForward);
VectorNormalize(vForward);
UTIL_TraceLine(GetAbsOrigin(), GetAbsOrigin() + vForward * 128, MASK_OPAQUE, pOther, COLLISION_GROUP_NONE, &tr2);
//tr2 = BaseClass::GetTouchTrace();
UTIL_ImpactTrace(&tr2, GetDamageType);
//UTIL_DecalTrace(&tr2, "RedGlowFade");
if (pOther->m_takedamage != DAMAGE_NO)
{
trace_t tr, tr2;
tr = BaseClass::GetTouchTrace();
Vector vecNormalizedVel = GetAbsVelocity();
ClearMultiDamage();
VectorNormalize(vecNormalizedVel);
flActualForce *= GetBulletSpeedRatio;
if (GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->IsNPC())
{
//CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), m_iDamage, DMG_NEVERGIB );
// dmgInfo(this, GetOwnerEntity(), flActualDamage, DMG_BULLET);
//dmgInfo.AdjustPlayerDamageInflictedForSkillLevel();
CalculateBulletDamageForce(&info, AmmoType, m_vecDirShooting, tr.endpos);
//dmgInfo.SetDamagePosition(tr.endpos);
pOther->DispatchTraceAttack(info, m_vecDirShooting, &tr);
}
else
{
//CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), m_iDamage, DMG_BULLET | DMG_NEVERGIB );
//CTakeDamageInfo dmgInfo(this, GetOwnerEntity(), flActualDamage, DMG_BULLET);
CalculateBulletDamageForce(&info, AmmoType, m_vecDirShooting, tr.endpos);
//dmgInfo.SetDamagePosition(tr.endpos);
pOther->DispatchTraceAttack(info, m_vecDirShooting, &tr);
}
ApplyMultiDamage();
//Adrian: keep going through the glass.
if (pOther->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS)
return;
SetAbsVelocity(Vector(0, 0, 0));
//EmitSound("Weapon_Shock.Impact");
//CEffectData data;
/*data.m_vOrigin = tr.endpos + (tr.plane.normal * 1.0f);
data.m_vNormal = tr.plane.normal;
g_pEffects->Sparks(data.m_vOrigin);*/
UTIL_ImpactTrace(&tr, GetDamageType);
SetTouch(NULL);
SetThink(NULL);
UTIL_Remove(m_Sprite);
UTIL_Remove(this);
}
else
{
// tr;
//tr = BaseClass::GetTouchTrace();
//UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + Vector ( 0, 0, 0 ), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);
/*Vector vForward;
AngleVectors(GetAbsAngles(), &vForward);
VectorNormalize(vForward);
UTIL_TraceLine(GetAbsOrigin(), GetAbsOrigin() + vForward * 128, MASK_OPAQUE, pOther, COLLISION_GROUP_NONE, &tr);*/
trace_t tr;
tr = BaseClass::GetTouchTrace();
UTIL_ImpactTrace(&tr, GetDamageType);
//EmitSound("Weapon_Shock.Impact");
/*CEffectData data;
data.m_vOrigin = tr.endpos + (tr.plane.normal * 1.0f);
data.m_vNormal = tr.plane.normal;
g_pEffects->Sparks(data.m_vOrigin);*/
//UTIL_DecalTrace( &tr, "extinguish" ); // BriJee OVR : Draw the decal
//UTIL_DecalTrace(&tr, "SmallScorch"); //"Scorch" );
//UTIL_DecalTrace(&tr, "RedGlowFade");
//UTIL_ImpactTrace( &tr, DMG_SLASH );
UTIL_Remove(m_Sprite);
UTIL_Remove(this);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWaterBulletDynamic::BubbleThink(void)
{
QAngle angNewAngles;
VectorAngles(GetAbsVelocity(), angNewAngles);
SetAbsAngles(angNewAngles);
SetNextThink(gpGlobals->curtime + 0.02f);
/*if (GetAbsAngles() != AbsAngles)
SetSolid(SOLID_BBOX);*/
/*if (GetAbsVelocity().x <= 10 && GetAbsVelocity().y <= 10 && GetAbsVelocity().z <= 10)
UTIL_Remove(this);*/
if (!underWater)
return;
if (GetWaterLevel() != 3)
{
SetGravity(600);
DispatchParticleEffect("shell_exhaust_smoke", PATTACH_ABSORIGIN_FOLLOW, this);
underWater = false;
}
//return;
//DispatchParticleEffect("Shockrifle_sparks", PATTACH_ABSORIGIN, NULL);
//UTIL_Remove(m_Sprite);
//UTIL_Remove(this); // BriJee OVR : Little trick to get entity killed in water
}