MapObj: Implement PoleGrabCeil (#861)

This commit is contained in:
Naii-the-Baf 2026-01-11 03:16:19 -06:00 committed by GitHub
parent bd8b1ad66d
commit 147f1548df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 229 additions and 17 deletions

View file

@ -79939,61 +79939,61 @@ MapObj/PoleGrabCeil.o:
- offset: 0x2e5cfc
size: 156
label: _ZN12PoleGrabCeilC2EPKc
status: NotDecompiled
status: Matching
- offset: 0x2e5d98
size: 168
label: _ZN12PoleGrabCeilC1EPKc
status: NotDecompiled
status: Matching
- offset: 0x2e5e40
size: 420
label: _ZN12PoleGrabCeil4initERKN2al13ActorInitInfoE
status: NotDecompiled
status: Matching
- offset: 0x2e5fe4
size: 180
label: _ZN12PoleGrabCeil18initAfterPlacementEv
status: NotDecompiled
status: Matching
- offset: 0x2e6098
size: 484
label: _ZN12PoleGrabCeil7controlEv
status: NotDecompiled
status: Matching
- offset: 0x2e627c
size: 16
label: _ZN12PoleGrabCeil7exeWaitEv
status: NotDecompiled
status: Matching
- offset: 0x2e628c
size: 244
label: ''
status: NotDecompiled
label: _Z12followPlayerPN4sead7Vector3IfEEPN2al9LiveActorE
status: Matching
- offset: 0x2e6380
size: 16
label: _ZN12PoleGrabCeil7exeGrabEv
status: NotDecompiled
status: Matching
- offset: 0x2e6390
size: 80
label: _ZN12PoleGrabCeil10exeGrabEndEv
status: NotDecompiled
status: Matching
- offset: 0x2e63e0
size: 396
label: _ZN12PoleGrabCeil12attackSensorEPN2al9HitSensorES2_
status: NotDecompiled
status: Matching
- offset: 0x2e656c
size: 148
label: _ZN12PoleGrabCeil10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_
status: NotDecompiled
status: Matching
- offset: 0x2e6600
size: 12
label: _ZNK12_GLOBAL__N_119PoleGrabCeilNrvWait7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2e660c
size: 12
label: _ZNK12_GLOBAL__N_119PoleGrabCeilNrvGrab7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x2e6618
size: 80
label: _ZNK12_GLOBAL__N_122PoleGrabCeilNrvGrabEnd7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
MapObj/PosterWatcher.o:
'.text':
@ -135103,7 +135103,7 @@ Scene/ProjectActorFactory.o:
- offset: 0x4ba538
size: 52
label: _ZN2al19createActorFunctionI12PoleGrabCeilEEPNS_9LiveActorEPKc
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x4ba56c
size: 52

173
src/MapObj/PoleGrabCeil.cpp Normal file
View file

@ -0,0 +1,173 @@
#include "MapObj/PoleGrabCeil.h"
#include <basis/seadTypes.h>
#include "Library/Collision/CollisionPartsKeeperUtil.h"
#include "Library/Collision/CollisionPartsTriangle.h"
#include "Library/Collision/PartsConnectorUtil.h"
#include "Library/Effect/EffectSystemInfo.h"
#include "Library/LiveActor/ActorActionFunction.h"
#include "Library/LiveActor/ActorAreaFunction.h"
#include "Library/LiveActor/ActorInitFunction.h"
#include "Library/LiveActor/ActorInitUtil.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/ActorSensorUtil.h"
#include "Library/Math/MathUtil.h"
#include "Library/Matrix/MatrixUtil.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "Library/Obj/KeyMoveFollowTarget.h"
#include "Library/Placement/PlacementFunction.h"
#include "Util/PlayerUtil.h"
#include "Util/SensorMsgFunction.h"
namespace {
NERVE_IMPL(PoleGrabCeil, Wait);
NERVE_IMPL(PoleGrabCeil, Grab);
NERVE_IMPL(PoleGrabCeil, GrabEnd);
NERVES_MAKE_STRUCT(PoleGrabCeil, Wait, Grab, GrabEnd);
} // namespace
PoleGrabCeil::PoleGrabCeil(const char* name) : al::LiveActor(name) {}
void PoleGrabCeil::init(const al::ActorInitInfo& initInfo) {
if (al::isObjectName(initInfo, "PoleGrabCeilKeyMoveParts")) {
al::initActorWithArchiveName(this, initInfo, "PoleGrabCeilKeyMoveParts", "KeyMoveParts");
mKeyMoveFollowTarget = new al::KeyMoveFollowTarget("ぶらさがり棒[キームーブ移動]本体");
mKeyMoveFollowTarget->initKeyMoveFollowTarget(initInfo, "PoleGrabCeilKeyMoveParts",
nullptr);
al::initSubActorKeeperNoFile(this, initInfo, 1);
al::registerSubActor(this, mKeyMoveFollowTarget);
al::tryGetArg(&mIsCollisionCheck, initInfo, "IsCollisionCheck");
mSurfaceMatrix.makeIdentity();
al::setEffectNamedMtxPtr(mKeyMoveFollowTarget, "Surface", &mSurfaceMatrix);
} else {
al::initActorWithArchiveName(this, initInfo, "PoleGrabCeil", nullptr);
mMtxConnector = al::tryCreateMtxConnector(this, initInfo);
mIsConnectPose = al::tryGetBoolArgOrFalse(initInfo, "IsConnectPose");
}
al::initNerve(this, &NrvPoleGrabCeil.Wait, 0);
al::setHitSensorPosPtr(this, "Snap", &mSnapSensorPos);
makeActorAlive();
}
void PoleGrabCeil::initAfterPlacement() {
if (mMtxConnector) {
sead::Vector3f sideDir = {0.0f, 0.0f, 0.0f};
al::calcSideDir(&sideDir, this);
al::attachMtxConnectorToCollision(mMtxConnector, this, al::getTrans(this) + sideDir * 50.0f,
sideDir * -150.0f);
}
}
void PoleGrabCeil::control() {
if (mKeyMoveFollowTarget) {
sead::Vector3f prevPos = al::getTrans(this);
al::copyPose(this, mKeyMoveFollowTarget);
if (!mIsCollisionCheck)
return;
sead::Vector3f moveVec = al::getTrans(this) - prevPos;
sead::Vector3f moveDir = {0.0f, 0.0f, 0.0f};
if (!al::tryNormalizeOrZero(&moveDir, moveVec))
return;
const al::ArrowHitInfo* hitInfo = nullptr;
if (!alCollisionUtil::getFirstPolyOnArrow(this, &hitInfo, prevPos - moveDir,
moveDir + moveVec, nullptr, nullptr)) {
if (!alCollisionUtil::getFirstPolyOnArrow(this, &hitInfo, prevPos + moveDir,
-moveVec - moveDir, nullptr, nullptr)) {
return;
}
}
const sead::Vector3f& hitPos = alCollisionUtil::getCollisionHitPos(**hitInfo);
const sead::Vector3f& hitNormal = alCollisionUtil::getCollisionHitPos(**hitInfo);
al::makeMtxUpNoSupportPos(&mSurfaceMatrix, hitNormal, hitPos);
al::startHitReaction(mKeyMoveFollowTarget, "コリジョンヒット");
return;
}
if (mMtxConnector) {
if (mIsConnectPose) {
al::connectPoseQT(this, mMtxConnector);
return;
}
sead::Vector3f connectTrans = {0.0f, 0.0f, 0.0f};
al::calcConnectTrans(&connectTrans, mMtxConnector);
al::updatePoseTrans(this, connectTrans);
}
}
void followPlayer(sead::Vector3f* pos, al::LiveActor* actor) {
sead::Vector3f sideDir = {0.0f, 0.0f, 0.0f};
al::calcSideDir(&sideDir, actor);
f32 sideOff = sead::Mathf::clamp(sideDir.dot(rs::getPlayerPos(actor) - al::getTrans(actor)),
0.0f, 380.0f);
pos->set(al::getTrans(actor) + sideOff * sideDir);
}
void PoleGrabCeil::exeWait() {
followPlayer(&mSnapSensorPos, this);
}
void PoleGrabCeil::exeGrab() {
followPlayer(&mSnapSensorPos, this);
}
void PoleGrabCeil::exeGrabEnd() {
followPlayer(&mSnapSensorPos, this);
if (!al::isLessEqualStep(this, 30))
al::setNerve(this, &NrvPoleGrabCeil.Wait);
}
void PoleGrabCeil::attackSensor(al::HitSensor* self, al::HitSensor* other) {
if (!al::isNerve(this, &NrvPoleGrabCeil.Wait) || rs::isPlayerCollidedGround(this) ||
al::isInAreaObj(this, "PoleGrabCeilNoSnapArea") || rs::isPlayerCarrySomething(this)) {
return;
}
sead::Vector3f bodyPos = rs::getPlayerBodyPos(this);
sead::Vector3f sensorPos = al::getSensorPos(self);
sead::Vector3f sideDir = {0.0f, 0.0f, 0.0f};
al::calcSideDir(&sideDir, this);
if (al::isInRange(sideDir.dot(bodyPos - al::getTrans(this)), 0.0f, 380.0f)) {
f32 scalar = 0.0f;
sead::Vector3f dir = {0.0f, 0.0f, 0.0f};
al::separateScalarAndDirection(&scalar, &dir, sensorPos - bodyPos);
scalar = sead::Mathf::clampMin(scalar * 0.25f, sead::Mathf::clampMax(40.0f, scalar));
rs::sendMsgObjSnapForce(other, self, dir * scalar);
}
}
bool PoleGrabCeil::receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) {
if (rs::isMsgPlayerDisregardHomingAttack(message))
return true;
if (rs::isMsgPlayerStartGrabCeil(message)) {
if (al::isNerve(this, &NrvPoleGrabCeil.Wait)) {
al::setNerve(this, &NrvPoleGrabCeil.Grab);
return true;
}
return false;
}
if (rs::isMsgPlayerEndGrabCeil(message)) {
if (al::isNerve(this, &NrvPoleGrabCeil.Grab)) {
al::setNerve(this, &NrvPoleGrabCeil.GrabEnd);
return true;
}
return false;
}
return false;
}

38
src/MapObj/PoleGrabCeil.h Normal file
View file

@ -0,0 +1,38 @@
#pragma once
#include <math/seadMatrix.h>
#include <math/seadVector.h>
#include "Library/LiveActor/LiveActor.h"
namespace al {
struct ActorInitInfo;
class HitSensor;
class KeyMoveFollowTarget;
class MtxConnector;
class SensorMsg;
} // namespace al
class PoleGrabCeil : public al::LiveActor {
public:
PoleGrabCeil(const char* name);
void init(const al::ActorInitInfo& initInfo) override;
void initAfterPlacement() override;
void control() override;
void exeWait();
void exeGrab();
void exeGrabEnd();
void attackSensor(al::HitSensor* self, al::HitSensor* other) override;
bool receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) override;
private:
sead::Vector3f mSnapSensorPos = {0.0f, 0.0f, 0.0f};
al::MtxConnector* mMtxConnector = nullptr;
al::KeyMoveFollowTarget* mKeyMoveFollowTarget = nullptr;
bool mIsConnectPose = false;
bool mIsCollisionCheck = false;
sead::Matrix34f mSurfaceMatrix = sead::Matrix34f::ident;
};
static_assert(sizeof(PoleGrabCeil) == 0x160);

View file

@ -66,6 +66,7 @@
#include "MapObj/MoonBasementSlideObj.h"
#include "MapObj/MoonWorldCaptureParadeLift.h"
#include "MapObj/PeachWorldTree.h"
#include "MapObj/PoleGrabCeil.h"
#include "MapObj/RouletteSwitch.h"
#include "MapObj/SaveFlagCheckObj.h"
#include "MapObj/SignBoardDanger.h"
@ -432,7 +433,7 @@ const al::NameToCreator<al::ActorCreatorFunction> sProjectActorFactoryEntries[]
{"Poetter", nullptr},
{"PoleClimbParts", nullptr},
{"PoleClimbPartsBreak", nullptr},
{"PoleGrabCeil", nullptr},
{"PoleGrabCeil", al::createActorFunction<PoleGrabCeil>},
{"PoleGrabCeilKeyMoveParts", nullptr},
{"PopnGenerator", nullptr},
{"LavaWorldPoster", nullptr},