From 27ea8b9b51d7a4a670f3059a499aec9178c8ad4e Mon Sep 17 00:00:00 2001 From: marcushutchings <40723596+marcushutchings@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:18:26 +0100 Subject: [PATCH] Bar105 allow unit def waterline (#1414) --------- Co-authored-by: lostsquirrel --- rts/Sim/MoveTypes/GroundMoveType.cpp | 19 ++++++++++--------- rts/Sim/MoveTypes/MoveDefHandler.cpp | 4 ++-- rts/Sim/MoveTypes/MoveDefHandler.h | 7 +++++++ rts/Sim/MoveTypes/MoveMath/GroundMoveMath.cpp | 2 +- rts/Sim/MoveTypes/MoveMath/HoverMoveMath.cpp | 2 +- rts/Sim/MoveTypes/MoveMath/MoveMath.cpp | 2 +- rts/Sim/MoveTypes/MoveMath/MoveMath.h | 1 + rts/Sim/Path/QTPFS/NodeLayer.cpp | 3 +-- 8 files changed, 24 insertions(+), 16 deletions(-) diff --git a/rts/Sim/MoveTypes/GroundMoveType.cpp b/rts/Sim/MoveTypes/GroundMoveType.cpp index 8ed30f9821..277d786de5 100644 --- a/rts/Sim/MoveTypes/GroundMoveType.cpp +++ b/rts/Sim/MoveTypes/GroundMoveType.cpp @@ -2772,8 +2772,6 @@ void CGroundMoveType::HandleUnitCollisions( const bool allowSAT = modInfo.allowSepAxisCollisionTest; const bool forceSAT = (colliderParams.z > 0.1f); - MoveTypes::CheckCollisionQuery colliderInfo(collider); - // Push resistent units when stopped impacting pathing and also cannot be pushed, so it is important that such // units are not going to prevent other units from moving around them if they are near narrow pathways. const float colliderSeparationDist = (pushResistant && pushResistanceBlockActive) ? 0.f : colliderUD->separationDistance; @@ -2782,6 +2780,9 @@ void CGroundMoveType::HandleUnitCollisions( const float maxCollisionRadius = colliderParams.y + moveDefHandler.GetLargestFootPrintSizeH(); const float searchRadius = colliderParams.x + maxCollisionRadius + colliderSeparationDist; + MoveTypes::CheckCollisionQuery colliderInfo(collider); + if ( !colliderMD->overrideUnitWaterline ) + colliderInfo.DisableHeightChecks(); // copy on purpose, since the below can call Lua QuadFieldQuery qfQuery; @@ -2808,8 +2809,6 @@ void CGroundMoveType::HandleUnitCollisions( // don't push/crush either party if the collidee does not block the collider (or vv.) if (colliderMobile && CMoveMath::IsNonBlocking(collidee, &colliderInfo)) continue; - if (collideeMobile && CMoveMath::IsNonBlocking(collider, &colliderInfo)) - continue; // disable collisions between collider and collidee // if collidee is currently inside any transporter, @@ -3209,12 +3208,15 @@ float CGroundMoveType::GetGroundHeight(const float3& p) const // in [minHeight, maxHeight] const float gh = CGround::GetHeightReal(p.x, p.z); - const float wh = -md->waterline * (gh <= 0.0f); - + // in [-waterline, maxHeight], note that waterline // can be much deeper than ground in shallow water - if (owner->FloatOnWater()) + if (owner->FloatOnWater()) { + MoveDef *md = owner->moveDef; + const float wh = ((md->overrideUnitWaterline) ? -md->waterline : -owner->unitDef->waterline) * (gh <= 0.0f); + return (std::max(gh, wh)); + } return gh; } @@ -3282,8 +3284,7 @@ void CGroundMoveType::UpdatePos(const CUnit* unit, const float3& moveDir, float3 MoveTypes::CheckCollisionQuery virtualObject(unit); MoveDefs::CollisionQueryStateTrack queryState; - const bool isSubmersible = (md->isSubmarine || - (md->followGround && md->depth > md->height)); + const bool isSubmersible = md->IsComplexSubmersible(); if (!isSubmersible) virtualObject.DisableHeightChecks(); diff --git a/rts/Sim/MoveTypes/MoveDefHandler.cpp b/rts/Sim/MoveTypes/MoveDefHandler.cpp index 3e76d385d0..a8b4381b10 100644 --- a/rts/Sim/MoveTypes/MoveDefHandler.cpp +++ b/rts/Sim/MoveTypes/MoveDefHandler.cpp @@ -322,6 +322,7 @@ MoveDef::MoveDef(const LuaTable& moveDefTable): MoveDef() { defaultWaterline = 1; } waterline = std::abs(moveDefTable.GetInt("waterline", defaultWaterline)); + overrideUnitWaterline = moveDefTable.GetBool("overrideUnitWaterline", overrideUnitWaterline); } else { waterline = std::numeric_limits::max(); } @@ -444,9 +445,8 @@ bool MoveDef::DoRawSearch( : MoveTypes::CheckCollisionQuery(md); MoveDefs::CollisionQueryStateTrack queryState; md->UpdateCheckCollisionQuery(virtualObject, queryState, startBlock); + const bool isSubmersible = md->IsComplexSubmersible(); - const bool isSubmersible = (md->isSubmarine || - (md->followGround && md->depth > md->height)); if (!isSubmersible) virtualObject.DisableHeightChecks(); diff --git a/rts/Sim/MoveTypes/MoveDefHandler.h b/rts/Sim/MoveTypes/MoveDefHandler.h index 21d9eae757..61f0fb583e 100644 --- a/rts/Sim/MoveTypes/MoveDefHandler.h +++ b/rts/Sim/MoveTypes/MoveDefHandler.h @@ -99,6 +99,10 @@ struct MoveDef { unsigned int CalcCheckSum() const; + bool IsComplexSubmersible() const { + return (isSubmarine || (followGround && depth > height)) && overrideUnitWaterline; + }; + static float GetDefaultMinWaterDepth() { return -1e6f; } static float GetDefaultMaxWaterDepth() { return +1e6f; } @@ -172,6 +176,9 @@ struct MoveDef { bool followGround = true; /// are we supposed to be a purely sub-surface ship? bool isSubmarine = false; + /// If false, this forces the use of simple underwater collisions, which can cause some pathing issues for + /// amphibious units. i.e. they are blocked by obstacles above and below the water regardless of height. + bool overrideUnitWaterline = true; /// do we try to pathfind around squares blocked by mobile units? /// diff --git a/rts/Sim/MoveTypes/MoveMath/GroundMoveMath.cpp b/rts/Sim/MoveTypes/MoveMath/GroundMoveMath.cpp index 3f939675ac..8b9c60fd4e 100644 --- a/rts/Sim/MoveTypes/MoveMath/GroundMoveMath.cpp +++ b/rts/Sim/MoveTypes/MoveMath/GroundMoveMath.cpp @@ -30,7 +30,7 @@ float CMoveMath::GroundSpeedMod(const MoveDef& moveDef, float height, float slop float CMoveMath::GroundSpeedMod(const MoveDef& moveDef, float height, float slope, float dirSlopeMod) { - RECOIL_DETAILED_TRACY_ZONE; + RECOIL_DETAILED_TRACY_ZONE; // Directional speed is now equal to regular except when: // 1) Climbing out of places which are below max depth. // 2) Climbing hills is slower. diff --git a/rts/Sim/MoveTypes/MoveMath/HoverMoveMath.cpp b/rts/Sim/MoveTypes/MoveMath/HoverMoveMath.cpp index ddb05b3e6a..89dfff1b7f 100644 --- a/rts/Sim/MoveTypes/MoveMath/HoverMoveMath.cpp +++ b/rts/Sim/MoveTypes/MoveMath/HoverMoveMath.cpp @@ -24,7 +24,7 @@ float CMoveMath::HoverSpeedMod(const MoveDef& moveDef, float height, float slope float CMoveMath::HoverSpeedMod(const MoveDef& moveDef, float height, float slope, float dirSlopeMod) { - RECOIL_DETAILED_TRACY_ZONE; + RECOIL_DETAILED_TRACY_ZONE; // Only difference direction can have is making hills climbing slower. // no speed-penalty if on water diff --git a/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp b/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp index e66fbdccb8..b09ecfad7e 100644 --- a/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp +++ b/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp @@ -241,7 +241,7 @@ bool CMoveMath::IsNonBlocking(const CSolidObject* collidee, const MoveTypes::Che // owner would need to be accessible, but the path-estimator // defs are not tied to any collider instances // - if (collider->pos.y == MoveTypes::CheckCollisionQuery::POS_Y_UNAVAILABLE) { + if ( !collider->IsHeightChecksEnabled() ) { const bool colliderIsSub = collider->moveDef->isSubmarine; const bool collideeIsSub = collidee->moveDef != nullptr && collidee->moveDef->isSubmarine; diff --git a/rts/Sim/MoveTypes/MoveMath/MoveMath.h b/rts/Sim/MoveTypes/MoveMath/MoveMath.h index 567f085d66..9fa391cdff 100644 --- a/rts/Sim/MoveTypes/MoveMath/MoveMath.h +++ b/rts/Sim/MoveTypes/MoveMath/MoveMath.h @@ -36,6 +36,7 @@ namespace MoveTypes { void ClearPhysicalStateBit(unsigned int bit) { unsigned int ps = physicalState; ps &= (~bit); physicalState = static_cast(ps); } bool IsInWater() const { return (HasPhysicalStateBit(CSolidObject::PhysicalState::PSTATE_BIT_INWATER)); } void DisableHeightChecks() { pos.y = POS_Y_UNAVAILABLE; } + bool IsHeightChecksEnabled() const { return pos.y != MoveTypes::CheckCollisionQuery::POS_Y_UNAVAILABLE; } const CSolidObject* unit = nullptr; const MoveDef* moveDef = nullptr; diff --git a/rts/Sim/Path/QTPFS/NodeLayer.cpp b/rts/Sim/Path/QTPFS/NodeLayer.cpp index 8838ec6fdd..4c796ef089 100644 --- a/rts/Sim/Path/QTPFS/NodeLayer.cpp +++ b/rts/Sim/Path/QTPFS/NodeLayer.cpp @@ -101,8 +101,7 @@ bool QTPFS::NodeLayer::Update(UpdateThreadData& threadData) { MoveTypes::CheckCollisionQuery virtualObject(md); MoveDefs::CollisionQueryStateTrack queryState; - const bool isSubmersible = (md->isSubmarine || - (md->followGround && md->depth > md->height)); + const bool isSubmersible = md->IsComplexSubmersible(); if (!isSubmersible) { CMoveMath::FloodFillRangeIsBlocked(*md, nullptr, threadData.areaMaxBlockBits, threadData.maxBlockBits, threadData.threadId); }