1#include "MapObj/MoonBasementSlideObj.h"
2
3#include "Library/LiveActor/ActorActionFunction.h"
4#include "Library/LiveActor/ActorAreaFunction.h"
5#include "Library/LiveActor/ActorCollisionFunction.h"
6#include "Library/LiveActor/ActorInitUtil.h"
7#include "Library/LiveActor/ActorMovementFunction.h"
8#include "Library/LiveActor/ActorPoseUtil.h"
9#include "Library/LiveActor/ActorSensorUtil.h"
10#include "Library/Math/MathUtil.h"
11#include "Library/Nerve/NerveSetupUtil.h"
12#include "Library/Nerve/NerveUtil.h"
13
14#include "Util/SensorMsgFunction.h"
15
16namespace {
17NERVE_IMPL(MoonBasementSlideObj, Wait)
18NERVE_IMPL(MoonBasementSlideObj, Slide)
19
20NERVES_MAKE_NOSTRUCT(MoonBasementSlideObj, Wait, Slide)
21} // namespace
22
23MoonBasementSlideObj::MoonBasementSlideObj(const char* name) : al::LiveActor(name) {}
24
25void MoonBasementSlideObj::init(const al::ActorInitInfo& info) {
26 al::initActor(actor: this, initInfo: info);
27 al::initNerve(actor: this, nerve: &Wait, maxStates: 0);
28 makeActorAlive();
29}
30
31bool MoonBasementSlideObj::receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
32 al::HitSensor* self) {
33 if (rs::isMsgKoopaHackPunchCollide(message)) {
34 mPunchHits++;
35
36 sead::Vector3f sideDir = sead::Vector3f(0, 0, 0);
37 sead::Vector3f frontDir = sead::Vector3f(0, 0, 0);
38
39 al::calcSideDir(side: &sideDir, actor: this);
40 al::calcFrontDir(front: &frontDir, actor: this);
41
42 sead::Vector3f dir = sead::Vector3f(0, 0, 0);
43
44 al::calcDirBetweenSensorsH(&dir, other, self);
45
46 sead::Vector3f sideComponent = sead::Vector3f(0, 0, 0);
47 sead::Vector3f frontComponent = sead::Vector3f(0, 0, 0);
48
49 al::parallelizeVec(&sideComponent, sideDir, dir);
50 al::parallelizeVec(&frontComponent, frontDir, dir);
51
52 dir.set(sideComponent.length() < frontComponent.length() ? frontComponent : sideComponent);
53
54 al::tryNormalizeOrZero(out: &dir);
55
56 al::addVelocity(actor: this, vel: dir * 45.0f);
57 al::startHitReaction(actor: this, name: "命中");
58 al::setNerve(user: this, nerve: &Slide);
59
60 return true;
61 }
62 return false;
63}
64
65void MoonBasementSlideObj::exeWait() {
66 if (al::isFirstStep(user: this))
67 al::startAction(actor: this, actionName: "Wait");
68
69 al::addVelocityToGravity(actor: this, force: 2.0f);
70 al::scaleVelocityHV(actor: this, factorH: 0.95f, factorV: 0.99f);
71 al::limitVelocityDir(actor: this, dir: al::getGravity(actor: this), limit: 5.0f);
72}
73
74void MoonBasementSlideObj::exeSlide() {
75 al::addVelocityToGravity(actor: this, force: 2.0f);
76 al::scaleVelocityHV(actor: this, factorH: 0.95f, factorV: 0.99f);
77
78 if (al::isOnGround(this, 0))
79 al::limitVelocityDir(actor: this, dir: al::getGravity(actor: this), limit: 5.0f);
80
81 if (al::isVelocitySlowH(actor: this, threshold: 0.2f)) {
82 sead::Vector3f* velocityPtr = al::getVelocityPtr(actor: this);
83 al::parallelizeVec(velocityPtr, al::getGravity(actor: this), *velocityPtr);
84
85 al::startHitReaction(actor: this, name: "停止");
86 al::setNerve(user: this, nerve: &Wait);
87 } else if (al::isInDeathArea(actor: this))
88 kill();
89}
90