This commit is contained in:
GRAnimated 2026-04-23 03:03:23 +02:00 committed by GitHub
commit 93e1f38222
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 191 additions and 15 deletions

View file

@ -8237,40 +8237,40 @@ Boss/BossRaid/BossRaidNpc.o:
- offset: 0x0413d8
size: 128
label: _ZN11BossRaidNpcC2EPKc
status: NotDecompiled
status: Matching
- offset: 0x041458
size: 140
label: _ZN11BossRaidNpcC1EPKc
status: NotDecompiled
status: Matching
- offset: 0x0414e4
size: 672
label: _ZN11BossRaidNpc4initERKN2al13ActorInitInfoE
status: NotDecompiled
status: Matching
- offset: 0x041784
size: 164
label: _ZN11BossRaidNpc10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_
status: NotDecompiled
status: Matching
- offset: 0x041828
size: 68
label: _ZNK11BossRaidNpc16isEnableReactionEv
status: NotDecompiled
status: Matching
- offset: 0x04186c
size: 80
label: _ZN11BossRaidNpc8exeEventEv
status: NotDecompiled
status: Matching
- offset: 0x0418bc
size: 152
label: _ZN11BossRaidNpc11exeReactionEv
status: NotDecompiled
status: Matching
- offset: 0x041954
size: 80
label: _ZNK12_GLOBAL__N_119BossRaidNpcNrvEvent7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x0419a4
size: 8
label: _ZNK12_GLOBAL__N_122BossRaidNpcNrvReaction7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
Boss/BossRaid/BossRaidRivet.o:
'.text':
@ -133691,7 +133691,7 @@ Scene/ProjectActorFactory.o:
- offset: 0x4b6778
size: 52
label: _ZN2al19createActorFunctionI11BossRaidNpcEEPNS_9LiveActorEPKc
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x4b67ac
size: 52

View file

@ -0,0 +1,51 @@
#pragma once
#include <math/seadMatrix.h>
#include <math/seadVector.h>
namespace al {
class JointAimInfo {
public:
JointAimInfo();
void makeTurnQuat(sead::Quatf* quat, const sead::Vector3f& targetDir) const;
void makeTurnQuatCircle(sead::Quatf* quat, const sead::Vector3f& targetDir) const;
void makeTurnQuatOval(sead::Quatf* quat, const sead::Vector3f& targetDir) const;
void makeTurnQuatRect(sead::Quatf* quat, const sead::Vector3f& targetDir) const;
void setBaseAimLocalDir(const sead::Vector3f& aim);
void setBaseUpLocalDir(const sead::Vector3f& up);
void setBaseSideLocalDir(const sead::Vector3f& side);
void setBaseOffsetLocal(const sead::Vector3f& offset);
void setBaseMtxPtr(const sead::Matrix34f* mtxPtr);
void setTargetPos(const sead::Vector3f& pos);
void setPowerRate(f32 rate);
void setLimitDegreeCircle(f32 degree);
// TODO: rename params
void setLimitDegreeOval(f32 a, f32 b, f32 c, f32 d);
// TODO: rename params
void setLimitDegreeRect(f32 a, f32 b, f32 c, f32 d);
void setEnableBackAim(bool enable);
void addPowerRate(f32 rate);
void subPowerRate(f32 rate);
void setInterpoleRate(f32 rate);
private:
sead::Vector3f mTargetPos = sead::Vector3f::zero;
sead::Vector3f mBaseAimLocalDir = sead::Vector3f::ez;
sead::Vector3f mBaseSideLocalDir = sead::Vector3f::ex;
sead::Vector3f mBaseUpLocalDir = sead::Vector3f::ey;
sead::Vector3f mBaseOffsetLocal = sead::Vector3f::zero;
const sead::Matrix34f* mBaseMtxPtr = nullptr;
f32 mPowerRate = 1.0f;
f32 mInterpoleRate = 0.1f;
f32 _50 = 30.0f;
f32 _54 = 30.0f;
f32 _58 = 30.0f;
f32 _5c = 30.0f;
s32 _60 = 0;
bool mIsEnableBackAim = false;
};
static_assert(sizeof(JointAimInfo) == 0x68);
} // namespace al

View file

@ -0,0 +1,91 @@
#include "Boss/BossRaid/BossRaidNpc.h"
#include <math/seadVector.h>
#include "Library/Demo/DemoFunction.h"
#include "Library/Joint/JointAimInfo.h"
#include "Library/Joint/JointControllerKeeper.h"
#include "Library/LiveActor/ActorActionFunction.h"
#include "Library/LiveActor/ActorInitUtil.h"
#include "Library/LiveActor/ActorSensorUtil.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "Util/NpcEventFlowUtil.h"
#include "Util/PlayerUtil.h"
#include "Util/SensorMsgFunction.h"
namespace {
NERVE_IMPL(BossRaidNpc, Event);
NERVE_IMPL(BossRaidNpc, Reaction);
NERVES_MAKE_NOSTRUCT(BossRaidNpc, Event, Reaction);
} // namespace
BossRaidNpc::BossRaidNpc(const char* name) : al::LiveActor(name) {}
void BossRaidNpc::init(const al::ActorInitInfo& info) {
al::initActorWithArchiveName(this, info, "BossRaid", "Npc");
al::initNerve(this, &Event, 0);
mEventFlowExecutor = rs::initEventFlow(this, info, "BossRaid", "Talk");
if (rs::isDefinedEventCamera(mEventFlowExecutor, "Default"))
rs::initEventCameraObject(mEventFlowExecutor, info, "Default");
rs::startEventFlow(mEventFlowExecutor, "Init");
al::initJointControllerKeeper(this, 2);
mJointAimInfoL = new al::JointAimInfo();
mJointAimInfoL->setPowerRate(1.0f);
mJointAimInfoL->setInterpoleRate(0.1f);
mJointAimInfoL->setBaseAimLocalDir(sead::Vector3f::ex);
mJointAimInfoL->setBaseUpLocalDir(sead::Vector3f::ey);
mJointAimInfoL->setBaseSideLocalDir(sead::Vector3f::ez);
mJointAimInfoL->setLimitDegreeRect(43.0f, 43.0f, 25.0f, 20.0f);
mJointAimInfoL->setEnableBackAim(true);
al::initJointAimController(this, mJointAimInfoL, "EyeL");
mJointAimInfoR = new al::JointAimInfo();
mJointAimInfoR->setPowerRate(1.0f);
mJointAimInfoR->setInterpoleRate(0.1f);
mJointAimInfoR->setBaseAimLocalDir(-sead::Vector3f::ex);
mJointAimInfoR->setBaseUpLocalDir(-sead::Vector3f::ey);
mJointAimInfoR->setBaseSideLocalDir(-sead::Vector3f::ez);
mJointAimInfoR->setLimitDegreeRect(43.0f, 43.0f, 25.0f, 20.0f);
mJointAimInfoR->setEnableBackAim(true);
al::initJointAimController(this, mJointAimInfoR, "EyeR");
al::registActorToDemoInfo(this, info);
makeActorAlive();
}
bool BossRaidNpc::receiveMsg(const al::SensorMsg* msg, al::HitSensor* other, al::HitSensor* self) {
if (rs::isMsgPlayerDisregardTargetMarker(msg))
return true;
if (rs::isMsgNpcCapReactionAll(msg) && al::isSensorEnemyBody(self) && isEnableReaction()) {
rs::requestHitReactionToAttacker(msg, self, other);
al::setNerve(this, &Reaction);
return true;
}
return false;
}
bool BossRaidNpc::isEnableReaction() const {
if (al::isNerve(this, &Reaction))
return al::isGreaterEqualStep(this, 20);
return true;
}
void BossRaidNpc::exeEvent() {
rs::updateEventFlow(mEventFlowExecutor);
mJointAimInfoL->setTargetPos(rs::getPlayerBodyPos(this));
mJointAimInfoR->setTargetPos(rs::getPlayerBodyPos(this));
}
void BossRaidNpc::exeReaction() {
if (al::isFirstStep(this))
al::startAction(this, "Reaction");
mJointAimInfoL->setTargetPos(rs::getPlayerBodyPos(this));
mJointAimInfoR->setTargetPos(rs::getPlayerBodyPos(this));
if (al::isActionEnd(this)) {
al::startAction(this, "Wait");
al::setNerve(this, &Event);
}
}

View file

@ -0,0 +1,25 @@
#pragma once
#include "Library/LiveActor/LiveActor.h"
namespace al {
class EventFlowExecutor;
class JointAimInfo;
} // namespace al
class BossRaidNpc : public al::LiveActor {
public:
BossRaidNpc(const char* name);
void init(const al::ActorInitInfo& info) override;
bool receiveMsg(const al::SensorMsg* msg, al::HitSensor* other, al::HitSensor* self) override;
bool isEnableReaction() const;
void exeEvent();
void exeReaction();
private:
al::EventFlowExecutor* mEventFlowExecutor = nullptr;
al::JointAimInfo* mJointAimInfoL = nullptr;
al::JointAimInfo* mJointAimInfoR = nullptr;
};
static_assert(sizeof(BossRaidNpc) == 0x120);

View file

@ -36,6 +36,7 @@
#include "Boss/BarrierField.h"
#include "Boss/BossForest/BossForestWander.h"
#include "Boss/BossRaid/BossRaidNpc.h"
#include "Boss/Mofumofu/MofumofuScrap.h"
#include "Camera/ScenarioStartCamera.h"
#include "Enemy/Bubble.h"
@ -170,7 +171,7 @@ const al::NameToCreator<al::ActorCreatorFunction> sProjectActorFactoryEntries[]
{"BossKnuckleFix", al::createActorFunction<BossKnuckleFix>},
{"BossMagma", nullptr},
{"BossRaid", nullptr},
{"BossRaidNpc", nullptr},
{"BossRaidNpc", al::createActorFunction<BossRaidNpc>},
{"BossRaidRivet", nullptr},
{"BreakablePole", nullptr},
{"Breeda", nullptr},

View file

@ -16,12 +16,20 @@ al::EventFlowExecutor* initEventFlowSuffix(al::LiveActor*, const al::ActorInitIn
const char*, const char*);
void startEventFlow(al::EventFlowExecutor*, const char*);
bool updateEventFlow(al::EventFlowExecutor*);
bool isDefinedEventCamera(const al::EventFlowExecutor*, const char*);
void initEventCameraObject(al::EventFlowExecutor*, const al::ActorInitInfo&, const char*);
void initEventCameraObjectAfterKeepPose(al::EventFlowExecutor*, const al::ActorInitInfo&,
const char*);
void initEventMessageTagDataHolder(al::EventFlowExecutor*, const al::MessageTagDataHolder*);
void initEventCameraObject(al::EventFlowExecutor* flowExecutor, const al::ActorInitInfo& initInfo,
const char* name);
void initEventCameraObjectAfterKeepPose(al::EventFlowExecutor* flowExecutor,
const al::ActorInitInfo& initInfo, const char* name);
void setEventBalloonFilterOnlyMiniGame(const al::LiveActor*);
void resetEventBalloonFilter(const al::LiveActor*);
bool tryStartEventCutSceneDemo(al::LiveActor*);
void endEventCutSceneDemoOrTryEndEventCutSceneDemoBySkip(al::LiveActor*);
bool tryHideDemoPlayerIfRequested(al::LiveActor*, al::EventFlowExecutor*);
bool tryShowDemoPlayerIfRequested(al::LiveActor*, al::EventFlowExecutor*);
bool tryStartDemoPlayerActionIfRequested(al::LiveActor*, al::EventFlowExecutor*);
bool isPlayingTextPaneAnimEventTalkMessage(const al::LiveActor*);
bool isCloseNpcDemoEventTalkMessage(const al::LiveActor*);
void requestSwitchTalkNpcEventVolleyBall(al::LiveActor*, s32);
void skipEventDemo(al::EventFlowExecutor*);
} // namespace rs