* spawn/speed optimisation for NSPhysicsEntity

* pick a better dmgDir for hitscan NSProjectiles so physics ent feedback is accurate

* fix NSPhysicsEntities not becoming invulnerable after breaking
This commit is contained in:
Marco Cawthorne 2024-09-03 12:15:16 -07:00
parent b60d420692
commit bf567da9ba
Signed by: eukara
GPG key ID: CE2032F0A2882A22
6 changed files with 59 additions and 38 deletions

View file

@ -472,7 +472,7 @@ NSItem::PredictPreFrame(void)
/* relink */
if (m_nextItem == __NULL__ && chain_entnum)
m_nextItem = findentity(world, ::entnum, chain_entnum);
m_nextItem = (NSItem)findentity(world, ::entnum, chain_entnum);
if (owner == __NULL__ && owner_entnum) {
owner = findentity(world, ::entnum, owner_entnum);

View file

@ -509,6 +509,7 @@ NSPhysicsEntity::_TouchThink(void)
/* continue testing next frame */
nextthink = time;
effects &= ~EF_NOSHADOW;
solid = SOLID_BSP;
}
#ifdef SERVER
@ -518,19 +519,21 @@ NSPhysicsEntity::Pain(entity inflictor, entity attacker, int damage, vector dir,
vector forceDir;
float force;
if (m_strOnDamaged)
if (m_strOnDamaged) {
UseOutput(this, m_strOnDamaged);
}
if (m_iFlags & BPHY_NODMGPUSH)
if (m_iFlags & BPHY_NODMGPUSH) {
return;
}
Wake();
forceDir = normalize(GetOrigin() - g_dmg_vecLocation);
force = CalculateImpactDamage(g_dmg_iDamage, g_dmg_iFlags);
force = CalculateImpactDamage(damage, g_dmg_iFlags);
if (force > 0.0f)
ApplyForceOffset(forceDir * force, g_dmg_vecLocation);
if (force > 0.0f) {
ApplyForceOffset(dir * force, g_dmg_vecLocation);
}
/* HACK: */
if (m_bInvincible) {
@ -546,16 +549,6 @@ NSPhysicsEntity::Death(entity inflictor, entity attacker, int damage, vector dir
{
Pain(inflictor, attacker, damage, dir, location);
super::Death(inflictor, attacker, damage, dir, location);
if (takedamage != DAMAGE_YES) {
takedamage = (DAMAGE_YES);
}
/* HACK: */
if (m_bInvincible) {
health = 10000;
}
/* make sure touch think is called */
nextthink = time;
}
@ -584,7 +577,7 @@ NSPhysicsEntity::Respawn(void)
bouncefactor = 0.0f;
bouncestop = 0.0f;
geomtype = GEOMTYPE_TRIMESH;
geomtype = GEOMTYPE_BOX;
friction = 1.0f;
m_flBuoyancyRatio = 1.0f;
@ -965,6 +958,14 @@ NSPhysicsEntity::Wake(void)
if (physics_supported() == TRUE) {
SetMovetype(MOVETYPE_PHYSICS);
SetSolid(SOLID_BSP);
/* Don't need a lot of precision during this */
if (time < 5.0) {
geomtype = GEOMTYPE_BOX;
} else {
geomtype = GEOMTYPE_TRIMESH;
}
physics_enable(this, TRUE);
} else {
SetMovetype(MOVETYPE_BOUNCE);
@ -980,6 +981,7 @@ NSPhysicsEntity::Sleep(void)
ClearVelocity();
physics_enable(this, FALSE);
SetMovetype(MOVETYPE_NONE);
SetSolid(SOLID_CORPSE);
} else {
SetMovetype(MOVETYPE_NONE);
SetSolid(SOLID_BBOX);

View file

@ -790,6 +790,7 @@ NSProjectile::_LaunchHitscan(vector startPos, vector launchDir, float dmgMultipl
}
if (m_eMultiTarget) {
angles = launchDir;
_ApplyDamage();
}
}
@ -811,7 +812,7 @@ NSProjectile::_ApplyDamage(void)
NSDict damageDecl = spawn(NSDict);
damageDecl.AddKey("hitbody", itos(trace_surface_id));
damageDecl.AddKey("damage", itos(m_iMultiValue));
vector dmgDir = dirFromTarget(GetOrigin(), m_eMultiTarget.origin);
vector dmgDir = normalize(angles);
entityDamage(m_eMultiTarget, owner, owner, damageDecl.GetDeclBody(), GetWeaponOwner().classname, GetOrigin(), dmgDir, trace_endpos);
remove(damageDecl);
@ -897,6 +898,7 @@ NSProjectile::_FireSingle(vector vecPos, vector vecAngles, float flDamage, float
if (trace_ent.takedamage != DAMAGE_NO) {
if (trace_ent != m_eMultiTarget) {
trace_endpos = endPos;
angles = vecAngles;
_ApplyDamage();
m_eMultiTarget = (NSSurfacePropEntity)trace_ent;
m_iMultiValue = flDamage;

View file

@ -334,20 +334,22 @@ NSSurfacePropEntity::Extinguish(void)
void
NSSurfacePropEntity::Respawn(void)
{
float sh = GetSpawnHealth();
NSRenderableEntity::Respawn();
float sh = GetSpawnFloat("health");
super::Respawn();
/* only use spawndata's health if we aren't overriding it */
if (HasPropData() != false && sh <= 0) {
health = (float)GetPropData(PROPINFO_HEALTH);
SetHealth((float)GetPropData(PROPINFO_HEALTH));
} else {
health = sh;
SetHealth(sh);
}
if (health > 0)
takedamage = DAMAGE_YES;
else
takedamage = DAMAGE_NO;
if (GetHealth() > 0) {
MakeVulnerable();
} else {
MakeInvulnerable();
}
}
void
@ -504,6 +506,7 @@ NSSurfacePropEntity::BreakModel(int damage, vector dir, int location)
{
m_flDeathTime = time;
MakeInvulnerable();
UseOutput(g_dmg_eAttacker, m_strOnBreak);
if (HasPropData() == false) {
@ -516,7 +519,6 @@ NSSurfacePropEntity::BreakModel(int damage, vector dir, int location)
string gibeffect = GetPropData(PROPINFO_BREAKMODEL);
int breakcount = GetPropData(PROPINFO_BREAKCOUNT);
BreakModel_Entity(this, dir, g_dmg_iDamage);
//BreakModel_Spawn(absmin, absmax, [0,0,0], 100, breakcount, gibeffect);
Disappear();
} else {
Disappear();
@ -528,8 +530,9 @@ NSSurfacePropEntity::BreakModel(int damage, vector dir, int location)
flExplodeRad = GetPropData(PROPINFO_EXPLOSIVE_RADIUS);
if (flExplodeMag) {
if (!flExplodeRad)
if (!flExplodeRad) {
flExplodeRad = flExplodeMag * 2.5f;
}
pointparticles(particleeffectnum("fx_explosion.main"), origin, angles, 1);
radiusDamage(origin, flExplodeRad, 0i, (int)flExplodeMag, this);
@ -555,10 +558,11 @@ NSSurfacePropEntity::_SurfaceDataFinish(void)
{
SurfData_SetStage(m_strSurfData);
if (m_strSurfData)
if (m_strSurfData) {
m_iMaterial = SurfData_Finish();
else
} else {
m_iMaterial = -1i;
}
}
void
@ -566,17 +570,19 @@ NSSurfacePropEntity::_PropDataFinish(void)
{
PropData_SetStage(m_strPropData);
if (m_strPropData)
if (m_strPropData) {
m_iPropData = PropData_Finish();
else
} else {
m_iPropData = -1i;
}
}
float
NSSurfacePropEntity::TimeSinceDeath(void)
{
if (IsAlive())
return (-1);
if (IsAlive()) {
return (-1.0f);
}
return (time - m_flDeathTime);
}

View file

@ -14,11 +14,14 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
static string g_lastSpawnData;
static entityDef_t g_entDefTable[ENTITYDEF_MAX];
static int g_entDefCount;
static string g_entDefInclude;
#ifdef SERVER
static string g_lastSpawnData;
#endif
void
EntityDef_ReadFile(string filePath)
{

View file

@ -259,6 +259,12 @@ PropData_ParsePhyFile(int i, string line, string type)
case "fadetime":
gibFadeTime = argv(x+1);
break;
case "health":
/* TODO: what's this? */
break;
case "burst":
/* TODO: what's this? */
break;
}
} else if (braced == 0i) {
t_name = strtolower(key);
@ -845,8 +851,9 @@ BreakModel_Spawn(vector smins, vector smaxs, vector dir, float speed, int count,
vector pvsPosition;
index = (int)hash_get(g_hashbreakmodel, type, -1);
if (index == -1)
if (index == -1) {
return;
}
pvsPosition = (smins + ( 0.5 * ( smaxs - smins )));
@ -875,8 +882,9 @@ BreakModel_Entity(NSSurfacePropEntity target, vector dir, float speed)
int index = (int)hash_get(g_hashbreakmodel, type, -1);
vector pos = target.GetOrigin();
if not (index)
if not (index) {
return;
}
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_BREAKMODEL);