| 1 | #include "Player/PlayerJudgeGrabCeil.h" |
| 2 | |
| 3 | #include "Library/Collision/CollisionParts.h" |
| 4 | #include "Library/LiveActor/ActorMovementFunction.h" |
| 5 | #include "Library/LiveActor/ActorPoseUtil.h" |
| 6 | #include "Library/Math/MathUtil.h" |
| 7 | |
| 8 | #include "Player/IPlayerModelChanger.h" |
| 9 | #include "Player/PlayerCarryKeeper.h" |
| 10 | #include "Player/PlayerConst.h" |
| 11 | #include "Player/PlayerExternalVelocity.h" |
| 12 | #include "Util/ObjUtil.h" |
| 13 | #include "Util/PlayerCollisionUtil.h" |
| 14 | |
| 15 | PlayerJudgeGrabCeil::PlayerJudgeGrabCeil(const al::LiveActor* player, const PlayerConst* pConst, |
| 16 | const IUsePlayerCollision* collider, |
| 17 | const IPlayerModelChanger* modelChanger, |
| 18 | const PlayerCarryKeeper* carryKeeper, |
| 19 | const PlayerExternalVelocity* externalVelocity) |
| 20 | : mPlayer(player), mConst(pConst), mCollision(collider), mModelChanger(modelChanger), |
| 21 | mCarryKeeper(carryKeeper), mExternalVelocity(externalVelocity) {} |
| 22 | |
| 23 | void PlayerJudgeGrabCeil::reset() { |
| 24 | mIsJudge = false; |
| 25 | _48 = {0.0f, 0.0f, 0.0f}; |
| 26 | _54 = {0.0f, 0.0f, 0.0f}; |
| 27 | _60 = {0.0f, 0.0f, 0.0f}; |
| 28 | } |
| 29 | |
| 30 | void PlayerJudgeGrabCeil::update() { |
| 31 | mIsJudge = false; |
| 32 | |
| 33 | if (mCarryKeeper->isCarry() || mModelChanger->is2DModel() || |
| 34 | mExternalVelocity->isExistForce() || !rs::isCollisionCodeGrabCeilAny(mCollision)) |
| 35 | return; |
| 36 | |
| 37 | if (rs::isCollisionCodeGrabCeilWall(mCollision)) { |
| 38 | sead::Vector3f pos = rs::getCollidedWallPos(mCollision); |
| 39 | sead::Vector3f normal = rs::getCollidedWallNormal(mCollision); |
| 40 | |
| 41 | if (!mExternalVelocity->isExistSnapForce()) { |
| 42 | sead::Vector3f verticalVelocity = al::getVelocity(actor: mPlayer); |
| 43 | al::verticalizeVec(out: &verticalVelocity, vertical: al::getGravity(actor: mPlayer), vec: verticalVelocity); |
| 44 | if (al::tryNormalizeOrZero(out: &verticalVelocity) && normal.dot(t: verticalVelocity) > 0.0f) |
| 45 | return; |
| 46 | } |
| 47 | |
| 48 | sead::Vector3f forceMovePower = {0.0f, 0.0f, 0.0f}; |
| 49 | rs::getCollidedWallCollisionParts(mCollision)->calcForceMovePower(&forceMovePower, pos); |
| 50 | |
| 51 | mIsJudge = rs::findGrabCeilPosWallHit( |
| 52 | &mCollidedParts, &_48, &_54, &_60, mPlayer, -normal, pos + forceMovePower, |
| 53 | mConst->getTall(), mConst->getGrabCeilRange(), mConst->getGrabCeilBodyRadius()); |
| 54 | |
| 55 | return; |
| 56 | } |
| 57 | |
| 58 | sead::Vector3f collidedNormal = {0.0f, 0.0f, 0.0f}; |
| 59 | sead::Vector3f collidedPos = {0.0f, 0.0f, 0.0f}; |
| 60 | const al::CollisionParts* collidedParts = nullptr; |
| 61 | |
| 62 | if (rs::isCollisionCodeGrabCeilCeiling(mCollision)) { |
| 63 | collidedNormal = rs::getCollidedCeilingNormal(mCollision); |
| 64 | collidedPos = rs::getCollidedCeilingPos(mCollision); |
| 65 | collidedParts = rs::getCollidedCeilingCollisionParts(mCollision); |
| 66 | } else if (rs::isCollisionCodeGrabCeilGrround(mCollision)) { |
| 67 | collidedNormal = rs::getCollidedGroundNormal(mCollision); |
| 68 | collidedPos = rs::getCollidedGroundPos(mCollision); |
| 69 | collidedParts = rs::getCollidedGroundCollisionParts(mCollision); |
| 70 | if (!mExternalVelocity->isExistSnapForce()) { |
| 71 | sead::Vector3f velocity = al::getVelocity(actor: mPlayer); |
| 72 | if (al::tryNormalizeOrZero(out: &velocity) && velocity.dot(t: collidedNormal) > 0.0f) |
| 73 | return; |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | sead::Vector3f forceMovePower = {0.0f, 0.0f, 0.0f}; |
| 78 | collidedParts->calcForceMovePower(&forceMovePower, collidedPos); |
| 79 | |
| 80 | mIsJudge = rs::findGrabCeilPosNoWallHit( |
| 81 | &mCollidedParts, &_48, &_54, &_60, mPlayer, collidedNormal, collidedPos + forceMovePower, |
| 82 | mConst->getTall(), mConst->getGrabCeilRange(), mConst->getGrabCeilBodyRadius()); |
| 83 | |
| 84 | if (!mIsJudge) |
| 85 | return; |
| 86 | |
| 87 | f32 dot = _54.dot(t: al::getVelocity(actor: mPlayer)); |
| 88 | if (sead::Mathf::abs(x: dot) > mConst->getNormalMinSpeed()) { |
| 89 | if (dot < 0.0f) { |
| 90 | _54 *= -1; |
| 91 | al::normalize(vec: &_54); |
| 92 | } |
| 93 | } else { |
| 94 | sead::Vector3f front = {0.0f, 0.0f, 0.0f}; |
| 95 | al::calcFrontDir(front: &front, actor: mPlayer); |
| 96 | if (front.dot(t: _54) < 0.0f) { |
| 97 | _54 *= -1; |
| 98 | al::normalize(vec: &_54); |
| 99 | } |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | bool PlayerJudgeGrabCeil::judge() const { |
| 104 | return mIsJudge; |
| 105 | } |
| 106 | |