1#include "MapObj/FurnitureStateWait.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 "Util/PlayerCollisionUtil.h"
9#include "Util/PlayerUtil.h"
10
11namespace {
12NERVE_IMPL(FurnitureStateWait, Wait);
13NERVE_IMPL(FurnitureStateWait, BindRequest);
14
15NERVES_MAKE_STRUCT(FurnitureStateWait, Wait, BindRequest);
16} // namespace
17
18FurnitureStateWait::FurnitureStateWait(al::LiveActor* actor, FurnitureType furniture)
19 : al::ActorStateBase("待機", actor), mFurnitureType(furniture) {
20 initNerve(nerve: &NrvFurnitureStateWait.Wait, stateCount: 0);
21}
22
23void FurnitureStateWait::appear() {
24 al::NerveStateBase::appear();
25 al::setNerve(user: this, nerve: &NrvFurnitureStateWait.Wait);
26 mIsPlayerNotOnGround = !rs::isPlayerOnGround(mActor);
27 mPlayerState = PlayerFurnitureState::Unbound;
28}
29
30bool FurnitureStateWait::isEnableBindRequest() const {
31 return al::isNerve(user: this, nerve: &NrvFurnitureStateWait.BindRequest);
32}
33
34void FurnitureStateWait::exeWait() {
35 al::LiveActor* actor = mActor;
36
37 if (al::isFirstStep(user: this))
38 mPlayerPos = rs::getPlayerPos(actor);
39
40 bool isPlayerNoInput = rs::isPlayerNoInput(actor);
41 FurnitureType furniture = mFurnitureType;
42 bool isPlayerOnSomething = false;
43
44 if (rs::isPlayerNoInput(actor)) {
45 if (furniture == FurnitureType::Chair)
46 isPlayerOnSomething = rs::isPlayerOnChairActor(actor);
47 if (furniture == FurnitureType::Bed)
48 isPlayerOnSomething = rs::isPlayerOnBedActor(actor);
49 }
50
51 bool isPlayerOnGround = rs::isPlayerOnGround(actor);
52 const sead::Vector3f& newPlayerPos = rs::getPlayerPos(actor);
53 bool isPlayerStationary = al::isNearZero(vec: mPlayerPos - newPlayerPos);
54 mPlayerPos = newPlayerPos;
55
56 if (!isPlayerOnSomething || !isPlayerNoInput || !isPlayerStationary) {
57 mIsPlayerNotOnGround = !isPlayerOnGround;
58 al::setNerve(user: this, nerve: &NrvFurnitureStateWait.Wait);
59 return;
60 }
61 if (mIsPlayerNotOnGround) {
62 sead::Vector3f frontDir = sead::Vector3f::zero;
63 rs::calcPlayerFrontDir(&frontDir, actor);
64 sead::Vector3f plane = sead::Vector3f::zero;
65 al::calcFrontDir(front: &plane, actor);
66 f32 angle = al::calcAngleOnPlaneDegree(a: frontDir, b: plane, vertical: sead::Vector3f::ey);
67
68 if (90.0f < sead::Mathf::abs(x: angle))
69 mPlayerState = PlayerFurnitureState::AirNotFacing;
70 else
71 mPlayerState = PlayerFurnitureState::AirFacing;
72 mIsPlayerNotOnGround = false;
73 return;
74 }
75
76 s32 waitTime = (mFurnitureType == FurnitureType::Chair) ? 30 : 120;
77 if (al::isGreaterEqualStep(user: this, step: waitTime)) {
78 mPlayerState = PlayerFurnitureState::Bound;
79 al::setNerve(user: this, nerve: &NrvFurnitureStateWait.BindRequest);
80 }
81}
82
83void FurnitureStateWait::exeBindRequest() {
84 al::LiveActor* actor = mActor;
85 FurnitureType furniture = mFurnitureType;
86
87 if (!rs::isPlayerNoInput(actor)) {
88 al::setNerve(user: this, nerve: &NrvFurnitureStateWait.Wait);
89 return;
90 }
91
92 bool isPlayerOnSomething = false;
93 if (furniture == FurnitureType::Bed)
94 isPlayerOnSomething = rs::isPlayerOnBedActor(actor);
95 if (furniture == FurnitureType::Chair)
96 isPlayerOnSomething = rs::isPlayerOnChairActor(actor);
97 if (!isPlayerOnSomething)
98 al::setNerve(user: this, nerve: &NrvFurnitureStateWait.Wait);
99}
100