Compare commits

...

7 commits

Author SHA1 Message Date
guymakinggames 8fd8cc1980
Merge 92e33f95bb into b30105638f 2026-04-23 10:50:13 +02:00
Narr the Reg b30105638f
all: Fix headers (#1091)
Some checks are pending
Compile and verify functions / compile_verify (push) Waiting to run
Copy headers to separate repo / copy_headers (push) Waiting to run
decomp-dev / publish_progress_decomp_dev (1.0) (push) Waiting to run
lint / clang-format (push) Waiting to run
lint / custom-lint (push) Waiting to run
Check and verify that setup works on NixOS / nixos_verify (push) Waiting to run
progress / publish_progress (push) Waiting to run
testcompile / test_compile (push) Waiting to run
Trigger full-sync on the tracker repo on push / api-trigger-workflow (push) Waiting to run
2026-04-23 10:42:13 +02:00
guymakinggames 0f550e5aae
MapObj: Implement RocketFlower (#1024)
Some checks are pending
Compile and verify functions / compile_verify (push) Waiting to run
Copy headers to separate repo / copy_headers (push) Waiting to run
decomp-dev / publish_progress_decomp_dev (1.0) (push) Waiting to run
lint / clang-format (push) Waiting to run
lint / custom-lint (push) Waiting to run
Check and verify that setup works on NixOS / nixos_verify (push) Waiting to run
progress / publish_progress (push) Waiting to run
testcompile / test_compile (push) Waiting to run
Trigger full-sync on the tracker repo on push / api-trigger-workflow (push) Waiting to run
2026-04-23 00:55:05 +02:00
guymakinggames 129691c069
MapObj: Implement MoonBasementFloor (#1022) 2026-04-23 00:02:29 +02:00
guymakinggames 9090655294
MapObj: Implement BossKnuckleFix (#1021) 2026-04-22 23:27:25 +02:00
MonsterDruide1 572c2d6736
Library/Sequence: Fix vtable of Sequence (#1087) 2026-04-22 22:45:21 +02:00
guymakinggames 92e33f95bb MapObj: Implement MeganePartsState 2026-04-22 06:19:00 +01:00
18 changed files with 880 additions and 82 deletions

View file

@ -59551,45 +59551,45 @@ MapObj/BossKnuckleFix.o:
- offset: 0x222ee4
size: 128
label: _ZN14BossKnuckleFixC2EPKc
status: NotDecompiled
status: Matching
- offset: 0x222f64
size: 140
label: _ZN14BossKnuckleFixC1EPKc
status: NotDecompiled
status: Matching
- offset: 0x222ff0
size: 336
label: _ZN14BossKnuckleFix4initERKN2al13ActorInitInfoE
status: NotDecompiled
status: Matching
- offset: 0x223140
size: 208
label: _ZN14BossKnuckleFix10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_
status: NotDecompiled
status: Matching
- offset: 0x223210
size: 60
label: _ZN14BossKnuckleFix7exeWaitEv
status: NotDecompiled
status: Matching
- offset: 0x22324c
size: 88
label: _ZN14BossKnuckleFix11exeReactionEv
status: NotDecompiled
status: Matching
- offset: 0x2232a4
size: 104
label: _ZN14BossKnuckleFix16exeReactionLargeEv
status: NotDecompiled
status: Matching
- offset: 0x22330c
size: 64
label: _ZNK12_GLOBAL__N_121BossKnuckleFixNrvWait7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x22334c
size: 108
label: _ZNK12_GLOBAL__N_130BossKnuckleFixNrvReactionLarge7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2233b8
size: 92
label: _ZNK12_GLOBAL__N_125BossKnuckleFixNrvReaction7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
MapObj/BreakablePole.o:
'.text':
@ -75869,59 +75869,59 @@ MapObj/MeganePartsState.o:
label:
- _ZN16MeganePartsStateC1EPN2al9LiveActorE
- _ZN16MeganePartsStateC2EPN2al9LiveActorE
status: NotDecompiled
status: Matching
- offset: 0x2bcf00
size: 60
label: _ZN16MeganePartsState6appearEv
status: NotDecompiled
status: Matching
- offset: 0x2bcf3c
size: 156
label: _ZN16MeganePartsState6updateEv
status: NotDecompiled
status: Matching
- offset: 0x2bcfd8
size: 84
label: _ZN16MeganePartsState7exeHideEv
status: NotDecompiled
status: Matching
- offset: 0x2bd02c
size: 288
label: _ZN16MeganePartsState5exeOnEv
status: NotDecompiled
status: Matching
- offset: 0x2bd14c
size: 172
label: _ZN16MeganePartsState11updateAlphaEv
status: NotDecompiled
status: Matching
- offset: 0x2bd1f8
size: 68
label: _ZN16MeganePartsState7exeShowEv
status: NotDecompiled
status: Matching
- offset: 0x2bd23c
size: 268
label: _ZN16MeganePartsState6exeOffEv
status: NotDecompiled
status: Matching
- offset: 0x2bd348
size: 36
label: _ZN16MeganePartsStateD0Ev
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x2bd36c
size: 88
label: _ZNK12_GLOBAL__N_123MeganePartsStateNrvHide7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2bd3c4
size: 8
label: _ZNK12_GLOBAL__N_121MeganePartsStateNrvOn7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2bd3cc
size: 8
label: _ZNK12_GLOBAL__N_122MeganePartsStateNrvOff7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2bd3d4
size: 68
label: _ZNK12_GLOBAL__N_123MeganePartsStateNrvShow7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
MapObj/Mirror.o:
'.text':
@ -76398,101 +76398,101 @@ MapObj/MoonBasementFloor.o:
- offset: 0x2c17dc
size: 128
label: _ZN17MoonBasementFloorC2EPKc
status: NotDecompiled
status: Matching
- offset: 0x2c185c
size: 140
label: _ZN17MoonBasementFloorC1EPKc
status: NotDecompiled
status: Matching
- offset: 0x2c18e8
size: 216
label: _ZN17MoonBasementFloor4initERKN2al13ActorInitInfoE
status: NotDecompiled
status: Matching
- offset: 0x2c19c0
size: 132
label: _ZN17MoonBasementFloor17startFallBySwitchEv
status: NotDecompiled
status: Matching
- offset: 0x2c1a44
size: 52
label: _ZN17MoonBasementFloor8movementEv
status: NotDecompiled
status: Matching
- offset: 0x2c1a78
size: 148
label: _ZN17MoonBasementFloor10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_
status: NotDecompiled
status: Matching
- offset: 0x2c1b0c
size: 60
label: _ZN17MoonBasementFloor7exeWaitEv
status: NotDecompiled
status: Matching
- offset: 0x2c1b48
size: 140
label: _ZN17MoonBasementFloor16exeFallSignStartEv
status: NotDecompiled
status: Matching
- offset: 0x2c1bd4
size: 68
label: _ZN17MoonBasementFloor11exeFallSignEv
status: NotDecompiled
status: Matching
- offset: 0x2c1c18
size: 84
label: _ZN17MoonBasementFloor19exeFallSignBySwitchEv
status: NotDecompiled
status: Matching
- offset: 0x2c1c6c
size: 220
label: _ZN17MoonBasementFloor7exeFallEv
status: NotDecompiled
status: Matching
- offset: 0x2c1d48
size: 64
label: _ZNK12_GLOBAL__N_124MoonBasementFloorNrvWait7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2c1d88
size: 8
label: _ZNK12_GLOBAL__N_133MoonBasementFloorNrvFallSignStart7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2c1d90
size: 8
label: _ZNK12_GLOBAL__N_141MoonBasementFloorNrvFallSignStartByMeteor7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2c1d98
size: 8
label: _ZNK12_GLOBAL__N_141MoonBasementFloorNrvFallSignStartBySwitch7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2c1da0
size: 88
label: _ZNK12_GLOBAL__N_136MoonBasementFloorNrvFallSignBySwitch7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2c1df8
size: 8
label: _ZNK12_GLOBAL__N_132MoonBasementFloorNrvFallByMeteor7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2c1e00
size: 72
label: _ZNK12_GLOBAL__N_128MoonBasementFloorNrvFallSign7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2c1e48
size: 8
label: _ZNK12_GLOBAL__N_124MoonBasementFloorNrvFall7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2c1e50
size: 28
label: _ZNK2al10FunctorV0MIP17MoonBasementFloorMS1_FvvEEclEv
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x2c1e6c
size: 76
label: _ZNK2al10FunctorV0MIP17MoonBasementFloorMS1_FvvEE5cloneEv
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x2c1eb8
size: 4
label: _ZN2al10FunctorV0MIP17MoonBasementFloorMS1_FvvEED0Ev
status: NotDecompiled
status: Matching
lazy: true
MapObj/MoonBasementGate.o:
'.text':
@ -82302,103 +82302,103 @@ MapObj/RocketFlower.o:
- offset: 0x2fd628
size: 128
label: _ZN12RocketFlowerC2EPKc
status: NotDecompiled
status: Matching
- offset: 0x2fd6a8
size: 140
label: _ZN12RocketFlowerC1EPKc
status: NotDecompiled
status: Matching
- offset: 0x2fd734
size: 268
label: _ZN12RocketFlower4initERKN2al13ActorInitInfoE
status: NotDecompiled
status: Matching
- offset: 0x2fd840
size: 28
label: _ZN12RocketFlower18initAfterPlacementEv
status: NotDecompiled
status: Matching
- offset: 0x2fd85c
size: 156
label: _ZN12RocketFlower12attackSensorEPN2al9HitSensorES2_
status: NotDecompiled
status: Matching
- offset: 0x2fd8f8
size: 84
label: _ZNK12RocketFlower13isEnableEquipEv
status: NotDecompiled
status: Matching
- offset: 0x2fd94c
size: 664
label: _ZN12RocketFlower10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_
status: NotDecompiled
status: Matching
- offset: 0x2fdbe4
size: 116
label: _ZN12RocketFlower15terminateFollowEv
status: NotDecompiled
status: Matching
- offset: 0x2fdc58
size: 76
label: _ZN12RocketFlower7exeWaitEv
status: NotDecompiled
status: Matching
- offset: 0x2fdca4
size: 100
label: _ZN12RocketFlower13exeWaitFollowEv
status: NotDecompiled
status: Matching
- offset: 0x2fdd08
size: 412
label: _ZN12RocketFlower19trySyncFlyingCapPosEv
status: NotDecompiled
status: Matching
- offset: 0x2fdea4
size: 324
label: _ZN12RocketFlower9exeFollowEv
status: NotDecompiled
status: Matching
- offset: 0x2fdfe8
size: 108
label: _ZN12RocketFlower15appearFlowerSubEv
status: NotDecompiled
status: Matching
- offset: 0x2fe054
size: 164
label: _ZN12RocketFlower13exeWaitAttachEv
status: NotDecompiled
status: Matching
- offset: 0x2fe0f8
size: 60
label: _ZN12RocketFlower9exeAttachEv
status: NotDecompiled
status: Matching
- offset: 0x2fe134
size: 48
label: _ZN12RocketFlower19setFollowFlowerPoseERKN4sead4QuatIfEERKNS0_7Vector3IfEE
status: NotDecompiled
status: Matching
- offset: 0x2fe164
size: 16
label: _ZN12RocketFlower9disappearEv
status: NotDecompiled
status: Matching
- offset: 0x2fe174
size: 124
label: _ZN12RocketFlower14disappearForceEv
status: NotDecompiled
status: Matching
- offset: 0x2fe1f0
size: 104
label: _ZN12RocketFlower7controlEv
status: NotDecompiled
status: Matching
- offset: 0x2fe258
size: 80
label: _ZNK12_GLOBAL__N_119RocketFlowerNrvWait7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2fe2a8
size: 64
label: _ZNK12_GLOBAL__N_121RocketFlowerNrvAttach7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2fe2e8
size: 104
label: _ZNK12_GLOBAL__N_125RocketFlowerNrvWaitFollow7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2fe350
size: 8
label: _ZNK12_GLOBAL__N_121RocketFlowerNrvFollow7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2fe358
size: 8
label: _ZNK12_GLOBAL__N_125RocketFlowerNrvWaitAttach7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
MapObj/RocketFlowerEquipWatcher.o:
'.text':
@ -133676,7 +133676,7 @@ Scene/ProjectActorFactory.o:
- offset: 0x4b66dc
size: 52
label: _ZN2al19createActorFunctionI14BossKnuckleFixEEPNS_9LiveActorEPKc
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x4b6710
size: 52
@ -134846,7 +134846,7 @@ Scene/ProjectActorFactory.o:
- offset: 0x4b99d4
size: 52
label: _ZN2al19createActorFunctionI17MoonBasementFloorEEPNS_9LiveActorEPKc
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x4b9a08
size: 52
@ -135906,7 +135906,7 @@ Scene/ProjectActorFactory.o:
- offset: 0x4bd180
size: 52
label: _ZN2al19createActorFunctionI12RocketFlowerEEPNS_9LiveActorEPKc
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x4bd1b4
size: 52

View file

@ -3,6 +3,8 @@
#include <math/seadVector.h>
#include <prim/seadDelegate.h>
#include "Library/HostIO/HioNode.h"
namespace al {
class CollisionParts;
struct HitInfo;
@ -14,7 +16,7 @@ class ArrowHitResultBuffer;
class DiskHitResultBuffer;
class CollisionCheckInfoBase;
class ICollisionPartsKeeper {
class ICollisionPartsKeeper : public IUseHioNode {
public:
virtual void endInit() = 0;
virtual void addCollisionParts(CollisionParts* parts) = 0;

View file

@ -2,6 +2,8 @@
#include <basis/seadTypes.h>
#include "Library/HostIO/HioNode.h"
namespace al {
struct ExecuteOrder;
struct ExecuteSystemInitInfo;
@ -16,7 +18,7 @@ class IUseExecutor;
class LayoutActor;
class LiveActor;
class ExecuteTableHolderDraw {
class ExecuteTableHolderDraw : public HioNode {
public:
ExecuteTableHolderDraw();
virtual ~ExecuteTableHolderDraw();

View file

@ -2,6 +2,8 @@
#include <container/seadPtrArray.h>
#include "Library/HostIO/HioNode.h"
namespace al {
class ExecuteDirector;
struct ExecuteOrder;
@ -17,7 +19,7 @@ class IUseExecutor;
class LayoutActor;
class LiveActor;
class ExecuteTableHolderUpdate {
class ExecuteTableHolderUpdate : public HioNode {
public:
ExecuteTableHolderUpdate();
virtual ~ExecuteTableHolderUpdate();

View file

@ -3,13 +3,14 @@
#include <math/seadQuat.h>
#include "Library/Fluid/IUseFluidSurface.h"
#include "Library/HostIO/HioNode.h"
namespace al {
class LiveActor;
struct ActorInitInfo;
// TODO: Finish this
class RippleCtrl : public IUseFluidSurface {
class RippleCtrl : public IUseFluidSurface, public HioNode {
public:
RippleCtrl(LiveActor* parent);

View file

@ -15,7 +15,7 @@ namespace al {
class SceneCameraInfo;
class ScreenCapture;
class ScreenCaptureExecutor : public IUseHioNode {
class ScreenCaptureExecutor : public HioNode {
public:
ScreenCaptureExecutor(s32);
~ScreenCaptureExecutor();

View file

@ -26,6 +26,8 @@ public:
virtual void drawMain() const;
virtual void drawSub() const;
AudioKeeper* getAudioKeeper() const override { return mAudioKeeper; }
virtual bool isDisposable() const;
virtual Scene* getCurrentScene() const { return nullptr; }
@ -34,8 +36,6 @@ public:
void setSceneCreator(SceneCreator* sceneCreator) override { mSceneCreator = sceneCreator; }
AudioKeeper* getAudioKeeper() const override { return mAudioKeeper; }
void initAudio(const GameSystemInfo&, const char*, s32, s32, s32, const char*);
void initAudioKeeper(const char*);
void initDrawSystemInfo(const SequenceInitInfo&);

View file

@ -0,0 +1,48 @@
#pragma once
#include <basis/seadTypes.h>
#include <math/seadQuat.h>
#include <math/seadVector.h>
#include "Library/Scene/ISceneObj.h"
#include "Scene/SceneObjFactory.h"
namespace al {
class LiveActor;
}
class KoopaHackStopCtrl : public al::ISceneObj {
public:
static constexpr s32 sSceneObjId = SceneObjID_KoopaStopHackCtrl;
KoopaHackStopCtrl();
const char* getSceneObjName() const override { return "崩落クッパの停止制御"; }
void startStop(const al::LiveActor* actor);
void endStop(const al::LiveActor* actor);
void resetPosture(const al::LiveActor* actor, const sead::Quatf& quat,
const sead::Vector3f& trans);
bool tryResetPosture(al::LiveActor* actor);
private:
const al::LiveActor* mStopActor = nullptr;
bool mIsNeedResetPosture = false;
sead::Quatf mResetQuat = sead::Quatf::unit;
sead::Vector3f mResetTrans = sead::Vector3f::zero;
bool mIsStatusDemoForSceneKoopaHack = false;
};
static_assert(sizeof(KoopaHackStopCtrl) == 0x38, "KoopaHackStopCtrl");
namespace KoopaHackFunction {
void startStopKoopaHack(al::LiveActor* actor);
void endStopKoopaHack(al::LiveActor* actor);
void resetPostureKoopaHack(al::LiveActor* actor, const sead::Quatf& quat,
const sead::Vector3f& trans);
bool isStopKoopaHack(const al::LiveActor* actor);
bool isStatusDemoForSceneKoopaHack(const al::LiveActor* actor);
void setStatusDemoForSceneKoopaHack(const al::LiveActor* actor);
void resetStatusDemoForSceneKoopaHack(const al::LiveActor* actor);
} // namespace KoopaHackFunction

View file

@ -0,0 +1,89 @@
#include "MapObj/BossKnuckleFix.h"
#include <math/seadVector.h>
#include "Library/LiveActor/ActorActionFunction.h"
#include "Library/LiveActor/ActorAnimFunction.h"
#include "Library/LiveActor/ActorCollisionFunction.h"
#include "Library/LiveActor/ActorInitUtil.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/ActorResourceFunction.h"
#include "Library/LiveActor/ActorSensorUtil.h"
#include "Library/LiveActor/LiveActorFunction.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "Library/Obj/CollisionObj.h"
#include "Library/Stage/StageSwitchUtil.h"
#include "Util/SensorMsgFunction.h"
namespace {
NERVE_IMPL(BossKnuckleFix, Wait);
NERVE_IMPL(BossKnuckleFix, ReactionLarge);
NERVE_IMPL(BossKnuckleFix, Reaction);
NERVES_MAKE_STRUCT(BossKnuckleFix, Wait, ReactionLarge, Reaction);
} // namespace
BossKnuckleFix::BossKnuckleFix(const char* name) : al::LiveActor(name) {}
void BossKnuckleFix::init(const al::ActorInitInfo& info) {
al::initActorWithArchiveName(this, info, "BossKnuckleBody", "Fix");
al::initNerve(this, &NrvBossKnuckleFix.Wait, 0);
// NOTE: color of embedded grand shine is hardcoded to 5 (Sand)
al::startMclAnimAndSetFrameAndStop(al::getSubActor(this, "グランドシャイン"), "Color", 5.0f);
al::trySyncStageSwitchKill(this);
makeActorAlive();
mCollisionObj = new al::CollisionObj(info, al::getModelResource(this), "MoveLimit",
al::getHitSensor(this, "Body"), nullptr, nullptr);
al::setCollisionPartsSpecialPurposeName(mCollisionObj, "MoveLimit");
al::setTrans(mCollisionObj, al::getTrans(this));
al::setRotate(mCollisionObj, {0.0f, 90.0f, 0.0f});
mCollisionObj->makeActorAlive();
}
bool BossKnuckleFix::receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) {
if (rs::isMsgPlayerDisregardHomingAttack(message))
return true;
if (al::isNerve(this, &NrvBossKnuckleFix.Wait) &&
(rs::isMsgSphinxRideAttackTouch(message) || rs::isMsgPlayerAndCapHipDropAll(message))) {
rs::requestHitReactionToAttacker(message, self, other);
mReactionCount++;
if (mReactionCount >= 3) {
mReactionCount = 0;
al::setNerve(this, &NrvBossKnuckleFix.ReactionLarge);
} else
al::setNerve(this, &NrvBossKnuckleFix.Reaction);
return !rs::isMsgPlayerAndCapHipDropAll(message);
}
return false;
}
void BossKnuckleFix::exeWait() {
if (al::isFirstStep(this))
al::startAction(this, "MapWait");
}
void BossKnuckleFix::exeReaction() {
if (al::isFirstStep(this))
al::startAction(this, "MapReaction");
if (al::isActionEnd(this))
al::setNerve(this, &NrvBossKnuckleFix.Wait);
}
void BossKnuckleFix::exeReactionLarge() {
if (al::isFirstStep(this)) {
al::startAction(this, "MapReactionLarge");
al::tryOnStageSwitch(this, "ReactionOn");
}
if (al::isActionEnd(this))
al::setNerve(this, &NrvBossKnuckleFix.Wait);
}

View file

@ -0,0 +1,31 @@
#pragma once
#include <basis/seadTypes.h>
#include "Library/LiveActor/LiveActor.h"
namespace al {
struct ActorInitInfo;
class CollisionObj;
class HitSensor;
class SensorMsg;
} // namespace al
class BossKnuckleFix : public al::LiveActor {
public:
BossKnuckleFix(const char* name);
void init(const al::ActorInitInfo& info) override;
bool receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) override;
void exeWait();
void exeReaction();
void exeReactionLarge();
private:
al::CollisionObj* mCollisionObj = nullptr;
s32 mReactionCount = 0;
};
static_assert(sizeof(BossKnuckleFix) == 0x118);

View file

@ -0,0 +1,91 @@
#include "MapObj/MeganePartsState.h"
#include "Library/LiveActor/ActorModelFunction.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/LiveActorFunction.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "Util/PlayerUtil.h"
namespace {
NERVE_IMPL(MeganePartsState, Hide);
NERVE_IMPL(MeganePartsState, On);
NERVE_IMPL(MeganePartsState, Off);
NERVE_IMPL(MeganePartsState, Show);
NERVES_MAKE_STRUCT(MeganePartsState, Hide, On, Off, Show);
} // namespace
MeganePartsState::MeganePartsState(al::LiveActor* actor)
: al::ActorStateBase("メガネーパーツ状態", actor) {
initNerve(&NrvMeganePartsState.Hide, 0);
}
void MeganePartsState::appear() {
al::setMaterialProgrammable(mActor);
al::hideModelIfShow(mActor);
al::NerveStateBase::appear();
al::setNerve(this, &NrvMeganePartsState.Hide);
}
bool MeganePartsState::update() {
s32 subActorNum = al::getSubActorNum(mActor);
for (s32 i = 0; i < subActorNum; i++)
al::setTrans(al::getSubActor(mActor, i), al::getTrans(mActor));
al::setModelMaterialParameterF32(mActor, al::getMaterialName(mActor, 0), "const_single0",
mAlpha);
return al::NerveStateBase::update();
}
void MeganePartsState::exeHide() {
if (al::isFirstStep(this))
al::hideModelIfShow(mActor);
if (rs::isPlayerEnableToSeeOddSpace(mActor))
al::setNerve(this, &NrvMeganePartsState.On);
}
void MeganePartsState::exeOn() {
if (al::isFirstStep(this))
al::showModelIfHide(mActor);
mAlpha = sead::Mathf::min(mAlpha + (1.0f / 15.0f), 1.0f);
if (!rs::isPlayerEnableToSeeOddSpace(mActor)) {
al::setNerve(this, &NrvMeganePartsState.Off);
return;
}
updateAlpha();
if (mAlpha == 1.0f)
al::setNerve(this, &NrvMeganePartsState.Show);
}
void MeganePartsState::updateAlpha() {
if (!al::isExistSubActorKeeper(mActor))
return;
f32 alpha = sead::Mathf::clamp((mAlpha - (7.0f / 15.0f)) / (8.0f / 15.0f), 0.0f, 1.0f);
s32 subActorNum = al::getSubActorNum(mActor);
for (s32 i = 0; i < subActorNum; i++)
al::setModelAlphaMask(al::getSubActor(mActor, i), alpha);
}
void MeganePartsState::exeShow() {
if (!rs::isPlayerEnableToSeeOddSpace(mActor))
al::setNerve(this, &NrvMeganePartsState.Off);
}
void MeganePartsState::exeOff() {
mAlpha = sead::Mathf::clampMin(mAlpha - (1.0f / 15.0f), 0.0f);
if (rs::isPlayerEnableToSeeOddSpace(mActor)) {
al::setNerve(this, &NrvMeganePartsState.On);
return;
}
updateAlpha();
if (mAlpha == 0.0f)
al::setNerve(this, &NrvMeganePartsState.Hide);
}

View file

@ -0,0 +1,28 @@
#pragma once
#include <basis/seadTypes.h>
#include "Library/Nerve/NerveStateBase.h"
namespace al {
class LiveActor;
} // namespace al
class MeganePartsState : public al::ActorStateBase {
public:
MeganePartsState(al::LiveActor* actor);
void appear() override;
bool update() override;
void exeHide();
void exeOn();
void updateAlpha();
void exeShow();
void exeOff();
private:
f32 mAlpha = 0.0f;
};
static_assert(sizeof(MeganePartsState) == 0x28);

View file

@ -0,0 +1,165 @@
#include "MapObj/MoonBasementFloor.h"
#include "Library/LiveActor/ActorActionFunction.h"
#include "Library/LiveActor/ActorClippingFunction.h"
#include "Library/LiveActor/ActorFlagFunction.h"
#include "Library/LiveActor/ActorInitFunction.h"
#include "Library/LiveActor/ActorInitUtil.h"
#include "Library/LiveActor/ActorMovementFunction.h"
#include "Library/Math/MathUtil.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "Library/Placement/PlacementFunction.h"
#include "Library/Stage/StageSwitchUtil.h"
#include "Library/Thread/FunctorV0M.h"
#include "Boss/Koopa/KoopaHackStopCtrl.h"
#include "Util/SensorMsgFunction.h"
namespace {
NERVE_IMPL(MoonBasementFloor, Wait)
NERVE_IMPL(MoonBasementFloor, FallSignStart)
NERVE_IMPL_(MoonBasementFloor, FallSignStartByMeteor, FallSignStart)
NERVE_IMPL_(MoonBasementFloor, FallSignStartBySwitch, FallSignStart)
NERVE_IMPL(MoonBasementFloor, FallSignBySwitch)
NERVE_IMPL_(MoonBasementFloor, FallByMeteor, Fall)
NERVE_IMPL(MoonBasementFloor, FallSign)
NERVE_IMPL(MoonBasementFloor, Fall)
NERVES_MAKE_STRUCT(MoonBasementFloor, Wait, FallSignStart, FallSignStartByMeteor,
FallSignStartBySwitch, FallSignBySwitch, FallByMeteor, FallSign, Fall)
const f32 sFallGravity = 0.2f;
const f32 sFallScale = 0.95f;
const f32 sFallGravityByMeteor = 0.2f;
const f32 sFallScaleByMeteor = 0.95f;
struct MoonFallParams {
const f32* gravity;
const f32* scale;
};
const MoonFallParams sFallParams{&sFallGravity, &sFallScale};
const MoonFallParams sFallParamsByMeteor{&sFallGravityByMeteor, &sFallScaleByMeteor};
inline const MoonFallParams& getMoonFallParams(al::LiveActor* actor) {
return al::isNerve(actor, &NrvMoonBasementFloor.FallByMeteor) ? sFallParamsByMeteor :
sFallParams;
}
} // namespace
MoonBasementFloor::MoonBasementFloor(const char* name) : al::LiveActor(name) {}
void MoonBasementFloor::init(const al::ActorInitInfo& info) {
using MoonBasementFloorFunctor =
al::FunctorV0M<MoonBasementFloor*, void (MoonBasementFloor::*)()>;
al::initActorChangeModel(this, info);
al::initNerve(this, &NrvMoonBasementFloor.Wait, 0);
f32 rotate = sead::Mathf::floor(al::getRandom(0.0f, 3.99f));
al::addRotateAndRepeatY(this, rotate * 90.0);
if (al::listenStageSwitchOn(
this, "SwitchFallStart",
MoonBasementFloorFunctor(this, &MoonBasementFloor::startFallBySwitch))) {
al::tryGetArg(&mFallSignStepBySwitch, info, "FallSignStepBySwitch");
}
al::trySyncStageSwitchKill(this);
}
void MoonBasementFloor::startFallBySwitch() {
if (!al::isAlive(this))
return;
if (al::isNerve(this, &NrvMoonBasementFloor.Fall))
return;
if (al::isNerve(this, &NrvMoonBasementFloor.FallByMeteor))
return;
s32 fallSignStepBySwitch = mFallSignStepBySwitch;
al::invalidateClipping(this);
if (fallSignStepBySwitch == 0)
al::setNerve(this, &NrvMoonBasementFloor.FallSignStart);
else
al::setNerve(this, &NrvMoonBasementFloor.FallSignStartBySwitch);
}
void MoonBasementFloor::movement() {
if (!KoopaHackFunction::isStopKoopaHack(this))
al::LiveActor::movement();
}
bool MoonBasementFloor::receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) {
if (!al::isNerve(this, &NrvMoonBasementFloor.Wait))
return false;
if (rs::isMsgKoopaTouchFloor(message)) {
al::startHitReaction(this, "クッパ着地");
al::invalidateClipping(this);
al::setNerve(this, &NrvMoonBasementFloor.FallSignStart);
return true;
}
if (rs::isMsgMoonBasementAttackMeteor(message)) {
al::invalidateClipping(this);
al::setNerve(this, &NrvMoonBasementFloor.FallSignStartByMeteor);
return true;
}
return false;
}
void MoonBasementFloor::exeWait() {
if (al::isFirstStep(this))
al::startAction(this, "Wait");
}
void MoonBasementFloor::exeFallSignStart() {
if (al::isFirstStep(this))
al::startAction(this, "FallSignStart");
if (al::isActionEnd(this)) {
if (al::isNerve(this, &NrvMoonBasementFloor.FallSignStartBySwitch))
al::setNerve(this, &NrvMoonBasementFloor.FallSignBySwitch);
else if (al::isNerve(this, &NrvMoonBasementFloor.FallSignStartByMeteor))
al::setNerve(this, &NrvMoonBasementFloor.FallByMeteor);
else
al::setNerve(this, &NrvMoonBasementFloor.FallSign);
}
}
void MoonBasementFloor::exeFallSign() {
if (al::isFirstStep(this))
al::startAction(this, "FallSign");
al::setNerveAtActionEnd(this, &NrvMoonBasementFloor.Fall);
}
void MoonBasementFloor::exeFallSignBySwitch() {
if (al::isFirstStep(this))
al::startAction(this, "FallSignBySwitch");
s32 fallSignStep = mFallSignStepBySwitch;
if (fallSignStep < 0)
fallSignStep = 30;
al::setNerveAtGreaterEqualStep(this, &NrvMoonBasementFloor.Fall, fallSignStep);
}
void MoonBasementFloor::exeFall() {
if (al::isFirstStep(this))
al::startAction(this, "Fall");
al::addVelocityToGravity(this, *getMoonFallParams(this).gravity);
al::scaleVelocity(this, *getMoonFallParams(this).scale);
if (al::isGreaterEqualStep(this, 300)) {
al::startHitReaction(this, "消滅");
kill();
}
}

View file

@ -0,0 +1,34 @@
#pragma once
#include <basis/seadTypes.h>
#include "Library/LiveActor/LiveActor.h"
namespace al {
struct ActorInitInfo;
class HitSensor;
class SensorMsg;
} // namespace al
class MoonBasementFloor : public al::LiveActor {
public:
MoonBasementFloor(const char* name);
void init(const al::ActorInitInfo& info) override;
void movement() override;
bool receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) override;
void startFallBySwitch();
void exeWait();
void exeFallSignStart();
void exeFallSign();
void exeFallSignBySwitch();
void exeFall();
private:
s32 mFallSignStepBySwitch = -1;
};
static_assert(sizeof(MoonBasementFloor) == 0x110);

237
src/MapObj/RocketFlower.cpp Normal file
View file

@ -0,0 +1,237 @@
#include "MapObj/RocketFlower.h"
#include "Library/Collision/PartsConnectorUtil.h"
#include "Library/Effect/EffectSystemInfo.h"
#include "Library/LiveActor/ActorActionFunction.h"
#include "Library/LiveActor/ActorAnimFunction.h"
#include "Library/LiveActor/ActorClippingFunction.h"
#include "Library/LiveActor/ActorInitUtil.h"
#include "Library/LiveActor/ActorMovementFunction.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/ActorSensorUtil.h"
#include "Library/Math/MathUtil.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "MapObj/RocketFlowerFunction.h"
#include "Util/PlayerUtil.h"
#include "Util/SensorMsgFunction.h"
namespace {
NERVE_IMPL(RocketFlower, Wait);
NERVE_IMPL(RocketFlower, Attach);
NERVE_IMPL(RocketFlower, WaitFollow);
NERVE_IMPL(RocketFlower, Follow);
NERVE_IMPL(RocketFlower, WaitAttach);
NERVES_MAKE_STRUCT(RocketFlower, Wait, Attach, WaitFollow, Follow, WaitAttach);
} // namespace
RocketFlower::RocketFlower(const char* name) : al::LiveActor(name) {}
void RocketFlower::init(const al::ActorInitInfo& info) {
al::initActor(this, info);
al::initNerve(this, &NrvRocketFlower.Wait, 0);
makeActorAlive();
mMtxConnector = al::tryCreateMtxConnector(this, info);
mFlowerSub = new al::LiveActor("ロケットフラワーの花");
al::initChildActorWithArchiveNameNoPlacementInfo(mFlowerSub, info, "RocketFlowerDash", nullptr);
al::startAction(mFlowerSub, "Wait");
mFlowerSub->makeActorDead();
RocketFlowerFunction::createRocketFlowerEquipWatcherIfNotExist(this, info);
al::setHitSensorPosPtr(this, "Equip", al::getTransPtr(mFlowerSub));
al::startAction(this, "Wait");
}
void RocketFlower::initAfterPlacement() {
if (mMtxConnector)
al::attachMtxConnectorToCollision(mMtxConnector, this, false);
}
void RocketFlower::attackSensor(al::HitSensor* self, al::HitSensor* other) {
if (!al::isSensorName(self, "Equip"))
return;
if (isEnableEquip()) {
if (rs::sendMsgRocketFlowerExtension(other, self))
al::setNerve(this, &NrvRocketFlower.Attach);
}
}
bool RocketFlower::isEnableEquip() const {
if (al::isNerve(this, &NrvRocketFlower.Follow) && !al::isNewNerve(this))
return true;
return al::isNerve(this, &NrvRocketFlower.WaitAttach);
}
bool RocketFlower::receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) {
if (al::isMsgPlayerSpinAttack(message)) {
if (al::isNerve(this, &NrvRocketFlower.Wait)) {
al::invalidateClipping(this);
al::setNerve(this, &NrvRocketFlower.WaitFollow);
}
} else if (rs::isMsgCapItemGet(message)) {
if (al::isNerve(this, &NrvRocketFlower.Wait)) {
al::invalidateClipping(this);
al::setNerve(this, &NrvRocketFlower.Follow);
return true;
}
} else if (al::isMsgPlayerObjTouch(message) || rs::isMsgBlowObjAttack(message) ||
rs::isMsgFireDamageAll(message) || rs::isMsgHammerBrosHammerEnemyAttack(message) ||
rs::isMsgHammerBrosHammerHackAttack(message) || rs::isMsgHosuiAttack(message) ||
al::isMsgEnemyAttack(message) || al::isMsgKickStoneAttack(message) ||
rs::isMsgRadishAttack(message) || rs::isMsgSeedAttack(message) ||
rs::isMsgTankBullet(message) || rs::isMsgGamaneBulletThrough(message) ||
rs::isMsgHackAttackPoison(message) || rs::isMsgYoshiTongueAttack(message)) {
if (al::isSensorMapObj(self)) {
if (mReactionFrame == 0)
al::startAction(this, "Reaction");
mReactionFrame = 30;
}
} else if (rs::isMsgCapAttack(message)) {
if (al::isSensorMapObj(self) && !al::isNerve(this, &NrvRocketFlower.Wait) &&
!al::isNerve(this, &NrvRocketFlower.WaitFollow)) {
if (mReactionFrame == 0)
al::startAction(this, "Reaction");
mReactionFrame = 30;
}
} else if (al::isMsgPlayerPutOnEquipment(message) && al::isSensorName(self, "Equip") &&
isEnableEquip()) {
if (RocketFlowerFunction::requestEquipRocketFlower(this, other)) {
al::setNerve(this, &NrvRocketFlower.Attach);
return true;
}
terminateFollow();
}
return false;
}
void RocketFlower::terminateFollow() {
al::invalidateHitSensor(this, "Equip");
al::validateClipping(this);
mFlowerSub->kill();
al::startAction(this, "Appear");
mReactionFrame = 30;
al::startHitReaction(this, "復帰");
al::setNerve(this, &NrvRocketFlower.Wait);
}
void RocketFlower::exeWait() {
if (al::isFirstStep(this)) {
al::startVisAnim(this, "Show");
al::invalidateHitSensor(this, "Equip");
}
}
void RocketFlower::exeWaitFollow() {
if (trySyncFlyingCapPos()) {
al::setNerve(this, &NrvRocketFlower.Follow);
return;
}
if (al::isGreaterEqualStep(this, 30)) {
al::validateClipping(this);
al::setNerve(this, &NrvRocketFlower.Wait);
}
}
bool RocketFlower::trySyncFlyingCapPos() {
sead::Vector3f flyingCapPos;
if (!rs::tryGetFlyingCapPos(&flyingCapPos, this))
return false;
flyingCapPos += 50.0f * sead::Vector3f::ey;
al::resetPosition(mFlowerSub, flyingCapPos);
sead::Vector3f toPlayerHead = rs::getPlayerHeadPos(this) - flyingCapPos;
if (al::tryNormalizeOrZero(&toPlayerHead)) {
sead::Quatf quat;
quat.makeVectorRotation(sead::Vector3f::ez, toPlayerHead);
al::setQuat(mFlowerSub, quat);
}
return true;
}
void RocketFlower::exeFollow() {
if (al::isFirstStep(this)) {
appearFlowerSub();
mFollowLostFrame = 0;
}
if (trySyncFlyingCapPos()) {
mFollowLostFrame = 0;
return;
}
if (rs::isEquipCapCatched(this)) {
al::validateHitSensor(this, "Equip");
al::setNerve(this, &NrvRocketFlower.WaitAttach);
return;
}
if (mFollowLostFrame >= 16)
terminateFollow();
mFollowLostFrame++;
}
void RocketFlower::appearFlowerSub() {
al::startVisAnim(this, "Hide");
mFlowerSub->appear();
al::startAction(mFlowerSub, "Wait");
al::startAction(this, "ReactionCap");
mReactionFrame = 30;
al::startHitReaction(this, "花が取れた");
}
void RocketFlower::exeWaitAttach() {
rs::tryCalcPlayerModelHeadJointPos(al::getTransPtr(mFlowerSub), this);
if (al::isGreaterEqualStep(this, 20))
terminateFollow();
}
void RocketFlower::exeAttach() {
if (al::isFirstStep(this))
al::startAction(mFlowerSub, "Dash");
}
void RocketFlower::setFollowFlowerPose(const sead::Quatf& quat, const sead::Vector3f& trans) {
al::setQuat(mFlowerSub, quat);
al::resetPosition(mFlowerSub, trans);
}
void RocketFlower::disappear() {
al::startHitReaction(mFlowerSub, "消滅");
}
void RocketFlower::disappearForce() {
al::tryKillEmitterAndParticleAll(mFlowerSub);
al::invalidateHitSensor(this, "Equip");
al::validateClipping(this);
mFlowerSub->kill();
al::startAction(this, "Wait");
mReactionFrame = 30;
al::setNerve(this, &NrvRocketFlower.Wait);
}
void RocketFlower::control() {
if (al::isActionOneTime(this) && al::isActionEnd(this))
al::startAction(this, "Wait");
if (mReactionFrame != 0)
mReactionFrame--;
if (mMtxConnector)
al::connectPoseQT(this, mMtxConnector);
}

48
src/MapObj/RocketFlower.h Normal file
View file

@ -0,0 +1,48 @@
#pragma once
#include <math/seadQuat.h>
#include <math/seadVector.h>
#include "Library/LiveActor/LiveActor.h"
namespace al {
struct ActorInitInfo;
class HitSensor;
class MtxConnector;
class SensorMsg;
} // namespace al
class RocketFlower : public al::LiveActor {
public:
RocketFlower(const char* name);
void init(const al::ActorInitInfo& info) override;
void initAfterPlacement() override;
void attackSensor(al::HitSensor* self, al::HitSensor* other) override;
bool receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) override;
void control() override;
bool isEnableEquip() const;
void terminateFollow();
void exeWait();
void exeWaitFollow();
bool trySyncFlyingCapPos();
void exeFollow();
void appearFlowerSub();
void exeWaitAttach();
void exeAttach();
void setFollowFlowerPose(const sead::Quatf& quat, const sead::Vector3f& trans);
void disappear();
void disappearForce();
private:
al::MtxConnector* mMtxConnector = nullptr;
al::LiveActor* mFlowerSub = nullptr;
s32 mReactionFrame = 0;
u32 mFollowLostFrame = 0;
};
static_assert(sizeof(RocketFlower) == 0x120);

View file

@ -0,0 +1,17 @@
#pragma once
namespace al {
struct ActorInitInfo;
class HitSensor;
class LiveActor;
} // namespace al
class RocketFlower;
namespace RocketFlowerFunction {
void createRocketFlowerEquipWatcherIfNotExist(const al::LiveActor* actor,
const al::ActorInitInfo& info);
bool requestEquipRocketFlower(RocketFlower* flower, al::HitSensor* sensor);
} // namespace RocketFlowerFunction

View file

@ -69,6 +69,7 @@
#include "MapObj/AllDeadWatcherWithShine.h"
#include "MapObj/AnagramAlphabet.h"
#include "MapObj/BlockEmpty2D.h"
#include "MapObj/BossKnuckleFix.h"
#include "MapObj/CapBomb.h"
#include "MapObj/CapHanger.h"
#include "MapObj/CapSwitch.h"
@ -87,12 +88,14 @@
#include "MapObj/LavaPan.h"
#include "MapObj/MeganeMapParts.h"
#include "MapObj/MoonBasementBreakParts.h"
#include "MapObj/MoonBasementFloor.h"
#include "MapObj/MoonBasementSlideObj.h"
#include "MapObj/MoonWorldCaptureParadeLift.h"
#include "MapObj/PeachWorldTree.h"
#include "MapObj/PoleGrabCeil.h"
#include "MapObj/ReactionMapParts.h"
#include "MapObj/RiseMapPartsHolder.h"
#include "MapObj/RocketFlower.h"
#include "MapObj/RouletteSwitch.h"
#include "MapObj/SaveFlagCheckObj.h"
#include "MapObj/ShineTowerRocket.h"
@ -164,7 +167,7 @@ const al::NameToCreator<al::ActorCreatorFunction> sProjectActorFactoryEntries[]
{"BossForestWander", al::createActorFunction<BossForestWander>},
{"BossKnuckle", nullptr},
{"BossKnuckleCounterGround", nullptr},
{"BossKnuckleFix", nullptr},
{"BossKnuckleFix", al::createActorFunction<BossKnuckleFix>},
{"BossMagma", nullptr},
{"BossRaid", nullptr},
{"BossRaidNpc", nullptr},
@ -411,7 +414,7 @@ const al::NameToCreator<al::ActorCreatorFunction> sProjectActorFactoryEntries[]
{"MoonBasementFallObj", nullptr},
{"MoonBasementFinalGate", nullptr},
{"MoonBasementFallObjDecoration", nullptr},
{"MoonBasementFloor", nullptr},
{"MoonBasementFloor", al::createActorFunction<MoonBasementFloor>},
{"MoonBasementGate", nullptr},
{"MoonBasementMeteorAreaObj", nullptr},
{"MoonBasementPillar", nullptr},
@ -670,7 +673,7 @@ const al::NameToCreator<al::ActorCreatorFunction> sProjectActorFactoryEntries[]
{"RiseMapParts", nullptr},
{"ReactionMapParts", al::createActorFunction<ReactionMapParts>},
{"RiseMapPartsHolder", al::createActorFunction<RiseMapPartsHolder>},
{"RocketFlower", nullptr},
{"RocketFlower", al::createActorFunction<RocketFlower>},
{"RollingCubeMapParts", al::createActorFunction<al::RollingCubeMapParts>},
{"RippleFixMapParts", nullptr},
{"RotateMapParts", al::createActorFunction<al::RotateMapParts>},