1#include "Player/PlayerStateWallAir.h"
2
3#include "Library/LiveActor/ActorPoseUtil.h"
4#include "Library/Math/MathUtil.h"
5#include "Library/Nerve/NerveSetupUtil.h"
6#include "Library/Nerve/NerveUtil.h"
7
8#include "Player/PlayerJudgePreInputJump.h"
9#include "Player/PlayerStateNormalWallJump.h"
10#include "Player/PlayerStateNormalWallSlide.h"
11#include "Player/PlayerWallActionHistory.h"
12#include "Util/JudgeUtil.h"
13
14namespace {
15NERVE_IMPL(PlayerStateWallAir, Slide)
16NERVE_IMPL(PlayerStateWallAir, Jump)
17
18NERVES_MAKE_NOSTRUCT(PlayerStateWallAir, Slide, Jump)
19} // namespace
20
21PlayerStateWallAir::PlayerStateWallAir(al::LiveActor* player, const PlayerConst* pConst,
22 const PlayerInput* input, const PlayerTrigger* trigger,
23 IUsePlayerCollision* collision, IJudge* judgeWallKeep,
24 PlayerJudgePreInputJump* judgePreInputJump,
25 PlayerAnimator* animator,
26 PlayerWallActionHistory* wallActionHistory,
27 PlayerActionDiveInWater* actionDiveInWater)
28 : al::ActorStateBase("空中壁接触", player), mConst(pConst), mJudgeWallKeep(judgeWallKeep),
29 mJudgePreInputJump(judgePreInputJump), mCollision(collision),
30 mWallActionHistory(wallActionHistory) {
31 initNerve(nerve: &Slide, stateCount: 2);
32 mStateNormalWallSlide =
33 new PlayerStateNormalWallSlide(player, mConst, input, collision, animator);
34 mStateNormalWallJump = new PlayerStateNormalWallJump(player, mConst, input, collision, trigger,
35 animator, actionDiveInWater);
36 al::initNerveState(user: this, state: mStateNormalWallSlide, nerve: &Slide, hostName: "壁すべり");
37 al::initNerveState(user: this, state: mStateNormalWallJump, nerve: &Jump, hostName: "壁ジャンプ");
38}
39
40void PlayerStateWallAir::appear() {
41 al::NerveStateBase::appear();
42 al::setNerve(user: this, nerve: &Slide);
43}
44
45bool PlayerStateWallAir::isAir() const {
46 return al::isNerve(user: this, nerve: &Jump) && al::isGreaterStep(user: this, step: 0);
47}
48
49bool PlayerStateWallAir::isJustJump() const {
50 return al::isNerve(user: this, nerve: &Jump) && al::isFirstStep(user: this);
51}
52
53bool PlayerStateWallAir::isEnableReactionCapCatch() const {
54 return !isDead() && al::isNerve(user: this, nerve: &Jump);
55}
56
57void PlayerStateWallAir::startSlideSpinAttack() {
58 al::LiveActor* player = mActor;
59 const sead::Vector3f& gravity = al::getGravity(actor: player);
60 mWallActionHistory->recordWallJump(collider: mCollision, position: al::getTrans(actor: player) + gravity * 20.0f);
61
62 sead::Vector3f front = {0.0f, 0.0f, 0.0f};
63 al::calcFrontDir(front: &front, actor: player);
64
65 sead::Quatf quat = sead::Quatf::unit;
66 al::makeQuatFrontUp(outQuat: &quat, front: -front, up: -gravity);
67 al::updatePoseQuat(actor: player, quat);
68}
69
70void PlayerStateWallAir::calcSnapMoveCutDir(sead::Vector3f* cutDir) const {
71 if (al::isNerve(user: this, nerve: &Slide))
72 cutDir->set(mStateNormalWallSlide->getNormalStart());
73 else
74 cutDir->set(mStateNormalWallJump->getFront());
75}
76
77void PlayerStateWallAir::exeSlide() {
78 if (al::updateNerveState(user: this)) {
79 mWallActionHistory->recordWallLeave(position: al::getTrans(actor: mActor),
80 normal: mStateNormalWallSlide->getNormalStart());
81 kill();
82 return;
83 }
84
85 if (rs::judgeAndResetReturnTrue(judge: mJudgePreInputJump)) {
86 mWallActionHistory->recordWallJump(collider: mCollision, position: al::getTrans(actor: mActor));
87 al::setNerve(user: this, nerve: &Jump);
88 }
89}
90
91void PlayerStateWallAir::exeJump() {
92 if (al::updateNerveState(user: this)) {
93 kill();
94 return;
95 }
96
97 if (rs::updateJudgeAndResult(judge: mJudgeWallKeep))
98 al::setNerve(user: this, nerve: &Slide);
99}
100