mirror of
https://github.com/ENSL/NS.git
synced 2025-02-21 11:21:55 +00:00
Fixed web hit detection
Fix for issue #94. Gorge web strands now have hit detection which matches their visible component. This is for both ensnaring marines, and for cutting them with a welder. This has the following impacts: * Webs are easier for marines to avoid since they can safely jump or duck under angled strands, however... * Webs are harder for marines to cut as they can no longer clear a while corridor with a single click but have to actually aim at each strand
This commit is contained in:
parent
5a04d595e3
commit
472e2c8d13
5 changed files with 125 additions and 16 deletions
|
@ -1712,32 +1712,55 @@ void AvHWebStrand::Spawn(void)
|
|||
CBeam::Spawn();
|
||||
|
||||
// Spawn code
|
||||
this->SetTouch(&AvHWebStrand::StrandTouch);
|
||||
this->pev->solid = SOLID_TRIGGER;
|
||||
//this->pev->solid = SOLID_BBOX;
|
||||
this->SetTouch(NULL);
|
||||
this->pev->solid = SOLID_NOT;
|
||||
this->pev->health = kWebHitPoints;
|
||||
this->pev->takedamage = DAMAGE_YES;
|
||||
this->mSolid=false;
|
||||
this->pev->nextthink = gpGlobals->time + BALANCE_VAR(kWebWarmupTime);
|
||||
this->mHardenTime = gpGlobals->time + BALANCE_VAR(kWebWarmupTime);
|
||||
this->pev->nextthink = gpGlobals->time + kWebThinkInterval;
|
||||
SetThink(&AvHWebStrand::StrandThink);
|
||||
|
||||
//SetBits(this->pev->flags, FL_MONSTER);
|
||||
|
||||
this->RelinkBeam();
|
||||
|
||||
EMIT_SOUND(ENT(this->pev), CHAN_AUTO, kWebStrandFormSound, 1.0, ATTN_IDLE);
|
||||
//SetThink(StrandExpire);
|
||||
//this->pev->nextthink = gpGlobals->time + kWebStrandLifetime;
|
||||
|
||||
}
|
||||
|
||||
void AvHWebStrand::StrandThink()
|
||||
{
|
||||
EMIT_SOUND(ENT(this->pev), CHAN_AUTO, kWebStrandHardenSound, 1.0, ATTN_IDLE);
|
||||
this->SetBrightness( 32 );
|
||||
this->SetColor( 255, 255, 255 );
|
||||
this->SetFrame(1);
|
||||
this->mSolid=true;
|
||||
SetThink(NULL);
|
||||
TraceResult Hit;
|
||||
|
||||
Vector StartTrace = this->GetStartPos();
|
||||
Vector EndTrace = this->GetEndPos();
|
||||
|
||||
UTIL_TraceLine(StartTrace, EndTrace, dont_ignore_monsters, nullptr, &Hit);
|
||||
|
||||
if (!FNullEnt(Hit.pHit))
|
||||
{
|
||||
edict_t* webbedEdict = Hit.pHit;
|
||||
AvHPlayer* theWebbedPlayer = dynamic_cast<AvHPlayer*>(CBaseEntity::Instance(webbedEdict));
|
||||
|
||||
if (theWebbedPlayer)
|
||||
{
|
||||
StrandTouch(theWebbedPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->mSolid)
|
||||
{
|
||||
if (gpGlobals->time >= this->mHardenTime)
|
||||
{
|
||||
EMIT_SOUND(ENT(this->pev), CHAN_AUTO, kWebStrandHardenSound, 1.0, ATTN_IDLE);
|
||||
this->SetBrightness(32);
|
||||
this->SetColor(255, 255, 255);
|
||||
this->SetFrame(1);
|
||||
this->mSolid = true;
|
||||
}
|
||||
}
|
||||
|
||||
this->pev->nextthink = gpGlobals->time + kWebThinkInterval;
|
||||
|
||||
}
|
||||
void AvHWebStrand::StrandExpire()
|
||||
{
|
||||
|
@ -1749,7 +1772,7 @@ void AvHWebStrand::StrandTouch( CBaseEntity *pOther )
|
|||
{
|
||||
// Webs can never break on friendlies
|
||||
//if(GetGameRules()->CanEntityDoDamageTo(this, pOther))
|
||||
if(pOther->pev->team != this->pev->team)
|
||||
if (pOther->pev->team != this->pev->team)
|
||||
{
|
||||
if ( this->mSolid ) {
|
||||
AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(pOther);
|
||||
|
|
|
@ -526,6 +526,7 @@ public:
|
|||
|
||||
private:
|
||||
bool mSolid;
|
||||
float mHardenTime;
|
||||
};
|
||||
|
||||
class AvHFuncResource : public CBaseAnimating
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "AvHMarineEquipmentConstants.h"
|
||||
#include "AvHWeldable.h"
|
||||
#include "AvHSpecials.h"
|
||||
#include "MathUtil.h"
|
||||
|
||||
#ifdef AVH_SERVER
|
||||
#include "AvHPlayerUpgrade.h"
|
||||
|
@ -179,16 +180,34 @@ void AvHWelder::FireProjectiles(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Scan area for webs, and clear them. I can't make the webs solid, and it seems like the welder might do this, so why not? Also
|
||||
// adds neat element of specialization where a guy with a welder might be needed to clear an area before an attack, kinda RPS
|
||||
const float kWebClearingRadius = 75;
|
||||
const float kWebCuttingDistance = 10.0f;
|
||||
CBaseEntity* thePotentialWebStrand = NULL;
|
||||
while((thePotentialWebStrand = UTIL_FindEntityInSphere(thePotentialWebStrand, theWelderBarrel, kWebClearingRadius)) != NULL)
|
||||
{
|
||||
AvHWebStrand* theWebStrand = dynamic_cast<AvHWebStrand*>(thePotentialWebStrand);
|
||||
if(theWebStrand)
|
||||
{
|
||||
theWebStrand->Break();
|
||||
//theWebStrand->Break();
|
||||
|
||||
Vector WelderCheckPoint;
|
||||
VectorGetMidPointOnLine(theWelderBarrel, vecEnd, WelderCheckPoint);
|
||||
|
||||
Vector ClosestPointOnStrand;
|
||||
VectorGetClosestPointOnLine(theWebStrand->GetStartPos(), theWebStrand->GetEndPos(), WelderCheckPoint, ClosestPointOnStrand);
|
||||
|
||||
float DistCuttingLineToStrand = VectorDistanceFromLine(theWelderBarrel, vecEnd, ClosestPointOnStrand);
|
||||
|
||||
if (DistCuttingLineToStrand <= kWebCuttingDistance)
|
||||
{
|
||||
theWebStrand->Break();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -349,6 +349,69 @@ double VectorDistance2D(const float* in1, const float* in2)
|
|||
return sqrt(theXDiff*theXDiff + theYDiff*theYDiff);
|
||||
}
|
||||
|
||||
// Added by Neoptolemus
|
||||
|
||||
void VectorGetClosestPointOnLine(const float* inLineFrom, const float* inLineTo, const float* inTestPosition, float *outClosestPoint)
|
||||
{
|
||||
|
||||
float vVector1[3];
|
||||
VectorSubtract(inTestPosition, inLineFrom, vVector1);
|
||||
|
||||
float vVector2[3];
|
||||
VectorSubtract(inLineTo, inLineFrom, vVector2);
|
||||
|
||||
VectorNormalize(vVector2);
|
||||
|
||||
float d = VectorDistance(inLineTo, inLineFrom);
|
||||
float t = DotProduct(vVector2, vVector1);
|
||||
|
||||
if (t <= 0)
|
||||
{
|
||||
outClosestPoint[0] = inLineFrom[0];
|
||||
outClosestPoint[1] = inLineFrom[1];
|
||||
outClosestPoint[2] = inLineFrom[2];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (t >= d)
|
||||
{
|
||||
outClosestPoint[0] = inLineTo[0];
|
||||
outClosestPoint[1] = inLineTo[1];
|
||||
outClosestPoint[2] = inLineTo[2];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
float vVector3[3];
|
||||
|
||||
VectorScale(vVector2, t, vVector3);
|
||||
|
||||
outClosestPoint[0] = inLineFrom[0] + vVector3[0];
|
||||
outClosestPoint[1] = inLineFrom[1] + vVector3[1];
|
||||
outClosestPoint[2] = inLineFrom[2] + vVector3[2];
|
||||
|
||||
}
|
||||
|
||||
float VectorDistanceFromLine(const float* inLineFrom, const float* inLineTo, const float* inTestPosition)
|
||||
{
|
||||
float nearestPointToLine[3];
|
||||
VectorGetClosestPointOnLine(inLineFrom, inLineTo, inTestPosition, nearestPointToLine);
|
||||
|
||||
return VectorDistance(inTestPosition, nearestPointToLine);
|
||||
}
|
||||
|
||||
void VectorGetMidPointOnLine(const float* inLineFrom, const float* inLineTo, float* outPosition)
|
||||
{
|
||||
float vVector1[3];
|
||||
VectorSubtract(inLineTo, inLineFrom, vVector1);
|
||||
VectorScale(vVector1, 0.5f, vVector1);
|
||||
|
||||
VectorAdd(inLineFrom, vVector1, outPosition);
|
||||
}
|
||||
|
||||
|
||||
// Added by mmcguire.
|
||||
|
||||
void VectorsToAngles(const float forward[3], const float right[3], const float up[3], float angles[3])
|
||||
|
|
|
@ -47,6 +47,9 @@ bool IsVectorBetweenBoundingVectors(const float* inOrigin, const float* inRay, c
|
|||
void VectorRotate (const float* in1, const float in2[3][4], float* out);
|
||||
double VectorDistance(const float* in1, const float* in2);
|
||||
double VectorDistance2D(const float* in1, const float* in2);
|
||||
void VectorGetClosestPointOnLine(const float* inLineFrom, const float* inLineTo, const float* inTestPosition, float* outClosestPoint);
|
||||
float VectorDistanceFromLine(const float* inLineFrom, const float* inLineTo, const float* inTestPosition);
|
||||
void VectorGetMidPointOnLine(const float* inLineFrom, const float* inLineTo, float* outPosition);
|
||||
|
||||
// Added by mmcguire.
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue