New class: NSTraceAttack. Will make it much easier for games/mods to overrides parts of it.
This commit is contained in:
parent
df589de04c
commit
59d46e1f63
2 changed files with 211 additions and 83 deletions
|
@ -14,12 +14,54 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef BULLETPENETRATION
|
|
||||||
var int iTotalPenetrations;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void TraceAttack_FireBullets(int iShots, vector vecPos, int iDamage, vector vecSpread, int iWeapon);
|
void TraceAttack_FireBullets(int iShots, vector vecPos, int iDamage, vector vecSpread, int iWeapon);
|
||||||
|
|
||||||
#ifdef BULLETPENETRATION
|
#ifdef BULLETPENETRATION
|
||||||
void TraceAttack_SetPenetrationPower(int power);
|
void TraceAttack_SetPenetrationPower(int power);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
class
|
||||||
|
NSTraceAttack
|
||||||
|
{
|
||||||
|
/* multi-part damage */
|
||||||
|
entity m_eMultiTarget;
|
||||||
|
int m_iMultiValue;
|
||||||
|
int m_iMultiBody;
|
||||||
|
|
||||||
|
int m_iShots;
|
||||||
|
float m_flDamage;
|
||||||
|
vector m_vecSpread;
|
||||||
|
int m_iWeapon;
|
||||||
|
entity m_eOwner;
|
||||||
|
float m_flRange;
|
||||||
|
vector m_vecOrigin;
|
||||||
|
|
||||||
|
/* bullet penetration */
|
||||||
|
#ifdef BULLETPENETRATION
|
||||||
|
float m_flMaxThickness;
|
||||||
|
float m_flRangeModifier;
|
||||||
|
int m_iTotalPenetrations;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void(void) NSTraceAttack;
|
||||||
|
|
||||||
|
virtual void(void) _ApplyDamage;
|
||||||
|
virtual void(vector, vector, float, float) _FireSingle;
|
||||||
|
virtual void(void) Fire;
|
||||||
|
|
||||||
|
virtual void(int) SetShots;
|
||||||
|
virtual void(vector) SetOrigin;
|
||||||
|
virtual void(int) SetDamage;
|
||||||
|
virtual void(vector) SetSpread;
|
||||||
|
virtual void(int) SetWeapon;
|
||||||
|
virtual void(float) SetRange;
|
||||||
|
virtual void(entity) SetOwner;
|
||||||
|
|
||||||
|
#ifdef BULLETPENETRATION
|
||||||
|
virtual void(float) SetPenetrationMaxThickness;
|
||||||
|
virtual void(int) SetPenetrationPower;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
NSTraceAttack g_traceAttack;
|
|
@ -14,65 +14,50 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
entity g_multiDamage_Target;
|
void
|
||||||
int g_multiDamage_Value;
|
NSTraceAttack::_ApplyDamage(void)
|
||||||
int g_multiDamage_HitBod;
|
|
||||||
|
|
||||||
#ifdef BULLETPENETRATION
|
|
||||||
float g_pen_flMaxThickness;
|
|
||||||
var float g_pen_flRangeMod = 1.0f;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
TraceAttack_Apply(entity eAttacker, int iWeapon)
|
|
||||||
{
|
{
|
||||||
/* may not be defined yet */
|
/* may not be defined yet */
|
||||||
if (g_multiDamage_Target == __NULL__)
|
if (m_eMultiTarget == __NULL__)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (trace_ent.iBleeds == 1) {
|
if (trace_ent.iBleeds == 1) {
|
||||||
FX_Blood(trace_endpos, [0.5,0,0]);
|
FX_Blood(trace_endpos, [0.5,0,0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_surface_id = g_multiDamage_HitBod;
|
trace_surface_id = m_iMultiBody;
|
||||||
Damage_Apply(g_multiDamage_Target, self, g_multiDamage_Value, iWeapon, DMG_BULLET);
|
Damage_Apply(m_eMultiTarget, m_eOwner, m_iMultiValue, m_iWeapon, DMG_BULLET);
|
||||||
g_multiDamage_Target = __NULL__;
|
m_eMultiTarget = __NULL__;
|
||||||
g_multiDamage_Value = 0;
|
m_iMultiValue = 0;
|
||||||
g_multiDamage_HitBod = 0;
|
m_iMultiBody = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TraceAttack_ImpactWorld(void)
|
NSTraceAttack::_FireSingle(vector vecPos, vector vecAngles, float flDamage, float flRange)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* cast a single bullet shot */
|
|
||||||
static void
|
|
||||||
TraceAttack_FireSingle(vector vecPos, vector vAngle, int iDamage, int iWeapon, float dist)
|
|
||||||
{
|
{
|
||||||
vector range;
|
vector range;
|
||||||
|
|
||||||
if (dist <= 0)
|
if (flRange <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
range = (vAngle * 8196);
|
range = (vecAngles * 8196);
|
||||||
|
|
||||||
self.dimension_solid = 255;
|
m_eOwner.dimension_solid = 255;
|
||||||
self.dimension_hit = 255;
|
m_eOwner.dimension_hit = 255;
|
||||||
|
|
||||||
/* make sure we can gib corpses */
|
/* make sure we can gib corpses */
|
||||||
int oldhitcontents = self.hitcontentsmaski;
|
int oldhitcontents = m_eOwner.hitcontentsmaski;
|
||||||
self.hitcontentsmaski = CONTENTBITS_POINTSOLID | CONTENTBIT_CORPSE | CONTENTBIT_WATER | CONTENTBIT_SLIME | CONTENTBIT_LAVA | CONTENTBIT_PROJECTILE;
|
m_eOwner.hitcontentsmaski = CONTENTBITS_POINTSOLID | CONTENTBIT_CORPSE | CONTENTBIT_WATER | CONTENTBIT_SLIME | CONTENTBIT_LAVA | CONTENTBIT_PROJECTILE;
|
||||||
traceline(vecPos, vecPos + range, MOVE_LAGGED | MOVE_HITMODEL, self);
|
traceline(vecPos, vecPos + range, MOVE_LAGGED | MOVE_HITMODEL, m_eOwner);
|
||||||
self.hitcontentsmaski = oldhitcontents;
|
m_eOwner.hitcontentsmaski = oldhitcontents;
|
||||||
|
|
||||||
dist -= trace_plane_dist;
|
flRange -= trace_plane_dist;
|
||||||
|
|
||||||
self.dimension_solid = 254;
|
m_eOwner.dimension_solid = 254;
|
||||||
self.dimension_hit = 254;
|
m_eOwner.dimension_hit = 254;
|
||||||
|
|
||||||
g_multiDamage_HitBod |= trace_surface_id;
|
m_iMultiBody |= trace_surface_id;
|
||||||
|
|
||||||
if (trace_fraction >= 1.0f)
|
if (trace_fraction >= 1.0f)
|
||||||
return;
|
return;
|
||||||
|
@ -80,13 +65,13 @@ TraceAttack_FireSingle(vector vecPos, vector vAngle, int iDamage, int iWeapon, f
|
||||||
/* water impact */
|
/* water impact */
|
||||||
if (trace_endcontentsi & CONTENTBIT_WATER) {
|
if (trace_endcontentsi & CONTENTBIT_WATER) {
|
||||||
FX_Impact(IMPACT_SLOSH, trace_endpos, trace_plane_normal);
|
FX_Impact(IMPACT_SLOSH, trace_endpos, trace_plane_normal);
|
||||||
TraceAttack_FireSingle(trace_endpos + (v_forward * 2), vAngle, iDamage / 2, iWeapon, dist);
|
_FireSingle(trace_endpos + (v_forward * 2), vecAngles, flDamage / 2, flRange);
|
||||||
} else if (trace_endcontentsi & CONTENTBIT_SLIME) {
|
} else if (trace_endcontentsi & CONTENTBIT_SLIME) {
|
||||||
FX_Impact(IMPACT_SLOSH, trace_endpos, trace_plane_normal);
|
FX_Impact(IMPACT_SLOSH, trace_endpos, trace_plane_normal);
|
||||||
TraceAttack_FireSingle(trace_endpos + (v_forward * 2), vAngle, iDamage / 2, iWeapon, dist);
|
_FireSingle(trace_endpos + (v_forward * 2), vecAngles, flDamage / 2, flRange);
|
||||||
} else if (trace_endcontentsi & CONTENTBIT_LAVA) {
|
} else if (trace_endcontentsi & CONTENTBIT_LAVA) {
|
||||||
FX_Impact(IMPACT_SLOSH, trace_endpos, trace_plane_normal);
|
FX_Impact(IMPACT_SLOSH, trace_endpos, trace_plane_normal);
|
||||||
TraceAttack_FireSingle(trace_endpos + (v_forward * 2), vAngle, iDamage / 2, iWeapon, dist);
|
_FireSingle(trace_endpos + (v_forward * 2), vecAngles, flDamage / 2, flRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trace_ent.takedamage == DAMAGE_YES && trace_ent.iBleeds) {
|
if (trace_ent.takedamage == DAMAGE_YES && trace_ent.iBleeds) {
|
||||||
|
@ -99,32 +84,39 @@ TraceAttack_FireSingle(vector vecPos, vector vAngle, int iDamage, int iWeapon, f
|
||||||
case BODY_HEAD:
|
case BODY_HEAD:
|
||||||
/* the helmet is one power house */
|
/* the helmet is one power house */
|
||||||
if (pl.g_items & ITEM_HELMET) {
|
if (pl.g_items & ITEM_HELMET) {
|
||||||
iDamage = 0;
|
m_flDamage = 0;
|
||||||
Sound_Play(trace_ent, CHAN_BODY, "player.headshotarmor");
|
Sound_Play(trace_ent, CHAN_BODY, "player.headshotarmor");
|
||||||
pl.g_items &= ~ITEM_HELMET;
|
pl.g_items &= ~ITEM_HELMET;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
iDamage *= 4;
|
m_flDamage *= 4;
|
||||||
Sound_Play(trace_ent, CHAN_BODY, "player.headshot");
|
Sound_Play(trace_ent, CHAN_BODY, "player.headshot");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BODY_STOMACH:
|
case BODY_STOMACH:
|
||||||
iDamage *= 0.9;
|
m_flDamage *= 0.9;
|
||||||
if (pl.armor > 0)
|
if (pl.armor > 0)
|
||||||
Sound_Play(trace_ent, CHAN_BODY, "player.hitarmor");
|
Sound_Play(trace_ent, CHAN_BODY, "player.hitarmor");
|
||||||
break;
|
break;
|
||||||
case BODY_LEGLEFT:
|
case BODY_LEGLEFT:
|
||||||
case BODY_LEGRIGHT:
|
case BODY_LEGRIGHT:
|
||||||
iDamage *= 0.4;
|
m_flDamage *= 0.4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* only headshots count in HL */
|
/* only headshots count in HL */
|
||||||
if (trace_surface_id == BODY_HEAD)
|
if (trace_surface_id == BODY_HEAD)
|
||||||
iDamage *= 3;
|
m_flDamage *= 3;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WASTES
|
||||||
|
player pl1 = (player)self;
|
||||||
|
if (pl1.m_iWillpowerValue > 0) {
|
||||||
|
FX_Crit(trace_endpos, vectoangles(trace_endpos - pl1.origin), 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* impact per bullet */
|
/* impact per bullet */
|
||||||
if (trace_ent.iBleeds == 0) {
|
if (trace_ent.iBleeds == 0) {
|
||||||
SurfData_Impact(trace_ent, trace_surfaceflagsi, trace_endpos, trace_plane_normal);
|
SurfData_Impact(trace_ent, trace_surfaceflagsi, trace_endpos, trace_plane_normal);
|
||||||
|
@ -132,58 +124,58 @@ TraceAttack_FireSingle(vector vecPos, vector vAngle, int iDamage, int iWeapon, f
|
||||||
|
|
||||||
/* combine them into one single Damage_Apply call later */
|
/* combine them into one single Damage_Apply call later */
|
||||||
if (trace_ent.takedamage == DAMAGE_YES) {
|
if (trace_ent.takedamage == DAMAGE_YES) {
|
||||||
if (trace_ent != g_multiDamage_Target) {
|
if (trace_ent != m_eMultiTarget) {
|
||||||
TraceAttack_Apply(self, iWeapon);
|
_ApplyDamage();
|
||||||
g_multiDamage_Target = trace_ent;
|
m_eMultiTarget = trace_ent;
|
||||||
g_multiDamage_Value = iDamage;
|
m_iMultiValue = flDamage;
|
||||||
} else {
|
} else {
|
||||||
g_multiDamage_Value += iDamage;
|
m_iMultiValue += flDamage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BULLETPENETRATION
|
#ifdef BULLETPENETRATION
|
||||||
if (iTotalPenetrations > 0) {
|
if (m_iTotalPenetrations > 0) {
|
||||||
float cont;
|
float cont;
|
||||||
|
|
||||||
if (!(trace_surfaceflagsi & SURF_PENETRATE))
|
if (!(trace_surfaceflagsi & SURF_PENETRATE))
|
||||||
iTotalPenetrations -= 1;
|
m_iTotalPenetrations -= 1;
|
||||||
|
|
||||||
/* check if this wall is 6 units thick... */
|
/* check if this wall is 6 units thick... */
|
||||||
if (iTotalPenetrations > 0) {
|
if (m_iTotalPenetrations > 0) {
|
||||||
cont = pointcontents(trace_endpos + v_forward * 5);
|
cont = pointcontents(trace_endpos + v_forward * 5);
|
||||||
|
|
||||||
if (cont == CONTENT_SOLID)
|
if (cont == CONTENT_SOLID)
|
||||||
iTotalPenetrations -= 1; /* deduct 1 penetration power */
|
m_iTotalPenetrations -= 1; /* deduct 1 penetration power */
|
||||||
}
|
}
|
||||||
|
|
||||||
cont = pointcontents(trace_endpos + v_forward * g_pen_flMaxThickness);
|
cont = pointcontents(trace_endpos + v_forward * m_flMaxThickness);
|
||||||
|
|
||||||
if (cont == CONTENT_EMPTY)
|
if (cont == CONTENT_EMPTY)
|
||||||
TraceAttack_FireSingle(trace_endpos + (v_forward * 2), vAngle, iDamage / 2, iWeapon, dist);
|
_FireSingle(trace_endpos + (v_forward * 2), vecAngles, m_flDamage / 2, flRange);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fire a given amount of shots */
|
|
||||||
void
|
void
|
||||||
TraceAttack_FireBullets(int iShots, vector vecPos, int iDamage, vector vecSpread, int iWeapon)
|
NSTraceAttack::Fire(void)
|
||||||
{
|
{
|
||||||
vector vDir;
|
vector vecDir;
|
||||||
makevectors(self.v_angle);
|
makevectors(m_eOwner.v_angle);
|
||||||
|
|
||||||
g_multiDamage_Target = __NULL__;
|
m_eMultiTarget = __NULL__;
|
||||||
g_multiDamage_Value = 0;
|
m_iMultiValue = 0;
|
||||||
|
|
||||||
|
while (m_iShots > 0) {
|
||||||
|
vecDir = aim(m_eOwner, 100000);
|
||||||
|
|
||||||
while (iShots > 0) {
|
|
||||||
vDir = aim(self, 100000);
|
|
||||||
#ifndef BULLETPATTERNS
|
#ifndef BULLETPATTERNS
|
||||||
vDir += random(-1,1) * vecSpread[0] * v_right;
|
vecDir += random(-1,1) * m_vecSpread[0] * v_right;
|
||||||
vDir += random(-1,1) * vecSpread[1] * v_up;
|
vecDir += random(-1,1) * m_vecSpread[1] * v_up;
|
||||||
#else
|
#else
|
||||||
player pl = (player)self;
|
player pl = (player) m_eOwner;
|
||||||
|
|
||||||
/* weapons have already applied their multiplier... so attempt this */
|
/* weapons have already applied their multiplier... so attempt this */
|
||||||
int multiplier = pl.cs_shotmultiplier - iShots;
|
int multiplier = pl.cs_shotmultiplier - m_iShots;
|
||||||
float frand = (multiplier / 6);
|
float frand = (multiplier / 6);
|
||||||
|
|
||||||
/* shoddy attempt at spray patterns */
|
/* shoddy attempt at spray patterns */
|
||||||
|
@ -192,29 +184,123 @@ TraceAttack_FireBullets(int iShots, vector vecPos, int iDamage, vector vecSpread
|
||||||
else if (frand <= 2)
|
else if (frand <= 2)
|
||||||
frand = 2 - (frand * 1.5);
|
frand = 2 - (frand * 1.5);
|
||||||
|
|
||||||
vDir += frand * vecSpread[0] * v_right;
|
vecDir += frand * m_vecSpread[0] * v_right;
|
||||||
vDir += (vecSpread[1] * v_up) * 2;
|
vecDir += (m_vecSpread[1] * v_up) * 2;
|
||||||
#endif
|
#endif
|
||||||
TraceAttack_FireSingle(vecPos, vDir, iDamage, iWeapon, 8196);
|
_FireSingle(m_vecOrigin, vecDir, m_flDamage, m_flRange);
|
||||||
iShots--;
|
m_iShots--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_multiDamage_Target) {
|
if (m_eMultiTarget) {
|
||||||
TraceAttack_Apply(self, iWeapon);
|
_ApplyDamage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSTraceAttack::SetShots(int iShots)
|
||||||
|
{
|
||||||
|
m_iShots = iShots;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSTraceAttack::SetOrigin(vector vecOrigin)
|
||||||
|
{
|
||||||
|
m_vecOrigin = vecOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSTraceAttack::SetDamage(int iDamage)
|
||||||
|
{
|
||||||
|
m_flDamage = (float)iDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSTraceAttack::SetSpread(vector vecSpread)
|
||||||
|
{
|
||||||
|
m_vecSpread = vecSpread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSTraceAttack::SetWeapon(int iWeapon)
|
||||||
|
{
|
||||||
|
m_iWeapon = iWeapon;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSTraceAttack::SetRange(float flRange)
|
||||||
|
{
|
||||||
|
m_flRange = flRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSTraceAttack::SetOwner(entity eOwner)
|
||||||
|
{
|
||||||
|
m_eOwner = eOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BULLETPENETRATION
|
||||||
|
void
|
||||||
|
NSTraceAttack::SetPenetrationMaxThickness(float flThickness)
|
||||||
|
{
|
||||||
|
m_flMaxThickness = flThickness;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
NSTraceAttack::SetPenetrationPower(int iPower)
|
||||||
|
{
|
||||||
|
m_iTotalPenetrations = iPower;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
NSTraceAttack::NSTraceAttack(void)
|
||||||
|
{
|
||||||
|
m_eMultiTarget = __NULL__;
|
||||||
|
m_iMultiValue = 0;
|
||||||
|
m_iMultiBody = 0;
|
||||||
|
m_flRange = 8196;
|
||||||
|
|
||||||
|
#ifdef BULLETPENETRATION
|
||||||
|
m_flMaxThickness = 5.0f;
|
||||||
|
m_flRangeModifier = 1.0f;
|
||||||
|
m_iTotalPenetrations = 0;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* fire a given amount of shots */
|
||||||
|
void
|
||||||
|
TraceAttack_FireBullets(int iShots, vector vecPos, int iDamage, vector vecSpread, int iWeapon)
|
||||||
|
{
|
||||||
|
if (!g_traceAttack) {
|
||||||
|
g_traceAttack = spawn(NSTraceAttack);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_traceAttack.SetShots(iShots);
|
||||||
|
g_traceAttack.SetOrigin(vecPos);
|
||||||
|
g_traceAttack.SetDamage(iDamage);
|
||||||
|
g_traceAttack.SetSpread(vecSpread);
|
||||||
|
g_traceAttack.SetWeapon(iWeapon);
|
||||||
|
g_traceAttack.SetOwner(self);
|
||||||
|
g_traceAttack.Fire();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BULLETPENETRATION
|
#ifdef BULLETPENETRATION
|
||||||
void
|
void
|
||||||
TraceAttack_SetRangeModifier(float units)
|
TraceAttack_SetRangeModifier(float units)
|
||||||
{
|
{
|
||||||
g_pen_flRangeMod = units;
|
if (!g_traceAttack) {
|
||||||
|
g_traceAttack = spawn(NSTraceAttack);
|
||||||
|
}
|
||||||
|
g_traceAttack.m_flRangeModifier = (units);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
TraceAttack_SetPenetrationPower(int power)
|
TraceAttack_SetPenetrationPower(int power)
|
||||||
{
|
{
|
||||||
iTotalPenetrations = power;
|
if (!g_traceAttack) {
|
||||||
|
g_traceAttack = spawn(NSTraceAttack);
|
||||||
|
}
|
||||||
|
g_traceAttack.SetPenetrationPower(power);
|
||||||
/* thickness equals 8 units per power times rangemodifier */
|
/* thickness equals 8 units per power times rangemodifier */
|
||||||
g_pen_flMaxThickness = ((8 * power) * g_pen_flRangeMod);
|
g_traceAttack.SetPenetrationMaxThickness((8 * power) * g_traceAttack.m_flRangeModifier);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue