1#include "Player/PlayerStateHeadSliding.h"
2
3#include "Library/LiveActor/ActorMovementFunction.h"
4#include "Library/LiveActor/ActorPoseUtil.h"
5#include "Library/Math/MathUtil.h"
6#include "Library/Nerve/NerveSetupUtil.h"
7#include "Library/Nerve/NerveUtil.h"
8
9#include "Player/PlayerActionDiveInWater.h"
10#include "Player/PlayerAnimator.h"
11#include "Player/PlayerConst.h"
12#include "Player/PlayerInput.h"
13#include "Util/ObjUtil.h"
14#include "Util/PlayerCollisionUtil.h"
15
16namespace {
17NERVE_IMPL(PlayerStateHeadSliding, Dive);
18NERVES_MAKE_NOSTRUCT(PlayerStateHeadSliding, Dive);
19} // namespace
20
21PlayerStateHeadSliding::PlayerStateHeadSliding(al::LiveActor* player, const PlayerConst* pConst,
22 const IUsePlayerCollision* collider,
23 const PlayerInput* input,
24 const PlayerActionDiveInWater* actionDiveInWater,
25 PlayerAnimator* animator)
26 : al::ActorStateBase("ヘッドスライディング", player), mConst(pConst), mCollider(collider),
27 mInput(input), mActionDiveInWater(actionDiveInWater), mAnimator(animator) {
28 initNerve(nerve: &Dive, stateCount: 0);
29}
30
31void PlayerStateHeadSliding::appear() {
32 mIsEnableDiveInWater = false;
33 al::NerveStateBase::appear();
34 al::setNerve(user: this, nerve: &Dive);
35}
36
37void PlayerStateHeadSliding::kill() {
38 al::NerveStateBase::kill();
39}
40
41bool PlayerStateHeadSliding::isEnableDiveInWater() const {
42 return mIsEnableDiveInWater;
43}
44
45void PlayerStateHeadSliding::exeDive() {
46 al::LiveActor* actor = mActor;
47 const sead::Vector3f& gravity = al::getGravity(actor);
48 if (al::isFirstStep(user: this)) {
49 mAnimator->startAnim(animName: "HeadSlidingStart");
50 sead::Vector3f velH = {0.0f, 0.0f, 0.0f};
51 sead::Vector3f velV = {0.0f, 0.0f, 0.0f};
52 al::separateVectorParallelVertical(&velV, &velH, gravity, al::getVelocity(actor));
53 if (!al::tryNormalizeOrZero(out: &velH))
54 al::calcFrontDir(front: &velH, actor);
55
56 if (velV.dot(t: gravity) > 0.0f)
57 velV = {0.0f, 0.0f, 0.0f};
58
59 velV.setScaleAdd(t: -mConst->getHeadSlidingJump(), a: gravity, b: velV);
60 al::setVelocity(actor, vel: (mConst->getHeadSlidingSpeed() * velH) + velV);
61 }
62
63 sead::Vector3f moveInput = {0.0f, 0.0f, 0.0f};
64 mInput->calcMoveInput(&moveInput, -gravity);
65 rs::moveDivingJump(actor, moveInput, 0.0f, mConst->getHeadSlidingBrake(),
66 mConst->getHeadSlidingSpeed(), mConst->getHeadSlidingSpeedMin(),
67 mConst->getHeadSlidingSideAccel(), mConst->getHeadSlidingGravityAir(),
68 mConst->getFallSpeedMax(), mConst->getSlerpQuatGrav());
69
70 if (mAnimator->isAnim(animName: "HeadSlidingStart") && mAnimator->isAnimEnd())
71 mAnimator->startAnim(animName: "HeadSliding");
72
73 mIsEnableDiveInWater |= mActionDiveInWater->judgeEnableDiveInWater();
74 if (rs::isOnGround(actor, mCollider))
75 kill();
76}
77