Skip to content

Commit

Permalink
Player: Implement PlayerActionSlopeSlideControl
Browse files Browse the repository at this point in the history
  • Loading branch information
MonsterDruide1 committed Mar 3, 2025
1 parent 47f7bf1 commit d70f6c9
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 11 deletions.
8 changes: 4 additions & 4 deletions data/odyssey_functions.csv
Original file line number Diff line number Diff line change
Expand Up @@ -26083,10 +26083,10 @@ Address,Quality,Size,Name
0x0000007100418c60,U,000060,_ZN28PlayerActionPivotTurnControl5resetEv
0x0000007100418c9c,U,001064,_ZN28PlayerActionPivotTurnControl6updateEv
0x00000071004190c4,U,000032,_ZN28PlayerActionPivotTurnControl17calcMoveDirectionEPN4sead7Vector3IfEERKS2_
0x00000071004190e4,U,000068,_ZN29PlayerActionSlopeSlideControlC2EPN2al9LiveActorEPK11PlayerConstPK11PlayerInputPK19IUsePlayerCollision
0x0000007100419128,U,000184,_ZN29PlayerActionSlopeSlideControl5setupEv
0x00000071004191e0,U,000284,_ZN29PlayerActionSlopeSlideControl24setupCutSlideOppositeDirEv
0x00000071004192fc,U,002068,_ZN29PlayerActionSlopeSlideControl6updateEffffffffffb
0x00000071004190e4,O,000068,_ZN29PlayerActionSlopeSlideControlC2EPN2al9LiveActorEPK11PlayerConstPK11PlayerInputPK19IUsePlayerCollision
0x0000007100419128,O,000184,_ZN29PlayerActionSlopeSlideControl5setupEv
0x00000071004191e0,O,000284,_ZN29PlayerActionSlopeSlideControl24setupCutSlideOppositeDirEv
0x00000071004192fc,O,002068,_ZN29PlayerActionSlopeSlideControl6updateEffffffffffb
0x0000007100419b10,U,000124,_ZN23PlayerActionTurnControlC2EPN2al9LiveActorE
0x0000007100419b8c,U,000028,_ZN23PlayerActionTurnControl5setupEffffiii
0x0000007100419ba8,U,000024,_ZN23PlayerActionTurnControl5resetEv
Expand Down
163 changes: 163 additions & 0 deletions src/Player/PlayerActionSlopeSlideControl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#include "Player/PlayerActionSlopeSlideControl.h"

#include "Library/LiveActor/ActorMovementFunction.h"
#include "Library/LiveActor/ActorPoseKeeper.h"
#include "Library/Math/MathUtil.h"

#include "Player/PlayerConst.h"
#include "Player/PlayerInput.h"
#include "Util/ObjUtil.h"
#include "Util/PlayerCollisionUtil.h"

PlayerActionSlopeSlideControl::PlayerActionSlopeSlideControl(al::LiveActor* player,
const PlayerConst* pConst,
const PlayerInput* input,
const IUsePlayerCollision* collider)
: mPlayer(player), mConst(pConst), mInput(input), mCollision(collider) {}

void PlayerActionSlopeSlideControl::setup() {
mGroundNormal = -al::getGravity(mPlayer);
mDirSlide = {0.0f, 0.0f, 0.0f};

if (rs::isCollidedGround(mCollision)) {
al::calcDirSlide(&mDirSlide, al::getGravity(mPlayer),
rs::getCollidedGroundNormal(mCollision));
if (!rs::isJustLand(mCollision))
mGroundNormal = rs::getCollidedGroundNormal(mCollision);
}

mHorizontalVelocity = {0.0f, 0.0f, 0.0f};
}

void PlayerActionSlopeSlideControl::setupCutSlideOppositeDir() {
setup();

sead::Vector3f groundNormal = {0.0f, 0.0f, 0.0f};
rs::calcGroundNormalOrGravityDir(&groundNormal, mPlayer, mCollision);

sead::Vector3f slideDir = {0.0f, 0.0f, 0.0f};
sead::Vector3f* velocityPtr = al::getVelocityPtr(mPlayer);
al::alongVectorNormalH(velocityPtr, *velocityPtr, mGroundNormal, groundNormal);
if (rs::calcSlideDir(&slideDir, al::getGravity(mPlayer), groundNormal))
al::limitVectorOppositeDir(velocityPtr, slideDir, *velocityPtr, velocityPtr->length());

*velocityPtr -= mConst->getGravityMove() * groundNormal;
mGroundNormal = groundNormal;
}

f32 PlayerActionSlopeSlideControl::update(f32 accel, f32 brake, f32 against, f32 anglePowerMax,
f32 maxSpeed, f32 sideAccel, f32 sideBrake,
f32 sideMaxSpeed, f32 turnDegree, f32 gravity,
bool isRolling) {
sead::Vector3f prevGroundNormal = mGroundNormal;
sead::Vector3f up = -al::getGravity(mPlayer);
sead::Vector3f velocity = al::getVelocity(mPlayer);
bool isOnGroundSlopeSlideEnd = rs::isOnGroundSlopeSlideEnd(mPlayer, mCollision, mConst);
if (rs::isOnGround(mPlayer, mCollision)) {
mGroundNormal = rs::getCollidedGroundNormal(mCollision);
up = mGroundNormal;
al::calcDirSlide(&mDirSlide, al::getGravity(mPlayer), up);
al::alongVectorNormalH(&velocity, velocity, prevGroundNormal, up);

sead::Vector3f velDirSlide = {0.0f, 0.0f, 0.0f};
sead::Vector3f velSide = {0.0f, 0.0f, 0.0f};
if (isOnGroundSlopeSlideEnd) {
al::separateVectorParallelVertical(&velSide, &velDirSlide, up, velocity);
velDirSlide *= brake;
velSide *= sideBrake;
if (isRolling) {
sead::Vector3f moveInput = {0.0f, 0.0f, 0.0f};
mInput->calcMoveInput(&moveInput, up);

sead::Vector3f normDirSlide = {0.0f, 0.0f, 0.0f};
al::tryNormalizeOrZero(&normDirSlide, velDirSlide);

sead::Vector3f side;
side.setCross(up, normDirSlide);
al::tryNormalizeOrZero(&side);

f32 sideInput = side.dot(moveInput);
sead::Vector3f moveSideVec = side * sideInput * sideAccel;
al::addVectorLimit(&velDirSlide, moveSideVec, maxSpeed);
}
} else {
al::separateVectorParallelVertical(&velDirSlide, &velSide, mDirSlide, velocity);
sead::Vector3f moveInput = {0.0f, 0.0f, 0.0f};
mInput->calcMoveInput(&moveInput, up);
f32 speedDirSlide = velDirSlide.dot(mDirSlide);
if (speedDirSlide < 0.0)
velDirSlide *= brake;

f32 moveInputAgainst = sead::Mathf::clamp(-mDirSlide.dot(moveInput), 0.0f, 1.0f);
f32 minSpeedNorm = sead::Mathf::clamp(1.0f - (moveInputAgainst * against), 0.0, 1.0);
f32 speedNorm = sead::Mathf::clamp(speedDirSlide + 1.0f, minSpeedNorm, 1.0f);

f32 anglePower = sead::Mathf::clamp(
90.0f - al::calcAngleDegree(mDirSlide, al::getGravity(mPlayer)), 0.0f, 90.0f);

f32 anglePowerNorm = 1.0f;
if (anglePowerMax > 0.0)
anglePowerNorm = sead::Mathf::clampMax(anglePower / anglePowerMax, 1.0f);

al::addVectorLimit(&velDirSlide, mDirSlide * accel * anglePowerNorm * speedNorm,
maxSpeed);
velSide *= sideBrake;
sead::Vector3f inputDir = {0.0f, 0.0f, 0.0f};
if (al::tryNormalizeOrZero(&inputDir, moveInput)) {
sead::Vector3f sideDir;
sideDir.setCross(up, mDirSlide);
al::addVectorLimit(&velSide,
sideDir * sideDir.dot(inputDir) * moveInput.length() * sideAccel,
sideMaxSpeed);
}
}

sead::Vector3f vel;
vel.x = velDirSlide.x + velSide.x;
vel.y = velDirSlide.y + velSide.y;
vel.z = velDirSlide.z + velSide.z;
al::limitLength(&vel, vel, maxSpeed);
al::setVelocity(mPlayer, vel - (mConst->getGravityMove() * up));
} else {
mGroundNormal = up;
f32 prevUpVel = prevGroundNormal.dot(al::getVelocity(mPlayer));
al::alongVectorNormalH(al::getVelocityPtr(mPlayer), al::getVelocity(mPlayer),
prevGroundNormal, mGroundNormal);
sead::Vector3f* velPtr = al::getVelocityPtr(mPlayer);
velPtr->x = (prevUpVel * mGroundNormal.x) + velPtr->x;
velPtr->y = (prevUpVel * mGroundNormal.y) + velPtr->y;
velPtr->z = (prevUpVel * mGroundNormal.z) + velPtr->z;
al::addVectorLimit(al::getVelocityPtr(mPlayer), up * -gravity, mConst->getFallSpeedMax());
}

sead::Vector3f hVel = {0.0f, 0.0f, 0.0f};
al::verticalizeVec(&hVel, up, al::getVelocity(mPlayer));
sead::Vector3f hVelDir = {0.0f, 0.0f, 0.0f};

f32 rumbleStrength;
if (al::tryNormalizeOrZero(&hVelDir, hVel)) {
sead::Vector3f front = {0.0f, 0.0f, 0.0f};
al::calcFrontDir(&front, mPlayer);
al::verticalizeVec(&front, up, front);
al::tryNormalizeOrZero(&front);
if (turnDegree > 0.0) {
f32 angleFrontVel = 2 * al::calcAngleDegree(front, hVelDir);
f32 turn = sead::Mathf::clamp(angleFrontVel / turnDegree, 0.0f, 1.0f);
sead::Vector3f upFrontVel;
upFrontVel.setCross(front, hVelDir);
rumbleStrength = -al::sign(up.dot(upFrontVel)) * turn;
} else {
rumbleStrength = 0.0;
}

al::turnVecToVecCosOnPlane(&front, hVelDir, up,
sead::Mathf::cos(sead::Mathf::deg2rad(turnDegree)));
rs::slerpUpFront(mPlayer, up, front, mConst->getSlerpQuatRate(),
mConst->getHillPoseDegreeMax());
} else {
rumbleStrength = 0.0;
}

mHorizontalVelocity = hVel;
return rumbleStrength;
}
14 changes: 7 additions & 7 deletions src/Player/PlayerActionSlopeSlideControl.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#pragma once

#include <basis/seadTypes.h>
#include <math/seadVector.h>

namespace al {
Expand All @@ -12,11 +11,12 @@ class IUsePlayerCollision;

class PlayerActionSlopeSlideControl {
public:
PlayerActionSlopeSlideControl(al::LiveActor*, const PlayerConst*, const PlayerInput*,
const IUsePlayerCollision*);
PlayerActionSlopeSlideControl(al::LiveActor* player, const PlayerConst* pConst,
const PlayerInput* input, const IUsePlayerCollision* collider);
void setup();
void setupCutSlideOppositeDir();
f32 update(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, bool);
f32 update(f32 accel, f32 brake, f32 against, f32 anglePowerMax, f32 maxSpeed, f32 sideAccel,
f32 sideBrake, f32 sideMaxSpeed, f32 turnDegree, f32 gravity, bool isRolling);

const sead::Vector3f& getDirSlide() const { return mDirSlide; }

Expand All @@ -29,9 +29,9 @@ class PlayerActionSlopeSlideControl {
const PlayerConst* mConst;
const PlayerInput* mInput;
const IUsePlayerCollision* mCollision;
sead::Vector3f mDirSlide = {0.0f, 0.0f, 0.0f};
sead::Vector3f mGroundNormal = {0.0f, 0.0f, 0.0f};
sead::Vector3f mHorizontalVelocity = {0.0f, 0.0f, 0.0f};
sead::Vector3f mDirSlide = sead::Vector3f::zero;
sead::Vector3f mGroundNormal = sead::Vector3f::zero;
sead::Vector3f mHorizontalVelocity = sead::Vector3f::zero;
};

static_assert(sizeof(PlayerActionSlopeSlideControl) == 0x48);
3 changes: 3 additions & 0 deletions src/Util/ObjUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,7 @@ void startHitReactionHipDropLand(al::LiveActor*, bool);

void waitGround(al::LiveActor*, const IUsePlayerCollision*, f32, f32, f32, f32);

void slerpUpFront(al::LiveActor*, const sead::Vector3f&, const sead::Vector3f&, f32, f32);

bool calcSlideDir(sead::Vector3f*, const sead::Vector3f&, const sead::Vector3f&);
} // namespace rs

0 comments on commit d70f6c9

Please sign in to comment.