MapObj: Implement SignBoardDanger (#611)

This commit is contained in:
Naii-the-Baf 2025-06-02 03:04:05 -06:00 committed by GitHub
parent b4e0ac3397
commit 0c44e67705
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 313 additions and 14 deletions

View file

@ -19352,18 +19352,18 @@ Address,Quality,Size,Name
0x000000710031b284,U,000304,_ZN13SignBoardBlow7exeBlowEv
0x000000710031b3b4,U,000004,_ZNK12_GLOBAL__N_120SignBoardBlowNrvWait7executeEPN2al11NerveKeeperE
0x000000710031b3b8,U,000008,_ZNK12_GLOBAL__N_120SignBoardBlowNrvBlow7executeEPN2al11NerveKeeperE
0x000000710031b3c0,U,000128,_ZN15SignBoardDangerC2EPKc
0x000000710031b440,U,000140,_ZN15SignBoardDangerC1EPKc
0x000000710031b4cc,U,000712,_ZN15SignBoardDanger4initERKN2al13ActorInitInfoE
0x000000710031b794,U,000700,_ZN15SignBoardDanger10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_
0x000000710031ba50,U,000096,_ZN15SignBoardDanger18isCanStartReactionEv
0x000000710031bab0,U,000120,_ZN15SignBoardDanger12attackSensorEPN2al9HitSensorES2_
0x000000710031bb28,U,000072,_ZN15SignBoardDanger7exeWaitEv
0x000000710031bb70,U,000096,_ZN15SignBoardDanger11exeReactionEv
0x000000710031bbd0,U,000236,_ZN15SignBoardDanger7exeDeadEv
0x000000710031bcbc,U,000076,_ZNK12_GLOBAL__N_122SignBoardDangerNrvWait7executeEPN2al11NerveKeeperE
0x000000710031bd08,U,000008,_ZNK12_GLOBAL__N_122SignBoardDangerNrvDead7executeEPN2al11NerveKeeperE
0x000000710031bd10,U,000100,_ZNK12_GLOBAL__N_126SignBoardDangerNrvReaction7executeEPN2al11NerveKeeperE
0x000000710031b3c0,O,000128,_ZN15SignBoardDangerC2EPKc
0x000000710031b440,O,000140,_ZN15SignBoardDangerC1EPKc
0x000000710031b4cc,M,000712,_ZN15SignBoardDanger4initERKN2al13ActorInitInfoE
0x000000710031b794,O,000700,_ZN15SignBoardDanger10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_
0x000000710031ba50,O,000096,_ZN15SignBoardDanger18isCanStartReactionEv
0x000000710031bab0,O,000120,_ZN15SignBoardDanger12attackSensorEPN2al9HitSensorES2_
0x000000710031bb28,O,000072,_ZN15SignBoardDanger7exeWaitEv
0x000000710031bb70,O,000096,_ZN15SignBoardDanger11exeReactionEv
0x000000710031bbd0,O,000236,_ZN15SignBoardDanger7exeDeadEv
0x000000710031bcbc,O,000076,_ZNK12_GLOBAL__N_122SignBoardDangerNrvWait7executeEPN2al11NerveKeeperE
0x000000710031bd08,O,000008,_ZNK12_GLOBAL__N_122SignBoardDangerNrvDead7executeEPN2al11NerveKeeperE
0x000000710031bd10,O,000100,_ZNK12_GLOBAL__N_126SignBoardDangerNrvReaction7executeEPN2al11NerveKeeperE
0x000000710031bd74,U,000124,_ZN22SignBoardLayoutTextureC2EPKc
0x000000710031bdf0,U,000136,_ZN22SignBoardLayoutTextureC1EPKc
0x000000710031be78,U,000368,_ZN22SignBoardLayoutTexture4initERKN2al13ActorInitInfoE
@ -30370,7 +30370,7 @@ Address,Quality,Size,Name
0x00000071004bbbc4,U,000052,_ZN2al19createActorFunctionI13ShopBgmPlayerEEPNS_9LiveActorEPKc
0x00000071004bbbf8,U,000052,_ZN2al19createActorFunctionI8ShopMarkEEPNS_9LiveActorEPKc
0x00000071004bbc2c,U,000060,_ZN2al19createActorFunctionI15ShoppingWatcherEEPNS_9LiveActorEPKc
0x00000071004bbc68,U,000052,_ZN2al19createActorFunctionI15SignBoardDangerEEPNS_9LiveActorEPKc
0x00000071004bbc68,O,000052,_ZN2al19createActorFunctionI15SignBoardDangerEEPNS_9LiveActorEPKc
0x00000071004bbc9c,U,000052,_ZN2al19createActorFunctionI22SignBoardLayoutTextureEEPNS_9LiveActorEPKc
0x00000071004bbcd0,U,000052,_ZN2al19createActorFunctionI25SkyFukankunZoomCapMessageEEPNS_9LiveActorEPKc
0x00000071004bbd04,U,000052,_ZN2al19createActorFunctionI13SkyWorldCloudEEPNS_9LiveActorEPKc

Can't render this file because it is too large.

47
src/MapObj/CapHanger.h Normal file
View file

@ -0,0 +1,47 @@
#pragma once
#include <basis/seadTypes.h>
#include "Library/LiveActor/LiveActor.h"
namespace al {
struct ActorInitInfo;
class HitSensor;
class SensorMsg;
} // namespace al
class CapHanger : public al::LiveActor {
public:
CapHanger(const char*, bool);
void init(const al::ActorInitInfo& info) override;
void initItem(s32, s32, const al::ActorInitInfo&);
void switchOn();
void switchOff();
void switchKill();
void initAfterPlacement() override;
void kill() override;
void control() override;
void attackSensor(al::HitSensor* other, al::HitSensor* self) override;
bool receiveMsg(const al::SensorMsg* msg, al::HitSensor* other, al::HitSensor* self) override;
void exeWait();
void exeKeep();
void exeRelease();
bool isKeep(s32) const;
void setPeachCastleCap(const sead::Vector3f&);
private:
void* _108;
void* _110;
s32 _118;
s32 _11c;
s32 _120;
void* _128;
bool _130;
void* _138;
void* _140;
sead::Matrix34f _148;
sead::Matrix34f _178;
bool _1a8;
};
static_assert(sizeof(CapHanger) == 0x1b0);

View file

@ -0,0 +1,27 @@
#pragma once
#include <basis/seadTypes.h>
#include "Library/LiveActor/LiveActor.h"
namespace al {
struct ActorInitInfo;
class HitSensor;
class SensorMsg;
} // namespace al
class SignBoardBlow : public al::LiveActor {
public:
SignBoardBlow(const char* actorName, const char* signBoardBlowName);
void init(const al::ActorInitInfo& info) override;
bool receiveMsg(const al::SensorMsg* msg, al::HitSensor* other, al::HitSensor* self) override;
void startBlow(const sead::Vector3f&);
void exeWait();
void exeBlow();
private:
const char* mName = nullptr;
sead::Vector3f _110;
};
static_assert(sizeof(SignBoardBlow) == 0x120);

View file

@ -0,0 +1,191 @@
#include "MapObj/SignBoardDanger.h"
#include "Library/Controller/PadRumbleFunction.h"
#include "Library/LiveActor/ActorActionFunction.h"
#include "Library/LiveActor/ActorClippingFunction.h"
#include "Library/LiveActor/ActorCollisionFunction.h"
#include "Library/LiveActor/ActorInitUtil.h"
#include "Library/LiveActor/ActorModelFunction.h"
#include "Library/LiveActor/ActorMovementFunction.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/ActorSensorUtil.h"
#include "Library/LiveActor/LiveActorFunction.h"
#include "Library/Math/MathUtil.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "Library/Placement/PlacementFunction.h"
#include "MapObj/CapHanger.h"
#include "MapObj/SignBoardBlow.h"
#include "Util/ItemUtil.h"
#include "Util/SensorMsgFunction.h"
namespace {
NERVE_IMPL(SignBoardDanger, Wait);
NERVE_IMPL(SignBoardDanger, Reaction);
NERVE_IMPL(SignBoardDanger, Dead);
NERVES_MAKE_STRUCT(SignBoardDanger, Wait, Dead, Reaction);
} // namespace
SignBoardDanger::SignBoardDanger(const char* name) : al::LiveActor(name) {}
// Mismatch: https://decomp.me/scratch/mqOky
void SignBoardDanger::init(const al::ActorInitInfo& info) {
al::initMapPartsActor(this, info, nullptr);
sead::Vector3f upDir;
al::calcUpDir(&upDir, this);
sead::Vector3f trans;
al::getTrans(&trans, info);
mSignBoardBlow = new SignBoardBlow("壊れモデル", "SignBoardDangerBreak");
al::initCreateActorNoPlacementInfo(mSignBoardBlow, info);
mYRotation = al::getRotate(this).y;
al::initNerve(this, &NrvSignBoardDanger.Wait, 0);
makeActorAlive();
// Mismatch starts here
sead::Vector3f upDir2;
sead::Vector3f rightDir;
sead::Vector3f frontDir;
al::calcUpDir(&upDir2, this);
al::calcRightDir(&rightDir, this);
al::calcFrontDir(&frontDir, this);
al::getTrans(this);
f32 rotation = mYRotation;
al::calcUpDir(&upDir2, this);
al::calcRightDir(&rightDir, this);
al::calcFrontDir(&frontDir, this);
sead::Vector3f trans2 = al::getTrans(this);
sead::Quatf yDegree;
sead::Quatf zDegree;
al::makeQuatYDegree(&yDegree, rotation);
al::makeQuatZDegree(&zDegree, -18.0f);
sead::Vector3f targetTrans = trans2 + 315.0f * upDir2 + -69.0f * rightDir + 0.0f * frontDir;
sead::Quatf quat = zDegree * yDegree;
// Mismatch ends here
mCapHanger = new CapHanger("CapHanger", false);
al::initCreateActorNoPlacementInfo(mCapHanger, info);
al::setTrans(mCapHanger, targetTrans);
al::setQuat(mCapHanger, quat);
s32 itemType = rs::getItemType(info);
if (itemType != -1)
mCapHanger->initItem(itemType, 1, info);
mCapHanger->makeActorAlive();
}
bool SignBoardDanger::receiveMsg(const al::SensorMsg* msg, al::HitSensor* other,
al::HitSensor* self) {
if (al::isNerve(this, &NrvSignBoardDanger.Dead)) {
if (rs::isMsgPlayerDisregardHomingAttack(msg) ||
rs::isMsgPlayerDisregardTargetMarker(msg) || al::isMsgPlayerDisregard(msg)) {
return true;
}
if (al::isSensorName(self, "Cap") && !al::isSensorCollision(other))
mRespawnTimer = sead::Mathi::max(mRespawnTimer, 6);
return false;
}
if (rs::isMsgPlayerDisregardHomingAttack(msg) || rs::isMsgPlayerDisregardTargetMarker(msg))
return true;
if (rs::isMsgBreakSignBoard(msg)) {
SignBoardBlow* signBlow = mSignBoardBlow;
sead::Vector3f upDir = sead::Vector3f::ey;
sead::Vector3f rightDir;
sead::Vector3f frontDir;
al::calcRightDir(&rightDir, this);
al::calcFrontDir(&frontDir, this);
sead::Vector3f resetPos =
al::getTrans(this) + 30.0f * rightDir + 200.0f * upDir + 0.0f * frontDir;
al::resetPosition(signBlow, resetPos);
al::setRotateY(signBlow, al::getRotate(this).y);
alPadRumbleFunction::startPadRumble(this, "破壊汎用(小)", 1000.0f, 3000.0f, -1);
signBlow->startBlow(al::getActorTrans(other));
al::LiveActor* subactor = al::getSubActor(this, "残骸モデル");
subactor->appear();
al::resetPosition(subactor, al::getTrans(this));
mCapHanger->kill();
al::setNerve(this, &NrvSignBoardDanger.Dead);
return true;
}
if (al::isSensorCollision(self) && rs::isMsgCapReflectCollide(msg) && isCanStartReaction()) {
rs::requestHitReactionToAttacker(msg, self, other);
al::setNerve(this, &NrvSignBoardDanger.Reaction);
return true;
}
return false;
}
bool SignBoardDanger::isCanStartReaction() {
if (al::isNerve(this, &NrvSignBoardDanger.Wait))
return true;
return al::isNerve(this, &NrvSignBoardDanger.Reaction) && al::isGreaterEqualStep(this, 30);
}
void SignBoardDanger::attackSensor(al::HitSensor* other, al::HitSensor* self) {
if (al::isNerve(this, &NrvSignBoardDanger.Dead) && (u32)mRespawnTimer < 5 &&
al::isSensorName(other, "Cap")) {
al::sendMsgPush(self, other);
}
}
void SignBoardDanger::exeWait() {
if (al::isFirstStep(this)) {
al::startAction(this, "Wait");
al::setRotateY(this, mYRotation);
}
}
void SignBoardDanger::exeReaction() {
if (al::isFirstStep(this)) {
al::startAction(this, "Reaction");
return;
}
if (al::isActionEnd(this))
al::setNerve(this, &NrvSignBoardDanger.Wait);
}
void SignBoardDanger::exeDead() {
if (al::isFirstStep(this)) {
al::hideModel(this);
al::invalidateClipping(this);
al::invalidateHitSensors(this);
al::validateHitSensor(this, "Cap");
al::invalidateCollisionParts(this);
mRespawnTimer = 180;
}
mRespawnTimer--;
if (mRespawnTimer <= 0) {
al::setRotateY(this, mYRotation);
al::showModel(this);
al::validateClipping(this);
al::validateHitSensors(this);
al::validateCollisionParts(this);
al::setNerve(this, &NrvSignBoardDanger.Wait);
al::startHitReaction(this, "出現");
al::getSubActor(this, "残骸モデル")->kill();
mCapHanger->appear();
mRespawnTimer = 0;
}
}

View file

@ -0,0 +1,33 @@
#pragma once
#include <basis/seadTypes.h>
#include "Library/LiveActor/LiveActor.h"
namespace al {
struct ActorInitInfo;
class HitSensor;
class SensorMsg;
} // namespace al
class CapHanger;
class SignBoardBlow;
class SignBoardDanger : public al::LiveActor {
public:
SignBoardDanger(const char* name);
void init(const al::ActorInitInfo& info) override;
bool receiveMsg(const al::SensorMsg* msg, al::HitSensor* other, al::HitSensor* self) override;
bool isCanStartReaction();
void attackSensor(al::HitSensor* other, al::HitSensor* self) override;
void exeWait();
void exeReaction();
void exeDead();
private:
SignBoardBlow* mSignBoardBlow = nullptr;
f32 mYRotation = 0.0f;
s32 mRespawnTimer = 0;
CapHanger* mCapHanger = nullptr;
};
static_assert(sizeof(SignBoardDanger) == 0x120);

View file

@ -65,6 +65,7 @@
#include "MapObj/PeachWorldTree.h"
#include "MapObj/RouletteSwitch.h"
#include "MapObj/SaveFlagCheckObj.h"
#include "MapObj/SignBoardDanger.h"
#include "MapObj/Souvenir.h"
#include "MapObj/StageSwitchSelector.h"
#include "MapObj/TrampleBush.h"
@ -498,7 +499,7 @@ const al::NameToCreator<al::ActorCreatorFunction> sProjectActorFactoryEntries[]
{"ShopBgmPlayer", nullptr},
{"ShopMark", nullptr},
{"ShoppingWatcher", nullptr},
{"SignBoardDanger", nullptr},
{"SignBoardDanger", al::createActorFunction<SignBoardDanger>},
{"SignBoardLayoutTexture", nullptr},
{"SkyFukankunZoomCapMessage", nullptr},
{"SkyWorldCloud", nullptr},