From 3d5cb0bc6d724af898fa23b4b9ca2026d73a00b0 Mon Sep 17 00:00:00 2001 From: pierow Date: Wed, 6 Sep 2023 13:41:27 -0400 Subject: [PATCH] Fixed func_breakable and func_weldable permanently blocking building placement This is a fix for Issue #55. Changes made: * Server ignores intangible entities when determining if a building placement is valid (fixes func_breakable issue) * If a func_weldable has the "welds open" spawnflag set, then upon completing the weld when it plays the break effect, it will become fully intangible. It will reset upon round restart. Fix by @RGreenlees --- main/source/mod/AvHSharedUtil.cpp | 4 +-- main/source/mod/AvHWeldable.cpp | 16 +++++++++-- main/source/mod/AvHWelder.cpp | 48 ++++++++++++++++--------------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/main/source/mod/AvHSharedUtil.cpp b/main/source/mod/AvHSharedUtil.cpp index 26f0d7b4..9591cef1 100644 --- a/main/source/mod/AvHSharedUtil.cpp +++ b/main/source/mod/AvHSharedUtil.cpp @@ -2745,7 +2745,7 @@ bool AvHSHUGetCanDropItem(vec3_t& ioCenter, Vector& inMinSize, Vector& inMaxSize //adjust origin to be base float theOrigin[3] = { ioCenter[0], ioCenter[1], ioCenter[2] + inMinSize[2] }; - CollisionChecker Checker(pmove,kHLPointHullIndex,CollisionChecker::HULL_TYPE_ALL,inIgnorePlayers,CollisionChecker::IGNORE_NONE,inIgnoreIndex); + CollisionChecker Checker(pmove, kHLPointHullIndex, CollisionChecker::HULL_TYPE_ALL, inIgnorePlayers, CollisionChecker::IGNORE_INTANGIBLE, inIgnoreIndex); bool theCanDropItem = (Checker.GetContentsInCylinder(theOrigin,theRadius,theHeight) != CONTENTS_SOLID); @@ -3553,7 +3553,7 @@ bool AvHSHUServerTraceWaypoint(const vec3_t& inStartPos, const vec3_t& inEndPos, { // and if surface isn't under water, lava, sky int thePointContents = UTIL_PointContents(tr.vecEndPos); - if(thePointContents == CONTENTS_EMPTY) + if (thePointContents == CONTENTS_EMPTY || thePointContents == 0) { // and if there's enough room to build if(outReturnCode) diff --git a/main/source/mod/AvHWeldable.cpp b/main/source/mod/AvHWeldable.cpp index 58e864f6..100381db 100644 --- a/main/source/mod/AvHWeldable.cpp +++ b/main/source/mod/AvHWeldable.cpp @@ -161,7 +161,12 @@ void AvHWeldable::Killed( entvars_t *pevAttacker, int iGib ) { AvHSUExplodeEntity(this, this->mMaterial); - AvHBaseEntity::Killed(pevAttacker, iGib); + //AvHBaseEntity::Killed(pevAttacker, iGib); + + this->pev->solid = SOLID_NOT; + this->pev->effects = EF_NODRAW; + this->pev->takedamage = DAMAGE_NO; + this->pev->deadflag = DEAD_DEAD; this->TriggerBroken(); } @@ -242,6 +247,8 @@ void AvHWeldable::SetPEVFlagsFromState() { this->pev->solid = SOLID_BSP; this->pev->movetype = MOVETYPE_PUSH; + this->pev->effects = 0; + this->pev->deadflag = DEAD_NO; } else { @@ -312,7 +319,12 @@ void AvHWeldable::UpdateEntityState() { this->pev->rendermode = kRenderTransTexture; this->pev->renderamt = 0; - this->pev->solid = 5; + //this->pev->solid = 5; + + this->pev->solid = SOLID_NOT; + this->pev->effects = EF_NODRAW; + this->pev->takedamage = DAMAGE_NO; + this->pev->deadflag = DEAD_DEAD; AvHSUExplodeEntity(this, this->mMaterial); } diff --git a/main/source/mod/AvHWelder.cpp b/main/source/mod/AvHWelder.cpp index 6ab2fd8d..6c4dfcdc 100644 --- a/main/source/mod/AvHWelder.cpp +++ b/main/source/mod/AvHWelder.cpp @@ -181,33 +181,35 @@ 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) + if (!theDidWeld) // Only check for cut strands if we're not welding something already { - AvHWebStrand* theWebStrand = dynamic_cast(thePotentialWebStrand); - if(theWebStrand) + // 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) { - //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) + AvHWebStrand* theWebStrand = dynamic_cast(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(); + } + + + } } }