From 08bda4008b5bc1f42e2f29f664abc9d65c172496 Mon Sep 17 00:00:00 2001 From: Sir-Skurpsalot <87043120+Sir-Skurpsalot@users.noreply.github.com> Date: Tue, 14 Apr 2026 21:35:46 -0600 Subject: [PATCH 1/6] Update player.cpp 1.added min and max prone look angle to datablock 2.added crawlsound, triggered like footsteps by animation trigger 3 3.added missing code for prone_side and prone_right animations 4.replaced box left/right/back/front head percentages with torso percentages, makes more sense for general use. 5.getDamageLocation() overhauled for better results in every pose 6.tweak to canSwim() to make sure player is actually submerged enough for the swim bounding box 7.fixed canCrouch(), canProne(), and canStand() calculations to work with lower boxSize.z values. 8.swapped order of canCrouch() and canProne() checks crouch so crouch does not need to be released in order to go prone (allows for scripting momentary crouch but toggle prone type setup if desired) 9.Added an engineMethod to check canProne() from script 10.tweaked canSprint to not allow if mWaterCoverage > 0.5 --- Engine/source/T3D/player.cpp | 264 ++++++++++++++++++++--------------- 1 file changed, 153 insertions(+), 111 deletions(-) diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index 0ccb13828b..3177e69bd3 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -170,6 +170,8 @@ PlayerData::ActionAnimationDef PlayerData::ActionAnimationList[NumTableActionAni { "prone_root" }, { "prone_forward", { 0.0f, 1.0f, 0.0f } }, { "prone_backward", { 0.0f,-1.0f, 0.0f } }, + { "prone_side", {-1.0f, 0.0f, 0.0f } }, //Skurps + { "prone_right", { 1.0f, 0.0f, 0.0f } }, //Skurps { "swim_root" }, { "swim_forward", { 0.0f, 1.0f, 0.0f } }, @@ -185,7 +187,6 @@ PlayerData::ActionAnimationDef PlayerData::ActionAnimationList[NumTableActionAni { "jet" }, // JetAnim }; - //---------------------------------------------------------------------------- typedef PlayerData::Sounds playerSoundsEnum; @@ -211,6 +212,7 @@ ImplementEnumType(playerSoundsEnum, "enum types.\n" { playerSoundsEnum::ImpactWaterMedium, "ImpactWaterMedium","..." }, { playerSoundsEnum::ImpactWaterHard, "ImpactWaterHard","..." }, { playerSoundsEnum::ExitWater, "ExitWater","..." }, + { playerSoundsEnum::Crawl, "Crawl","..." }, //Skurps EndImplementEnumType; //---------------------------------------------------------------------------- @@ -305,6 +307,8 @@ PlayerData::PlayerData() pickupRadius = 0.0f; minLookAngle = -1.4f; maxLookAngle = 1.4f; + minProneLookAngle = -.3491f; // Skurps + maxProneLookAngle = .3491f; // Skurps maxFreelookAngle = 3.0f; maxTimeScale = 1.5f; @@ -416,10 +420,10 @@ PlayerData::PlayerData() boxTorsoPercentage = 0.55f; // damage locations - boxHeadLeftPercentage = 0; - boxHeadRightPercentage = 1; - boxHeadBackPercentage = 0; - boxHeadFrontPercentage = 1; + boxTorsoLeftPercentage = 0; //Skurps replaced left/right/front/back head percentages + boxTorsoRightPercentage = 1; //Skurps + boxTorsoBackPercentage = 0; //Skurps + boxTorsoFrontPercentage = 1; //Skurps for (S32 i = 0; i < MaxSounds; i++) INIT_SOUNDASSET_ARRAY(PlayerSound, i); @@ -736,6 +740,14 @@ void PlayerData::initPersistFields() addFieldV( "maxFreelookAngle", TypeRangedF32, Offset(maxFreelookAngle, PlayerData), &CommonValidators::PositiveFloat, "@brief Defines the maximum left and right angles (in radians) the player can " "look in freelook mode.\n\n" ); + addField( "minProneLookAngle", TypeF32, Offset(minProneLookAngle, PlayerData), + "@brief Lowest angle (in radians) the player can look when Prone.\n\n" + "@note An angle of zero is straight ahead, with positive up and negative down." ); //Skurps + addField( "maxProneLookAngle", TypeF32, Offset(maxProneLookAngle, PlayerData), + "@brief Highest angle (in radians) the player can look when Prone.\n\n" + "@note An angle of zero is straight ahead, with positive up and negative down." ); //Skurps + + endGroup( "Camera" ); @@ -992,28 +1004,29 @@ void PlayerData::initPersistFields() "@brief Collision bounding box used when the player is swimming.\n\n" "@see boundingBox" ); - addFieldV( "boxHeadPercentage", TypeRangedF32, Offset(boxHeadPercentage, PlayerData), &CommonValidators::NormalizedFloat, + // Damage collision boxes changed by Skurps + addField( "boxHeadPercentage", TypeF32, Offset(boxHeadPercentage, PlayerData), "@brief Percentage of the player's bounding box height that represents the head.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addFieldV( "boxTorsoPercentage", TypeRangedF32, Offset(boxTorsoPercentage, PlayerData), &CommonValidators::NormalizedFloat, + addField( "boxTorsoPercentage", TypeF32, Offset(boxTorsoPercentage, PlayerData), "@brief Percentage of the player's bounding box height that represents the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addFieldV( "boxHeadLeftPercentage", TypeRangedF32, Offset(boxHeadLeftPercentage, PlayerData), &CommonValidators::NormalizedFloat, - "@brief Percentage of the player's bounding box width that represents the left side of the head.\n\n" + addField( "boxTorsoLeftPercentage", TypeF32, Offset(boxTorsoLeftPercentage, PlayerData), + "@brief Percentage of the player's bounding box width that represents the left side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addFieldV( "boxHeadRightPercentage", TypeRangedF32, Offset(boxHeadRightPercentage, PlayerData), &CommonValidators::NormalizedFloat, - "@brief Percentage of the player's bounding box width that represents the right side of the head.\n\n" + addField( "boxTorsoRightPercentage", TypeF32, Offset(boxTorsoRightPercentage, PlayerData), + "@brief Percentage of the player's bounding box width that represents the right side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addFieldV( "boxHeadBackPercentage", TypeRangedF32, Offset(boxHeadBackPercentage, PlayerData), &CommonValidators::NormalizedFloat, - "@brief Percentage of the player's bounding box depth that represents the back side of the head.\n\n" + addField( "boxTorsoBackPercentage", TypeF32, Offset(boxTorsoBackPercentage, PlayerData), + "@brief Percentage of the player's bounding box depth that represents the back side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addFieldV( "boxHeadFrontPercentage", TypeRangedF32, Offset(boxHeadFrontPercentage, PlayerData), &CommonValidators::NormalizedFloat, - "@brief Percentage of the player's bounding box depth that represents the front side of the head.\n\n" + addField( "boxTorsoFrontPercentage", TypeF32, Offset(boxTorsoFrontPercentage, PlayerData), + "@brief Percentage of the player's bounding box depth that represents the front side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); @@ -1174,6 +1187,8 @@ void PlayerData::packData(BitStream* stream) stream->write(minLookAngle); stream->write(maxLookAngle); stream->write(maxFreelookAngle); + stream->write(minProneLookAngle);//Skurps + stream->write(maxProneLookAngle);//Skurps stream->write(maxTimeScale); stream->write(mass); @@ -1356,6 +1371,8 @@ void PlayerData::unpackData(BitStream* stream) stream->read(&minLookAngle); stream->read(&maxLookAngle); stream->read(&maxFreelookAngle); + stream->read(&minProneLookAngle); // Skurps + stream->read(&maxProneLookAngle); // Skurps stream->read(&maxTimeScale); stream->read(&mass); @@ -2319,29 +2336,44 @@ const char* Player::getStateName() return "Move"; } +//Skurps - overhaul void Player::getDamageLocation(const Point3F& in_rPos, const char *&out_rpVert, const char *&out_rpQuad) { - // TODO: This will be WRONG when player is prone or swimming! - Point3F newPoint; mWorldToObj.mulP(in_rPos, &newPoint); Point3F boxSize = mObjBox.getExtents(); F32 zHeight = boxSize.z; - F32 zTorso = mDataBlock->boxTorsoPercentage; - F32 zHead = mDataBlock->boxHeadPercentage; + F32 yLength = boxSize.y; + F32 torsoLimit = mDataBlock->boxTorsoPercentage; + F32 headLimit = mDataBlock->boxHeadPercentage; - zTorso *= zHeight; - zHead *= zHeight; + if(mPose == PronePose) + { + torsoLimit = (torsoLimit * yLength) - (yLength / 2); + headLimit = (headLimit * yLength) - (yLength / 2); - if (newPoint.z <= zTorso) - out_rpVert = "legs"; - else if (newPoint.z <= zHead) - out_rpVert = "torso"; - else - out_rpVert = "head"; + if(newPoint.y <= torsoLimit) + out_rpVert = "legs"; + else if(newPoint.y <= headLimit) + out_rpVert = "torso"; + else + out_rpVert = "head"; + } + else + { + torsoLimit *= zHeight; + headLimit *= zHeight; + + if (newPoint.z <= torsoLimit) + out_rpVert = "legs"; + else if (newPoint.z <= headLimit) + out_rpVert = "torso"; + else + out_rpVert = "head"; + } - if(String::compare(out_rpVert, "head") != 0) + if(dStrcmp(out_rpVert, "torso") != 0) { if (newPoint.y >= 0.0f) { @@ -2360,40 +2392,36 @@ void Player::getDamageLocation(const Point3F& in_rPos, const char *&out_rpVert, } else { - F32 backToFront = boxSize.x; - F32 leftToRight = boxSize.y; + F32 xWidth = boxSize.x; - F32 backPoint = backToFront * mDataBlock->boxHeadBackPercentage; - F32 frontPoint = backToFront * mDataBlock->boxHeadFrontPercentage; - F32 leftPoint = leftToRight * mDataBlock->boxHeadLeftPercentage; - F32 rightPoint = leftToRight * mDataBlock->boxHeadRightPercentage; + //boxTorsoBackPercentage and boxTorsoLeftPercentage should both be negative floats + F32 backPoint = yLength * mDataBlock->boxTorsoBackPercentage; + F32 frontPoint = yLength * mDataBlock->boxTorsoFrontPercentage; + F32 leftPoint = xWidth * mDataBlock->boxTorsoLeftPercentage; + F32 rightPoint = xWidth * mDataBlock->boxTorsoRightPercentage; - S32 index = 0; - if (newPoint.y < backPoint) - index += 0; - else if (newPoint.y >= frontPoint) + S32 index = 0; //Middle hits are cases 0-2 + if (newPoint.y < backPoint) //Back hits are cases 3-5 index += 3; - else + else if (newPoint.y >= frontPoint) //Front hits are cases 6-8 index += 6; - if (newPoint.x < leftPoint) - index += 0; - else if (newPoint.x >= rightPoint) + if (newPoint.x < leftPoint) //Base number + 1 is left side index += 1; - else + else if (newPoint.x >= rightPoint) //Base number + 2 is right side index += 2; switch (index) { - case 0: out_rpQuad = "left_back"; break; - case 1: out_rpQuad = "middle_back"; break; - case 2: out_rpQuad = "right_back"; break; - case 3: out_rpQuad = "left_middle"; break; - case 4: out_rpQuad = "middle_middle"; break; - case 5: out_rpQuad = "right_middle"; break; - case 6: out_rpQuad = "left_front"; break; - case 7: out_rpQuad = "middle_front"; break; - case 8: out_rpQuad = "right_front"; break; + case 0: out_rpQuad = "middle_middle"; break; // "Middle middle" sounds confusing but it is the case that occurs when shot in the back when prone + case 1: out_rpQuad = "middle_left"; break; + case 2: out_rpQuad = "middle_right"; break; + case 3: out_rpQuad = "back_middle"; break; + case 4: out_rpQuad = "back_left"; break; + case 5: out_rpQuad = "back_right"; break; + case 6: out_rpQuad = "front_middle"; break; + case 7: out_rpQuad = "front_left"; break; + case 8: out_rpQuad = "front_right"; break; default: AssertFatal(0, "Bad non-tant index"); @@ -2686,8 +2714,13 @@ void Player::updateMove(const Move* move) F32 p = move->pitch * (mPose == SprintPose ? mDataBlock->sprintPitchScale : 1.0f); if (p > M_PI_F) p -= M_2PI_F; - mHead.x = mClampF(mHead.x + p,mDataBlock->minLookAngle, - mDataBlock->maxLookAngle); + + //Skurps - use different min/max if prone + F32 curMinLookAngle = mPose == PronePose ? mDataBlock->minProneLookAngle : mDataBlock->minLookAngle; + F32 curMaxLookAngle = mPose == PronePose ? mDataBlock->maxProneLookAngle : mDataBlock->maxLookAngle; + + mHead.x = mClampF(mHead.x + p,curMinLookAngle, + curMaxLookAngle); // Skurps F32 y = move->yaw * (mPose == SprintPose ? mDataBlock->sprintYawScale : 1.0f); if (y > M_PI_F) @@ -3234,11 +3267,11 @@ void Player::updateMove(const Move* move) if ( !mIsAiControlled ) { if ( mSwimming ) - desiredPose = SwimPose; - else if ( runSurface && move->trigger[sCrouchTrigger] && canCrouch() ) - desiredPose = CrouchPose; - else if ( runSurface && move->trigger[sProneTrigger] && canProne() ) + desiredPose = SwimPose; + else if ( runSurface && move->trigger[sProneTrigger] && canProne() ) //Skurps swapped with crouch so crouch does not need to be released in order to go prone desiredPose = PronePose; + else if ( runSurface && move->trigger[sCrouchTrigger] && canCrouch() ) + desiredPose = CrouchPose; else if ( move->trigger[sSprintTrigger] && canSprint() ) desiredPose = SprintPose; else if ( canStand() ) @@ -3311,27 +3344,27 @@ bool Player::canJetJump() } bool Player::canSwim() -{ - // Not used! - //return mState == MoveState && mDamageState == Enabled && !isMounted() && mEnergy >= mDataBlock->minSwimEnergy && mWaterCoverage >= 0.8f; - return mAllowSwimming; +{ + // Make sure swim bounding box would be submerged enough go to swim pose, necessary when crouched or prone in shallow water - Skurps + return mAllowSwimming && ((getPosition().z + mDataBlock->swimBoxSize.z) < mLiquidHeight); } +//Fixed to work with small boxsize.z values - Skurps bool Player::canCrouch() { if (!mAllowCrouching) return false; - if ( mState != MoveState || - mDamageState != Enabled || - isMounted() || + if ( mState != MoveState || + mDamageState != Enabled || + isMounted() || mSwimming || mFalling ) return false; // Can't crouch if no crouch animation! if ( mDataBlock->actionList[PlayerData::CrouchRootAnim].sequence == -1 ) - return false; + return false; // We are already in this pose, so don't test it again... if ( mPose == CrouchPose ) @@ -3340,22 +3373,13 @@ bool Player::canCrouch() // Do standard Torque physics test here! if ( !mPhysicsRep ) { - F32 radius; - - if ( mPose == PronePose ) - radius = mDataBlock->proneBoxSize.z; - else - return true; - - // use our X and Y dimentions on our boxsize as the radii for our search, and the difference between a standing position - // and the position we currently are in. - Point3F extent( mDataBlock->crouchBoxSize.x / 2, mDataBlock->crouchBoxSize.y / 2, mDataBlock->crouchBoxSize.z - radius ); + //Changed from stock because math does not work with small z values -Skurps + Point3F extent( mDataBlock->crouchBoxSize.x / 2, mDataBlock->crouchBoxSize.y / 2, mDataBlock->crouchBoxSize.z / 2); Point3F position = getPosition(); - position.z += radius; + position.z += (mDataBlock->crouchBoxSize.z / 2); //gets a position at the center of proposed crouch box. - // Use these radii to create a box that represents the difference between a standing position and the position - // we want to move into. + // Box shaped like new desired pose Box3F B(position - extent, position + extent, true); EarlyOutPolyList polyList; @@ -3376,39 +3400,27 @@ bool Player::canCrouch() return mPhysicsRep->testSpacials( getPosition(), mDataBlock->crouchBoxSize ); } -bool Player::canStand() -{ - if ( mState != MoveState || - mDamageState != Enabled || - isMounted() || +bool Player::canStand() //Fixed to work with small boxsize.z values - Skurps +{ + if ( mState != MoveState || + mDamageState != Enabled || + isMounted() || mSwimming ) return false; // We are already in this pose, so don't test it again... - if ( mPose == StandPose ) + if ( mPose == StandPose || mPose == SprintPose || mPose == SwimPose ) return true; // Do standard Torque physics test here! if ( !mPhysicsRep ) { - F32 radius; - - if (mPose == CrouchPose) - radius = mDataBlock->crouchBoxSize.z; - else if (mPose == PronePose) - radius = mDataBlock->proneBoxSize.z; - else - return true; - - // use our X and Y dimentions on our boxsize as the radii for our search, and the difference between a standing position - // and the position we currently are in. - Point3F extent( mDataBlock->boxSize.x / 2, mDataBlock->boxSize.y / 2, mDataBlock->boxSize.z - radius ); + Point3F extent( mDataBlock->boxSize.x / 2, mDataBlock->boxSize.y / 2, mDataBlock->boxSize.z /2 ); Point3F position = getPosition(); - position.z += radius; + position.z += (mDataBlock->boxSize.z / 2); //gets a position at the center of proposed stand box. - // Use these radii to create a box that represents the difference between a standing position and the position - // we want to move into. + // Box shaped like new desired pose Box3F B(position - extent, position + extent, true); EarlyOutPolyList polyList; @@ -3434,9 +3446,9 @@ bool Player::canProne() if (!mAllowProne) return false; - if ( mState != MoveState || - mDamageState != Enabled || - isMounted() || + if ( mState != MoveState || + mDamageState != Enabled || + isMounted() || mSwimming || mFalling ) return false; @@ -3458,7 +3470,8 @@ bool Player::canProne() bool Player::canSprint() { - return mAllowSprinting && mState == MoveState && mDamageState == Enabled && !isMounted() && mEnergy >= mDataBlock->minSprintEnergy && !mSwimming; + //Incorporate wading in deep water check -Skurps + return mAllowSprinting && mState == MoveState && mDamageState == Enabled && !isMounted() && mEnergy >= mDataBlock->minSprintEnergy && !mSwimming && mWaterCoverage < 0.5f; } //---------------------------------------------------------------------------- @@ -3511,14 +3524,19 @@ void Player::updateLookAnimation(F32 dt) // the min and max look angles provided in the datablock. if (mArmAnimation.thread) { + // Skurps + F32 curMinLookAngle = mPose == PronePose ? mDataBlock->minProneLookAngle : mDataBlock->minLookAngle; + F32 curMaxLookAngle = mPose == PronePose ? mDataBlock->maxProneLookAngle : mDataBlock->maxLookAngle; + if(mControlObject) { mShapeInstance->setPos(mArmAnimation.thread,0.5f); } else { - F32 d = mDataBlock->maxLookAngle - mDataBlock->minLookAngle; - F32 tp = (renderHead.x - mDataBlock->minLookAngle) / d; + F32 d = curMaxLookAngle - curMinLookAngle; //Skurps + F32 tp = (renderHead.x - curMinLookAngle) / d; //Skurps + mShapeInstance->setPos(mArmAnimation.thread,mClampF(tp,0,1)); } } @@ -3948,6 +3966,11 @@ void Player::updateActionThread() if (footfallSoundOverride <= 0) playFootstepSound( triggeredLeft, material, rInfo.object ); } + } + //Prone crawl sound - Skurps + if( mShapeInstance->getTriggerState( 3 ) ) + { + playCrawlSound(); } } @@ -4100,7 +4123,7 @@ void Player::pickActionAnimation() } else if ( mPose == PronePose ) { - pickBestMoveAction(PlayerData::ProneRootAnim, PlayerData::ProneBackwardAnim, &action, &forward); + pickBestMoveAction(PlayerData::ProneRootAnim, PlayerData::ProneRightAnim, &action, &forward); //Skurps } else if ( mPose == SprintPose ) { @@ -4329,7 +4352,6 @@ void Player::onImageStateAnimation(U32 imageSlot, const char* seqName, bool dire if (mDataBlock->allowImageStateAnimation && isGhost()) { MountedImage& image = mMountedImageList[imageSlot]; - // Just as with onImageAnimThreadChange we're going to apply various prefixes to determine the final sequence to use. // Here is the order: // imageBasePrefix_scriptPrefix_baseAnimName @@ -4449,7 +4471,7 @@ void Player::onImageAnimThreadChange(U32 imageSlot, S32 imageShapeIndex, ShapeBa return; } - // Just as with ShapeBase::udpateAnimThread we're going to apply various prefixes to determine the final sequence to use. + // Just as with ShapeBase::updateAnimThread we're going to apply various prefixes to determine the final sequence to use. // Here is the order: // imageBasePrefix_scriptPrefix_baseAnimName // imageBasePrefix_baseAnimName @@ -6399,7 +6421,10 @@ U32 Player::packUpdate(NetConnection *con, U32 mask, BitStream *stream) mRot.z = mWrapF(mRot.z, 0.0f, M_2PI_F); stream->writeFloat(mRot.z / M_2PI_F, 7); - stream->writeSignedFloat(mHead.x / (mDataBlock->maxLookAngle - mDataBlock->minLookAngle), 6); + //Skurps - use different min/max if prone + F32 curMinLookAngle = mPose == PronePose ? mDataBlock->minProneLookAngle : mDataBlock->minLookAngle; + F32 curMaxLookAngle = mPose == PronePose ? mDataBlock->maxProneLookAngle : mDataBlock->maxLookAngle; + stream->writeSignedFloat(mHead.x / ( curMaxLookAngle - curMinLookAngle), 6); //Skurps stream->writeSignedFloat(mHead.z / mDataBlock->maxFreelookAngle, 6); mDelta.move.pack(stream); stream->writeFlag(!(mask & NoWarpMask)); @@ -6505,7 +6530,10 @@ void Player::unpackUpdate(NetConnection *con, BitStream *stream) rot.y = rot.x = 0.0f; rot.z = stream->readFloat(7) * M_2PI_F; - mHead.x = stream->readSignedFloat(6) * (mDataBlock->maxLookAngle - mDataBlock->minLookAngle); + //Skurps - use different min/max if prone + F32 curMinLookAngle = mPose == PronePose ? mDataBlock->minProneLookAngle : mDataBlock->minLookAngle; //Skurps + F32 curMaxLookAngle = mPose == PronePose ? mDataBlock->maxProneLookAngle : mDataBlock->maxLookAngle; //Skurps + mHead.x = stream->readSignedFloat(6) * (curMaxLookAngle - curMinLookAngle); //Skurps mHead.z = stream->readSignedFloat(6) * mDataBlock->maxFreelookAngle; mDelta.move.unpack(stream); @@ -6918,6 +6946,13 @@ DefineEngineMethod( Player, checkDismountPoint, bool, ( Point3F oldPos, Point3F return object->checkDismountPosition(oldPosMat, posMat); } +//Skurps +DefineEngineMethod( Player, canProne, bool, ( ),, + "@brief checks if the engine would allow prone.\n") +{ + return object->canProne(); +} + DefineEngineMethod( Player, getNumDeathAnimations, S32, ( ),, "@brief Get the number of death animations available to this player.\n\n" "Death animations are assumed to be named death1-N using consecutive indices." ) @@ -7087,6 +7122,13 @@ void Player::playFootstepSound( bool triggeredLeft, Material* contactMaterial, S } } +//Skurps +void Player:: playCrawlSound() +{ + MatrixF crawlMat = getTransform(); + SFX->playOnce(mDataBlock->getPlayerSoundProfile( PlayerData::Crawl ), &crawlMat); +} + void Player:: playImpactSound() { if( mWaterCoverage == 0.0f ) From 1404bc801cfefaa7e935b48b11043e17f0b7c55a Mon Sep 17 00:00:00 2001 From: Sir-Skurpsalot <87043120+Sir-Skurpsalot@users.noreply.github.com> Date: Tue, 14 Apr 2026 21:38:16 -0600 Subject: [PATCH 2/6] Update player.h --- Engine/source/T3D/player.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Engine/source/T3D/player.h b/Engine/source/T3D/player.h index 05277a208a..78cb99d544 100644 --- a/Engine/source/T3D/player.h +++ b/Engine/source/T3D/player.h @@ -97,6 +97,10 @@ struct PlayerData: public ShapeBaseData /*protected AssetPtrCallback < already i F32 maxLookAngle; ///< Highest angle (radians) the player can look F32 maxFreelookAngle; ///< Max left/right angle the player can look + F32 minProneLookAngle; /// Skurps + F32 maxProneLookAngle; /// Skurps + + /// @name Physics constants /// @{ @@ -183,10 +187,11 @@ struct PlayerData: public ShapeBaseData /*protected AssetPtrCallback < already i F32 boxHeadPercentage; F32 boxTorsoPercentage; - F32 boxHeadLeftPercentage; - F32 boxHeadRightPercentage; - F32 boxHeadBackPercentage; - F32 boxHeadFrontPercentage; + //Skurps changed from Head to Torso + F32 boxTorsoLeftPercentage; + F32 boxTorsoRightPercentage; + F32 boxTorsoBackPercentage; + F32 boxTorsoFrontPercentage; /// @} F32 minImpactSpeed; ///< Minimum impact speed required to apply fall damage @@ -222,6 +227,7 @@ struct PlayerData: public ShapeBaseData /*protected AssetPtrCallback < already i ImpactWaterMedium, ImpactWaterHard, ExitWater, + Crawl,//Skurps MaxSounds }; @@ -273,6 +279,8 @@ struct PlayerData: public ShapeBaseData /*protected AssetPtrCallback < already i ProneRootAnim, ProneForwardAnim, ProneBackwardAnim, + ProneLeftAnim, //Skurps + ProneRightAnim, //Skurps SwimRootAnim, SwimForwardAnim, @@ -688,6 +696,8 @@ class Player: public ShapeBase /// @param contactMaterial Material onto which the player stepped; may be NULL. /// @param contactObject Object onto which the player stepped; may be NULL. void playFootstepSound( bool triggeredLeft, Material* contactMaterial, SceneObject* contactObject ); + /// Skurps prone crawl sound + void playCrawlSound(); /// Play an impact sound. void playImpactSound(); From b351b3ffbeb6e7cd0f7f396843289ec66559524e Mon Sep 17 00:00:00 2001 From: Sir-Skurpsalot <87043120+Sir-Skurpsalot@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:31:27 -0600 Subject: [PATCH 3/6] Update player.cpp --- Engine/source/T3D/player.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index 3177e69bd3..dc8ccb0b1d 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -1005,27 +1005,27 @@ void PlayerData::initPersistFields() "@see boundingBox" ); // Damage collision boxes changed by Skurps - addField( "boxHeadPercentage", TypeF32, Offset(boxHeadPercentage, PlayerData), + addField( "boxHeadPercentage", TypeF32, Offset(boxHeadPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box height that represents the head.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addField( "boxTorsoPercentage", TypeF32, Offset(boxTorsoPercentage, PlayerData), + addField( "boxTorsoPercentage", TypeF32, Offset(boxTorsoPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box height that represents the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addField( "boxTorsoLeftPercentage", TypeF32, Offset(boxTorsoLeftPercentage, PlayerData), + addField( "boxTorsoLeftPercentage", TypeF32, Offset(boxTorsoLeftPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box width that represents the left side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addField( "boxTorsoRightPercentage", TypeF32, Offset(boxTorsoRightPercentage, PlayerData), + addField( "boxTorsoRightPercentage", TypeF32, Offset(boxTorsoRightPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box width that represents the right side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addField( "boxTorsoBackPercentage", TypeF32, Offset(boxTorsoBackPercentage, PlayerData), + addField( "boxTorsoBackPercentage", TypeF32, Offset(boxTorsoBackPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box depth that represents the back side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addField( "boxTorsoFrontPercentage", TypeF32, Offset(boxTorsoFrontPercentage, PlayerData), + addField( "boxTorsoFrontPercentage", TypeF32, Offset(boxTorsoFrontPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box depth that represents the front side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); From 7e72dfba8114bec9ec605a2a736273785d3c52c5 Mon Sep 17 00:00:00 2001 From: Sir-Skurpsalot <87043120+Sir-Skurpsalot@users.noreply.github.com> Date: Wed, 15 Apr 2026 17:08:10 -0600 Subject: [PATCH 4/6] Update player.cpp fixed validator stuff --- Engine/source/T3D/player.cpp | 118 +++++++++++++++++------------------ 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index dc8ccb0b1d..b9042de638 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -120,9 +120,9 @@ static U32 sCollisionMoveMask = TerrainObjectType | PlayerObjectType | StaticShapeObjectType | VehicleObjectType | - PhysicalZoneObjectType | + PhysicalZoneObjectType | // PATHSHAPE - PathShapeObjectType; + PathShapeObjectType; // PATHSHAPE END static U32 sServerCollisionContactMask = sCollisionMoveMask | @@ -740,14 +740,14 @@ void PlayerData::initPersistFields() addFieldV( "maxFreelookAngle", TypeRangedF32, Offset(maxFreelookAngle, PlayerData), &CommonValidators::PositiveFloat, "@brief Defines the maximum left and right angles (in radians) the player can " "look in freelook mode.\n\n" ); - addField( "minProneLookAngle", TypeF32, Offset(minProneLookAngle, PlayerData), + addField( "minProneLookAngle", TypeF32, Offset(minProneLookAngle, PlayerData), "@brief Lowest angle (in radians) the player can look when Prone.\n\n" "@note An angle of zero is straight ahead, with positive up and negative down." ); //Skurps addField( "maxProneLookAngle", TypeF32, Offset(maxProneLookAngle, PlayerData), "@brief Highest angle (in radians) the player can look when Prone.\n\n" "@note An angle of zero is straight ahead, with positive up and negative down." ); //Skurps - + endGroup( "Camera" ); @@ -1004,28 +1004,28 @@ void PlayerData::initPersistFields() "@brief Collision bounding box used when the player is swimming.\n\n" "@see boundingBox" ); - // Damage collision boxes changed by Skurps - addField( "boxHeadPercentage", TypeF32, Offset(boxHeadPercentage, PlayerData), &CommonValidators::NormalizedFloat, + // Damage collision boxes changed by Skurps + addFieldV( "boxHeadPercentage", TypeRangedF32, Offset(boxHeadPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box height that represents the head.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addField( "boxTorsoPercentage", TypeF32, Offset(boxTorsoPercentage, PlayerData), &CommonValidators::NormalizedFloat, + addFieldV( "boxTorsoPercentage", TypeRangedF32, Offset(boxTorsoPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box height that represents the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addField( "boxTorsoLeftPercentage", TypeF32, Offset(boxTorsoLeftPercentage, PlayerData), &CommonValidators::NormalizedFloat, + addFieldV( "boxTorsoLeftPercentage", TypeRangedF32, Offset(boxTorsoLeftPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box width that represents the left side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addField( "boxTorsoRightPercentage", TypeF32, Offset(boxTorsoRightPercentage, PlayerData), &CommonValidators::NormalizedFloat, + addFieldV( "boxTorsoRightPercentage", TypeRangedF32, Offset(boxTorsoRightPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box width that represents the right side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addField( "boxTorsoBackPercentage", TypeF32, Offset(boxTorsoBackPercentage, PlayerData), &CommonValidators::NormalizedFloat, + addFieldV( "boxTorsoBackPercentage", TypeRangedF32, Offset(boxTorsoBackPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box depth that represents the back side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); - addField( "boxTorsoFrontPercentage", TypeF32, Offset(boxTorsoFrontPercentage, PlayerData), &CommonValidators::NormalizedFloat, + addFieldV( "boxTorsoFrontPercentage", TypeRangedF32, Offset(boxTorsoFrontPercentage, PlayerData), &CommonValidators::NormalizedFloat, "@brief Percentage of the player's bounding box depth that represents the front side of the torso.\n\n" "Used when computing the damage location.\n" "@see Player::getDamageLocation" ); @@ -2061,18 +2061,18 @@ void Player::processTick(const Move* move) } // Warp to catch up to server if (mDelta.warpTicks > 0) { - mDelta.warpTicks--; + mDelta.warpTicks--; // Set new pos getTransform().getColumn(3, &mDelta.pos); - mDelta.pos += mDelta.warpOffset; - mDelta.rot += mDelta.rotOffset; + mDelta.pos += mDelta.warpOffset; + mDelta.rot += mDelta.rotOffset; // Wrap yaw to +/-PI if (mDelta.rot.z < - M_PI_F) - mDelta.rot.z += M_2PI_F; + mDelta.rot.z += M_2PI_F; else if (mDelta.rot.z > M_PI_F) - mDelta.rot.z -= M_2PI_F; + mDelta.rot.z -= M_2PI_F; if (!ignore_updates) { @@ -2082,8 +2082,8 @@ void Player::processTick(const Move* move) updateLookAnimation(); // Backstepping - mDelta.posVec = -mDelta.warpOffset; - mDelta.rotVec = -mDelta.rotOffset; + mDelta.posVec = -mDelta.warpOffset; + mDelta.rotVec = -mDelta.rotOffset; } else { // If there is no move, the player is either an @@ -2583,7 +2583,7 @@ void Player::updateMove(const Move* move) // Update current orientation if (mDamageState == Enabled) { F32 prevZRot = mRot.z; - mDelta.headVec = mHead; + mDelta.headVec = mHead; bool doStandardMove = true; bool absoluteDelta = false; @@ -2714,8 +2714,8 @@ void Player::updateMove(const Move* move) F32 p = move->pitch * (mPose == SprintPose ? mDataBlock->sprintPitchScale : 1.0f); if (p > M_PI_F) p -= M_2PI_F; - - //Skurps - use different min/max if prone + + //Skurps - use different min/max if prone F32 curMinLookAngle = mPose == PronePose ? mDataBlock->minProneLookAngle : mDataBlock->minLookAngle; F32 curMaxLookAngle = mPose == PronePose ? mDataBlock->maxProneLookAngle : mDataBlock->maxLookAngle; @@ -2749,21 +2749,21 @@ void Player::updateMove(const Move* move) mRot.z -= M_2PI_F; } - mDelta.rot = mRot; - mDelta.rotVec.x = mDelta.rotVec.y = 0.0f; - mDelta.rotVec.z = prevZRot - mRot.z; + mDelta.rot = mRot; + mDelta.rotVec.x = mDelta.rotVec.y = 0.0f; + mDelta.rotVec.z = prevZRot - mRot.z; if (mDelta.rotVec.z > M_PI_F) - mDelta.rotVec.z -= M_2PI_F; + mDelta.rotVec.z -= M_2PI_F; else if (mDelta.rotVec.z < -M_PI_F) - mDelta.rotVec.z += M_2PI_F; + mDelta.rotVec.z += M_2PI_F; - mDelta.head = mHead; - mDelta.headVec -= mHead; + mDelta.head = mHead; + mDelta.headVec -= mHead; if (absoluteDelta) { mDelta.headVec = Point3F(0, 0, 0); - mDelta.rotVec = Point3F(0, 0, 0); + mDelta.rotVec = Point3F(0, 0, 0); } for(U32 i=0; i<3; ++i) @@ -2850,7 +2850,7 @@ void Player::updateMove(const Move* move) // Acceleration due to gravity VectorF acc(0.0f, 0.0f, mNetGravity/(1.0 - mBuoyancy) * TickSec); if (getParent() !=NULL) - acc = VectorF::Zero; + acc = VectorF::Zero; // Determine ground contact normal. Only look for contacts if // we can move and aren't mounted. @@ -3527,7 +3527,7 @@ void Player::updateLookAnimation(F32 dt) // Skurps F32 curMinLookAngle = mPose == PronePose ? mDataBlock->minProneLookAngle : mDataBlock->minLookAngle; F32 curMaxLookAngle = mPose == PronePose ? mDataBlock->maxProneLookAngle : mDataBlock->maxLookAngle; - + if(mControlObject) { mShapeInstance->setPos(mArmAnimation.thread,0.5f); @@ -3967,7 +3967,7 @@ void Player::updateActionThread() playFootstepSound( triggeredLeft, material, rInfo.object ); } } - //Prone crawl sound - Skurps + //Prone crawl sound - Skurps if( mShapeInstance->getTriggerState( 3 ) ) { playCrawlSound(); @@ -4777,7 +4777,7 @@ void Player::updateAttachment() } } else - { + { if (getParent() != NULL) { clearProcessAfter(); @@ -5280,8 +5280,8 @@ bool Player::updatePos(const F32 travelTime) if (isClientObject()) { mDelta.pos = newPos; - mDelta.posVec = mDelta.posVec - mDelta.pos; - mDelta.dt = 1.0f; + mDelta.posVec = mDelta.posVec - mDelta.pos; + mDelta.dt = 1.0f; } setPosition( newPos, mRot ); @@ -6305,7 +6305,7 @@ void Player::readPacketData(GameConnection *connection, BitStream *stream) stream->read(&mVelocity.y); stream->read(&mVelocity.z); stream->setCompressionPoint(pos); - mDelta.pos = pos; + mDelta.pos = pos; mJumpSurfaceLastContact = stream->readInt(4); if (stream->readFlag()) @@ -6421,12 +6421,12 @@ U32 Player::packUpdate(NetConnection *con, U32 mask, BitStream *stream) mRot.z = mWrapF(mRot.z, 0.0f, M_2PI_F); stream->writeFloat(mRot.z / M_2PI_F, 7); - //Skurps - use different min/max if prone + //Skurps - use different min/max if prone F32 curMinLookAngle = mPose == PronePose ? mDataBlock->minProneLookAngle : mDataBlock->minLookAngle; F32 curMaxLookAngle = mPose == PronePose ? mDataBlock->maxProneLookAngle : mDataBlock->maxLookAngle; stream->writeSignedFloat(mHead.x / ( curMaxLookAngle - curMinLookAngle), 6); //Skurps stream->writeSignedFloat(mHead.z / mDataBlock->maxFreelookAngle, 6); - mDelta.move.pack(stream); + mDelta.move.pack(stream); stream->writeFlag(!(mask & NoWarpMask)); } // Ghost need energy to predict reliably @@ -6530,33 +6530,33 @@ void Player::unpackUpdate(NetConnection *con, BitStream *stream) rot.y = rot.x = 0.0f; rot.z = stream->readFloat(7) * M_2PI_F; - //Skurps - use different min/max if prone + //Skurps - use different min/max if prone F32 curMinLookAngle = mPose == PronePose ? mDataBlock->minProneLookAngle : mDataBlock->minLookAngle; //Skurps F32 curMaxLookAngle = mPose == PronePose ? mDataBlock->maxProneLookAngle : mDataBlock->maxLookAngle; //Skurps mHead.x = stream->readSignedFloat(6) * (curMaxLookAngle - curMinLookAngle); //Skurps mHead.z = stream->readSignedFloat(6) * mDataBlock->maxFreelookAngle; - mDelta.move.unpack(stream); + mDelta.move.unpack(stream); - mDelta.head = mHead; - mDelta.headVec.set(0.0f, 0.0f, 0.0f); + mDelta.head = mHead; + mDelta.headVec.set(0.0f, 0.0f, 0.0f); if (stream->readFlag() && isProperlyAdded()) { // Determine number of ticks to warp based on the average // of the client and server velocities. - mDelta.warpOffset = pos - mDelta.pos; + mDelta.warpOffset = pos - mDelta.pos; F32 as = (speed + mVelocity.len()) * 0.5f * TickSec; F32 dt = (as > 0.00001f) ? mDelta.warpOffset.len() / as: sMaxWarpTicks; - mDelta.warpTicks = (S32)((dt > sMinWarpTicks) ? getMax(mFloor(dt + 0.5f), 1.0f) : 0.0f); + mDelta.warpTicks = (S32)((dt > sMinWarpTicks) ? getMax(mFloor(dt + 0.5f), 1.0f) : 0.0f); if (mDelta.warpTicks) { // Setup the warp to start on the next tick. if (mDelta.warpTicks > sMaxWarpTicks) - mDelta.warpTicks = sMaxWarpTicks; - mDelta.warpOffset /= (F32)mDelta.warpTicks; + mDelta.warpTicks = sMaxWarpTicks; + mDelta.warpOffset /= (F32)mDelta.warpTicks; - mDelta.rotOffset = rot - mDelta.rot; + mDelta.rotOffset = rot - mDelta.rot; // Ignore small rotation differences if (mFabs(mDelta.rotOffset.z) < 0.001f) @@ -6564,11 +6564,11 @@ void Player::unpackUpdate(NetConnection *con, BitStream *stream) // Wrap rotation to +/-PI if(mDelta.rotOffset.z < - M_PI_F) - mDelta.rotOffset.z += M_2PI_F; + mDelta.rotOffset.z += M_2PI_F; else if(mDelta.rotOffset.z > M_PI_F) - mDelta.rotOffset.z -= M_2PI_F; + mDelta.rotOffset.z -= M_2PI_F; - mDelta.rotOffset /= (F32)mDelta.warpTicks; + mDelta.rotOffset /= (F32)mDelta.warpTicks; } else { @@ -6584,18 +6584,18 @@ void Player::unpackUpdate(NetConnection *con, BitStream *stream) else { F32 dti = 1.0f / mDelta.dt; - mDelta.posVec = (cp - pos) * dti; - mDelta.rotVec.z = mRot.z - rot.z; + mDelta.posVec = (cp - pos) * dti; + mDelta.rotVec.z = mRot.z - rot.z; if(mDelta.rotVec.z > M_PI_F) mDelta.rotVec.z -= M_2PI_F; else if(mDelta.rotVec.z < -M_PI_F) mDelta.rotVec.z += M_2PI_F; - mDelta.rotVec.z *= dti; + mDelta.rotVec.z *= dti; } - mDelta.pos = pos; - mDelta.rot = rot; + mDelta.pos = pos; + mDelta.rot = rot; if (!ignore_updates) setPosition(pos,rot); } @@ -6605,10 +6605,10 @@ void Player::unpackUpdate(NetConnection *con, BitStream *stream) // Set the player to the server position mDelta.pos = pos; mDelta.rot = rot; - mDelta.posVec.set(0.0f, 0.0f, 0.0f); - mDelta.rotVec.set(0.0f, 0.0f, 0.0f); - mDelta.warpTicks = 0; - mDelta.dt = 0.0f; + mDelta.posVec.set(0.0f, 0.0f, 0.0f); + mDelta.rotVec.set(0.0f, 0.0f, 0.0f); + mDelta.warpTicks = 0; + mDelta.dt = 0.0f; if (!ignore_updates) setPosition(pos,rot); } From a49f9ff00677532b557f9e6848ab898425c1b382 Mon Sep 17 00:00:00 2001 From: Sir-Skurpsalot <87043120+Sir-Skurpsalot@users.noreply.github.com> Date: Wed, 15 Apr 2026 17:11:20 -0600 Subject: [PATCH 5/6] Update player.cpp --- Engine/source/T3D/player.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index b9042de638..3aa2ba51da 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -120,9 +120,9 @@ static U32 sCollisionMoveMask = TerrainObjectType | PlayerObjectType | StaticShapeObjectType | VehicleObjectType | - PhysicalZoneObjectType | + PhysicalZoneObjectType | // PATHSHAPE - PathShapeObjectType; + PathShapeObjectType; // PATHSHAPE END static U32 sServerCollisionContactMask = sCollisionMoveMask | From 51686fa45273f630df07275ec92ade681017075e Mon Sep 17 00:00:00 2001 From: Sir-Skurpsalot <87043120+Sir-Skurpsalot@users.noreply.github.com> Date: Wed, 15 Apr 2026 17:20:49 -0600 Subject: [PATCH 6/6] Update player.cpp --- Engine/source/T3D/player.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index 3aa2ba51da..8eec248b33 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -740,10 +740,10 @@ void PlayerData::initPersistFields() addFieldV( "maxFreelookAngle", TypeRangedF32, Offset(maxFreelookAngle, PlayerData), &CommonValidators::PositiveFloat, "@brief Defines the maximum left and right angles (in radians) the player can " "look in freelook mode.\n\n" ); - addField( "minProneLookAngle", TypeF32, Offset(minProneLookAngle, PlayerData), + addFieldV( "minProneLookAngle", TypeF32, Offset(minProneLookAngle, PlayerData), &CommonValidators::DirFloatPi, "@brief Lowest angle (in radians) the player can look when Prone.\n\n" "@note An angle of zero is straight ahead, with positive up and negative down." ); //Skurps - addField( "maxProneLookAngle", TypeF32, Offset(maxProneLookAngle, PlayerData), + addFieldV( "maxProneLookAngle", TypeF32, Offset(maxProneLookAngle, PlayerData), &CommonValidators::DirFloatPi, "@brief Highest angle (in radians) the player can look when Prone.\n\n" "@note An angle of zero is straight ahead, with positive up and negative down." ); //Skurps