MapObj: Implement CheckpointFlag (#968)

This commit is contained in:
egg guy 2026-03-22 19:52:07 -04:00 committed by GitHub
parent bd787b53c6
commit 39d080e3b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 551 additions and 23 deletions

View file

@ -64014,92 +64014,92 @@ MapObj/CheckpointFlag.o:
- offset: 0x2495b8
size: 188
label: _ZN14CheckpointFlagC2EPKc
status: NotDecompiled
status: Matching
- offset: 0x249674
size: 184
label: _ZN14CheckpointFlagC1EPKc
status: NotDecompiled
status: Matching
- offset: 0x24972c
size: 792
label: _ZN14CheckpointFlag4initERKN2al13ActorInitInfoE
status: NotDecompiled
status: Matching
- offset: 0x249a44
size: 4
label: _ZN14CheckpointFlag18initAfterPlacementEv
status: NotDecompiled
status: Matching
- offset: 0x249a48
size: 44
label: _ZN14CheckpointFlag7controlEv
status: NotDecompiled
status: Matching
- offset: 0x249a74
size: 108
label: _ZN14CheckpointFlag12attackSensorEPN2al9HitSensorES2_
status: NotDecompiled
status: Matching
- offset: 0x249ae0
size: 688
label: _ZN14CheckpointFlag10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_
status: NotDecompiled
status: Matching
- offset: 0x249d90
size: 8
label: _ZNK14CheckpointFlag20getPlayerRestartInfoEv
status: NotDecompiled
status: Matching
- offset: 0x249d98
size: 80
label: _ZN14CheckpointFlag8setAfterEv
status: NotDecompiled
status: Matching
- offset: 0x249de8
size: 16
label: _ZN14CheckpointFlag17startArriveByWarpEv
status: NotDecompiled
status: Matching
- offset: 0x249df8
size: 20
label: _ZN14CheckpointFlag12initHomeFlagERKN2al13ActorInitInfoE
status: NotDecompiled
status: Matching
- offset: 0x249e0c
size: 148
label: _ZN14CheckpointFlag9exeBeforeEv
status: NotDecompiled
status: Matching
- offset: 0x249ea0
size: 132
label: _ZN14CheckpointFlag6exeGetEv
status: NotDecompiled
status: Matching
- offset: 0x249f24
size: 124
label: _ZN14CheckpointFlag8exeAfterEv
status: NotDecompiled
status: Matching
- offset: 0x249fa0
size: 168
label: _ZN14CheckpointFlag8exeShakeEv
status: NotDecompiled
status: Matching
- offset: 0x24a048
size: 8
label: _ZNK14CheckpointFlag16getMessageSystemEv
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x24a050
size: 8
label: _ZThn264_NK14CheckpointFlag16getMessageSystemEv
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x24a058
size: 8
label: _ZNK12_GLOBAL__N_123CheckpointFlagNrvBefore7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x24a060
size: 128
label: _ZNK12_GLOBAL__N_122CheckpointFlagNrvAfter7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x24a0e0
size: 8
label: _ZNK12_GLOBAL__N_120CheckpointFlagNrvGet7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x24a0e8
size: 8
label: _ZNK12_GLOBAL__N_122CheckpointFlagNrvShake7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
MapObj/CheckpointFlagWatcher.o:
'.text':
@ -133918,7 +133918,7 @@ Scene/ProjectActorFactory.o:
- offset: 0x4b71f0
size: 52
label: _ZN2al19createActorFunctionI14CheckpointFlagEEPNS_9LiveActorEPKc
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x4b7224
size: 52

33
src/MapObj/AirBubble.h Normal file
View file

@ -0,0 +1,33 @@
#pragma once
#include "Library/LiveActor/LiveActor.h"
class AirBubble : public al::LiveActor {
public:
AirBubble(const char*, bool);
void init(const al::ActorInitInfo& info) override;
void endClipped() override;
void startClipped() override;
void appear() override;
void appearPopup();
void control() override;
bool receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) override;
void exeCreate();
void exeWait();
void exeReaction();
void exeMove();
void exeGot();
void getItem();
void exeCapGet();
void exeBreak();
private:
char _108[0x20];
};
static_assert(sizeof(AirBubble) == 0x128);

View file

@ -0,0 +1,255 @@
#include "MapObj/CheckpointFlag.h"
#include <basis/seadNew.h>
#include "Library/Layout/LayoutInitInfo.h"
#include "Library/LiveActor/ActorActionFunction.h"
#include "Library/LiveActor/ActorAnimFunction.h"
#include "Library/LiveActor/ActorFlagFunction.h"
#include "Library/LiveActor/ActorInitUtil.h"
#include "Library/LiveActor/ActorModelFunction.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/ActorSensorUtil.h"
#include "Library/Message/MessageHolder.h"
#include "Library/Nature/NatureUtil.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "Library/Placement/PlacementFunction.h"
#include "MapObj/AirBubble.h"
#include "MapObj/CheckpointFlagWatcher.h"
#include "MapObj/PlayerStartInfoHolder.h"
#include "Npc/BirdMtxGlideCtrl.h"
#include "System/GameDataFunction.h"
#include "Util/ItemUtil.h"
#include "Util/PlayerUtil.h"
#include "Util/SensorMsgFunction.h"
#include "Util/StageLayoutFunction.h"
namespace {
NERVE_IMPL(CheckpointFlag, Before);
NERVE_IMPL(CheckpointFlag, After);
NERVE_IMPL(CheckpointFlag, Get);
NERVE_IMPL(CheckpointFlag, Shake);
NERVES_MAKE_STRUCT(CheckpointFlag, Before, After, Get, Shake);
} // namespace
CheckpointFlag::CheckpointFlag(const char* name) : al::LiveActor(name) {}
const sead::Vector3f gBirdOffset = {75.0f, 0.0f, 0.0f};
const sead::Vector3f gAirBubbleOffset = {0.0f, 100.0f, 0.0f};
const sead::Vector3f gBalloonOffset = {0.0f, 75.0f, 0.0f};
void CheckpointFlag::init(const al::ActorInitInfo& info) {
al::initActorWithArchiveName(this, info, "CheckpointFlag", nullptr);
al::initNerve(this, &NrvCheckpointFlag.Before, 0);
rs::registerCheckpointFlagToWatcher(this);
mMessageSystem = al::getLayoutInitInfo(info).getMessageSystem();
mPlayerRestartInfo = al::createLinksPlayerActorInfo(this, info);
mPlacementId = al::createPlacementId(info);
al::tryGetArg(&mIsZeroGravity, info, "IsZeroGravity");
if (al::isInWater(this)) {
if (al::isInWaterPos(this, al::getSensorPos(this, "BodyTop"))) {
mAirBubble = new AirBubble("中間ポイントの空気泡", false);
al::initCreateActorNoPlacementInfo(mAirBubble, info);
}
}
if (mIsHome) {
rs::registerLinkedPlayerStartInfoToHolder(this, info, nullptr, nullptr, nullptr);
mFlagName = al::getSystemMessageString(this, "GlossaryObject", "Home");
setAfter();
makeActorAlive();
return;
}
f32 frame = rs::getStageShineAnimFrame(this);
if (frame < 0.0f)
frame = 0.0f;
al::startMclAnimAndSetFrameAndStop(this, "Color", frame);
al::StringTmp<128> messageLabel("");
rs::makeActorMessageLabel(&messageLabel, info, rs::getCheckpointLabelPrefix());
const char* stageName = rs::getPlacementStageName(this, info);
if (al::isExistLabelInStageMessage(this, stageName, messageLabel.cstr()))
mFlagName = al::getStageMessageString(this, stageName, messageLabel.cstr());
if (GameDataFunction::isGotCheckpoint(this, mPlacementId))
setAfter();
rs::registerLinkedPlayerStartInfoToHolder(this, info, nullptr, nullptr, nullptr);
GameDataFunction::registerCheckpointTrans(this, mPlacementId, al::getTrans(this));
mBirdMtxGlideCtrl = BirdMtxGlideCtrl::tryCreateAliveWaitByLinksBird(
al::getJointMtxPtr(this, "Pole2"), gBirdOffset, info, "Bird");
al::trySyncStageSwitchAppear(this);
}
void CheckpointFlag::initAfterPlacement() {}
void CheckpointFlag::control() {
mHitCooldown--;
if (mAirBubbleTimer > -1)
mAirBubbleTimer--;
if (mBirdMtxGlideCtrl)
mBirdMtxGlideCtrl->update();
}
void CheckpointFlag::attackSensor(al::HitSensor* self, al::HitSensor* other) {
if (al::isNerve(this, &NrvCheckpointFlag.After) && al::isSensorName(self, "Push"))
rs::sendMsgPushToPlayer(other, self) || al::sendMsgPush(other, self);
}
bool CheckpointFlag::receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) {
if (al::isNerve(this, &NrvCheckpointFlag.Get))
return false;
if (al::isMsgPlayerDisregard(message))
return !al::isSensorName(self, "BodyTop");
if (rs::isMsgPlayerDisregardTargetMarker(message))
return true;
if (mIsGot) {
if (rs::isMsgItemGet(message) || al::isMsgPlayerKick(message) ||
al::isMsgPlayerObjTouch(message) || rs::isMsgYoshiTongueAttack(message)) {
bool isGot = mIsGot;
AirBubble* airBubble = mAirBubble;
s32 hitCooldown = mHitCooldown;
mHitCooldown = 10;
if (hitCooldown > 0)
return false;
if (isGot)
rs::setTouchCheckpointFlagToWatcher(this);
if (airBubble && !al::isAlive(airBubble) && mAirBubbleTimer < 0) {
al::calcTransLocalOffset(al::getTransPtr(airBubble), this, gAirBubbleOffset);
airBubble->appear();
mAirBubbleTimer = 180;
}
al::setNerve(this, &NrvCheckpointFlag.Shake);
return al::isMsgPlayerObjTouch(message);
}
} else {
bool isAcquired = false;
if (rs::isMsgItemGet(message)) {
if (rs::isPlayerHack(this) || rs::isPlayerBinding(this))
isAcquired = true;
} else if (rs::isMsgCapReflect(message) || al::isMsgPlayerKick(message) ||
al::isMsgPlayerItemGet(message) || rs::isMsgYoshiTongueAttack(message))
isAcquired = true;
if (isAcquired) {
al::startHitReaction(this, "取得");
rs::setTouchCheckpointFlagToWatcher(this);
AirBubble* airBubble = mAirBubble;
if (airBubble && !al::isAlive(airBubble) && mAirBubbleTimer < 0) {
al::calcTransLocalOffset(al::getTransPtr(airBubble), this, gAirBubbleOffset);
airBubble->appear();
mAirBubbleTimer = 180;
}
GameDataFunction::recoveryPlayerMax(this);
rs::sendMsgAckCheckpoint(other, self);
al::setNerve(this, &NrvCheckpointFlag.Get);
return al::isMsgPlayerKick(message);
}
}
if (rs::isMsgCapReflect(message) || rs::isMsgHosuiAttack(message) ||
rs::isMsgHammerBrosHammerHackAttack(message) || al::isMsgPlayerFireBallAttack(message) ||
rs::isMsgTankBullet(message)) {
bool isGot = mIsGot;
AirBubble* airBubble = mAirBubble;
s32 hitCooldown = mHitCooldown;
mHitCooldown = 10;
if (hitCooldown > 0)
return false;
if (isGot)
rs::setTouchCheckpointFlagToWatcher(this);
if (airBubble && !al::isAlive(airBubble) && mAirBubbleTimer < 0) {
al::calcTransLocalOffset(al::getTransPtr(airBubble), this, gAirBubbleOffset);
airBubble->appear();
mAirBubbleTimer = 180;
}
al::setNerve(this, &NrvCheckpointFlag.Shake);
return al::isMsgPlayerObjTouch(message);
}
return false;
}
const al::PlacementInfo* CheckpointFlag::getPlayerRestartInfo() const {
return &al::getPlacementInfo(*mPlayerRestartInfo);
}
void CheckpointFlag::setAfter() {
bool isZeroGravity = mIsZeroGravity;
al::startAction(this, "After");
if (isZeroGravity)
al::setActionFrameRate(this, 0.2f);
al::setNerve(this, &NrvCheckpointFlag.After);
}
void CheckpointFlag::startArriveByWarp() {
if (mBirdMtxGlideCtrl)
mBirdMtxGlideCtrl->makeActorDeadBirdIfAlive();
}
void CheckpointFlag::initHomeFlag(const al::ActorInitInfo& info) {
mIsHome = true;
init(info);
}
void CheckpointFlag::exeBefore() {
if (al::isFirstStep(this)) {
bool isZeroGravity = mIsZeroGravity;
al::startAction(this, "Before");
if (isZeroGravity)
al::setActionFrameRate(this, 0.2f);
if (mBirdMtxGlideCtrl)
mBirdMtxGlideCtrl->validateGlide();
}
if (!mIsHome) {
if (mBirdMtxGlideCtrl && mBirdMtxGlideCtrl->isWaitBird())
rs::requestShowCheckpointFlagBalloon(this, gBalloonOffset);
else
rs::requestShowCheckpointFlagBalloon(this, sead::Vector3f::zero);
}
}
void CheckpointFlag::exeGet() {
if (al::isFirstStep(this)) {
bool isZeroGravity = mIsZeroGravity;
al::startAction(this, "Get");
if (isZeroGravity)
al::setActionFrameRate(this, 0.2f);
rs::requestShowCheckpointFlagNameLayout(this, mFlagName);
rs::requestHideCheckpointFlagBalloon(this);
if (mBirdMtxGlideCtrl)
mBirdMtxGlideCtrl->invalidateGlide();
mIsGot = true;
}
al::setNerveAtActionEnd(this, &NrvCheckpointFlag.After);
}
void CheckpointFlag::exeAfter() {
if (al::isFirstStep(this)) {
bool isZeroGravity = mIsZeroGravity;
mIsGot = true;
if (!al::isActionPlaying(this, "After")) {
al::startAction(this, "After");
if (isZeroGravity)
al::setActionFrameRate(this, 0.2f);
}
if (mBirdMtxGlideCtrl)
mBirdMtxGlideCtrl->validateGlide();
}
}
void CheckpointFlag::exeShake() {
if (al::isFirstStep(this)) {
bool isZeroGravity = mIsZeroGravity;
al::startAction(this, "Shake");
if (isZeroGravity)
al::setActionFrameRate(this, 0.2f);
if (mBirdMtxGlideCtrl)
mBirdMtxGlideCtrl->invalidateGlide();
if (mIsGot)
rs::requestShowCheckpointFlagNameLayout(this, mFlagName);
}
if (al::isActionEnd(this)) {
if (mIsGot)
al::setNerve(this, &NrvCheckpointFlag.After);
else
al::setNerve(this, &NrvCheckpointFlag.Before);
}
}

View file

@ -0,0 +1,50 @@
#pragma once
#include "Library/LiveActor/LiveActor.h"
#include "Library/Message/IUseMessageSystem.h"
namespace al {
class PlacementId;
class PlacementInfo;
} // namespace al
class AirBubble;
class BirdMtxGlideCtrl;
class CheckpointFlag : public al::LiveActor, public al::IUseMessageSystem {
public:
CheckpointFlag(const char* name);
void init(const al::ActorInitInfo& info) override;
void initAfterPlacement() override;
void control() override;
void attackSensor(al::HitSensor* self, al::HitSensor* other) override;
bool receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) override;
const al::PlacementInfo* getPlayerRestartInfo() const;
void setAfter();
void startArriveByWarp();
void initHomeFlag(const al::ActorInitInfo& info);
void exeBefore();
void exeGet();
void exeAfter();
void exeShake();
const al::MessageSystem* getMessageSystem() const override { return mMessageSystem; }
private:
al::MessageSystem* mMessageSystem = nullptr;
al::ActorInitInfo* mPlayerRestartInfo = nullptr;
al::PlacementId* mPlacementId = nullptr;
const char16* mFlagName = u"/////////////////";
s32 mHitCooldown = 0;
bool mIsGot = false;
bool mIsHome = false;
bool mIsZeroGravity = false;
AirBubble* mAirBubble = nullptr;
s32 mAirBubbleTimer = -1;
BirdMtxGlideCtrl* mBirdMtxGlideCtrl = nullptr;
};
static_assert(sizeof(CheckpointFlag) == 0x150);

View file

@ -0,0 +1,86 @@
#pragma once
#include <basis/seadTypes.h>
#include <math/seadVector.h>
#include "Library/Camera/IUseCamera.h"
#include "Library/Execute/IUseExecutor.h"
#include "Library/HostIO/HioNode.h"
#include "Library/LiveActor/LiveActorGroup.h"
#include "Library/Scene/ISceneObj.h"
#include "Scene/SceneObjFactory.h"
namespace al {
class LiveActor;
class PlacementInfo;
class Scene;
class SimpleLayoutAppearWaitEnd;
} // namespace al
class CheckpointFlag;
class CheckpointFlagWatcher : public al::HioNode,
public al::ISceneObj,
public al::IUseCamera,
public al::IUseExecutor {
public:
static constexpr s32 sSceneObjId = SceneObjID_CheckpointFlagWatcher;
CheckpointFlagWatcher(al::CameraDirector* director);
void initStageInfo(const char* stageName, s32 scenarioNum);
void initAfterPlacementSceneObj(const al::ActorInitInfo& info) override;
void execute() override;
void registerCheckpointFlag(CheckpointFlag* checkpoint);
void setTouchCheckpointFlag(CheckpointFlag* checkpoint);
void setTouchAfterCheckpointFlag(const char* checkpointName);
CheckpointFlag* findCheckpointFlag(const char* checkpointName) const;
CheckpointFlag* tryFindCheckpointFlag(const char* checkpointName) const;
bool tryFindCheckpointFlagTrans(sead::Vector3f* trans, const char* checkpointName) const;
void requestShowNameLayout(const char16*);
void requestCancelNameLayoutByShineGetDemo();
void requestShowBalloon(const CheckpointFlag*, const sead::Vector3f&);
void requestHideBalloon();
void hideBalloonAllAtBossSequence(const al::LiveActor*);
void showBalloonAllAfterBossSequence(const al::LiveActor*);
const char* getSceneObjName() const override { return "中間ポイント監視"; }
al::CameraDirector* getCameraDirector() const override { return mCameraDirector; }
private:
CheckpointFlag* mLastCheckpoint = nullptr;
al::DeriveActorGroup<CheckpointFlag>* mCheckpointTable;
char _28[0x8];
al::SimpleLayoutAppearWaitEnd* mNameLayout = nullptr;
bool mIsCancelNameLayout = false;
char _40[0x30];
const char* mStageName = nullptr;
s32 mScenarioNum = 1;
al::CameraDirector* mCameraDirector = nullptr;
al::LiveActor* _88 = nullptr;
};
static_assert(sizeof(CheckpointFlagWatcher) == 0x90);
namespace rs {
void registerCheckpointFlagToWatcher(CheckpointFlag*);
void setTouchCheckpointFlagToWatcher(CheckpointFlag*);
void setTouchAfterCheckpointFlagToWatcher(const al::IUseSceneObjHolder* sceneObjHolder,
const char* checkpointName);
const al::PlacementInfo*
tryFindCheckpointFlagPlayerRestartInfo(const al::IUseSceneObjHolder* sceneObjHolder,
const char* checkpointName);
CheckpointFlag* tryFindCheckpointFlag(const al::IUseSceneObjHolder* sceneObjHolder,
const char* checkpointName);
bool tryFindCheckpointFlagTrans(sead::Vector3f*, const al::IUseSceneObjHolder* sceneObjHolder,
const char* checkpointName);
void requestShowCheckpointFlagNameLayout(const CheckpointFlag* checkpoint, const char16* name);
void requestShowCheckpointFlagBalloon(const CheckpointFlag*, const sead::Vector3f&);
void requestHideCheckpointFlagBalloon(const CheckpointFlag*);
void requestCancelCheckpointFlagNameLayoutByShineGetDemo(const al::Scene*);
void hideCheckpointFlagBalloonAllAtBossSequence(const al::LiveActor*);
void showCheckpointFlagBalloonAllAfterBossSequence(const al::LiveActor*);
} // namespace rs

View file

@ -0,0 +1,67 @@
#pragma once
#include <basis/seadTypes.h>
#include <math/seadQuat.h>
#include <math/seadVector.h>
#include "Library/Camera/IUseCamera.h"
#include "Library/HostIO/HioNode.h"
#include "Library/Scene/ISceneObj.h"
namespace al {
struct ActorInitInfo;
class AreaObjGroup;
class CameraTicket;
class IUseSceneObjHolder;
class LiveActor;
class PlacementInfo;
class Scene;
} // namespace al
class PlayerStartInfo;
class PlayerStartObj;
class PlayerStartInfoHolder : public al::ISceneObj, public al::IUseCamera, public al::HioNode {
public:
PlayerStartInfoHolder();
void init(al::CameraDirector*, s32);
void registerPlayerStartInfo(const al::PlacementInfo*, const char*, al::CameraTicket*,
PlayerStartObj*, const sead::Vector3f*, const sead::Quatf*);
bool isRegistered(const al::PlacementInfo*, const char*) const;
void registerChangeStageAreaGroup(al::AreaObjGroup*, const al::ActorInitInfo&);
void registerWarpAreaGroup(al::AreaObjGroup*, const al::ActorInitInfo&);
void registerRestartAreaGroup(al::AreaObjGroup*);
PlayerStartInfo* tryFindInitInfoByStartId(const char*) const;
PlayerStartInfo* tryFindInitInfoByPlacementIdString(const char*) const;
const char* getSceneObjName() const override;
al::CameraDirector* getCameraDirector() const override;
private:
char _10[0x18];
};
static_assert(sizeof(PlayerStartInfoHolder) == 0x28);
namespace rs {
void registerLinkedPlayerStartInfoToHolder(const al::IUseSceneObjHolder*, const al::ActorInitInfo&,
const char*, const sead::Vector3f*, const sead::Quatf*);
void registerPlayerStartInfoToHolder(const al::IUseSceneObjHolder*, const al::PlacementInfo&,
const char*, PlayerStartObj*, const sead::Vector3f*,
const sead::Quatf*);
void registerPlayerStartInfoToHolder(const al::IUseSceneObjHolder*, const al::ActorInitInfo&,
const char*, PlayerStartObj*, const sead::Vector3f*,
const sead::Quatf*);
void registerPlayerStartInfoToHolderWithCamera(al::CameraTicket*, const al::IUseSceneObjHolder*,
const al::ActorInitInfo&, const char*,
PlayerStartObj*, const sead::Vector3f*,
const sead::Quatf*);
void registerPlayerStartInfoToHolderForTimeBalloon(const al::IUseSceneObjHolder*,
const al::ActorInitInfo&);
void registerPlayerStartInfoToHolderForCloset(const al::IUseSceneObjHolder*,
const al::ActorInitInfo&, const sead::Vector3f&,
const sead::Quatf&);
void tryStartEntranceCamera(const al::Scene*, const char*);
bool isPlayerStartCloset(const al::LiveActor*);
} // namespace rs

View file

@ -0,0 +1,36 @@
#pragma once
#include <math/seadMatrix.h>
#include <math/seadVector.h>
#include "Library/Nerve/NerveExecutor.h"
namespace al {
struct ActorInitInfo;
} // namespace al
class Bird;
class BirdMtxGlideCtrl : public al::NerveExecutor {
public:
static BirdMtxGlideCtrl* tryCreateAliveWaitByLinksBird(const sead::Matrix34f*,
const sead::Vector3f&,
const al::ActorInitInfo&, const char*);
BirdMtxGlideCtrl(Bird*);
void update();
void makeActorDeadBirdIfAlive();
void exeInvalid();
void exeValid();
void validateGlide();
void invalidateGlide();
bool isWaitBird() const;
private:
char _10[0x8];
};
static_assert(sizeof(BirdMtxGlideCtrl) == 0x18);

View file

@ -70,6 +70,7 @@
#include "MapObj/CapBomb.h"
#include "MapObj/CapHanger.h"
#include "MapObj/CapSwitch.h"
#include "MapObj/CheckpointFlag.h"
#include "MapObj/ChurchDoor.h"
#include "MapObj/CitySignal.h"
#include "MapObj/CoinCollectHintObj.h"
@ -210,7 +211,7 @@ const al::NameToCreator<al::ActorCreatorFunction> sProjectActorFactoryEntries[]
{"CardboardBox", nullptr},
{"CatchBomb", al::createActorFunction<CatchBomb>},
{"Chair", nullptr},
{"CheckpointFlag", nullptr},
{"CheckpointFlag", al::createActorFunction<CheckpointFlag>},
{"ChorobonHolder", nullptr},
{"ChurchDoor", al::createActorFunction<ChurchDoor>},
{"CityBuilding", nullptr},