Boss/SmallWanderBoss: Implement SmallWanderBossBullet

This commit is contained in:
guymakinggames 2026-04-22 17:44:01 +01:00
parent b6f947c559
commit 3c9269fb1f
3 changed files with 362 additions and 24 deletions

View file

@ -21386,104 +21386,104 @@ Boss/SmallWanderBoss/SmallWanderBossBullet.o:
- offset: 0x0bab08
size: 156
label: _ZN21SmallWanderBossBulletC2EPKc
status: NotDecompiled
status: Matching
- offset: 0x0baba4
size: 168
label: _ZN21SmallWanderBossBulletC1EPKc
status: NotDecompiled
status: Matching
- offset: 0x0bac4c
size: 276
label: _ZN21SmallWanderBossBullet4initERKN2al13ActorInitInfoE
status: NotDecompiled
status: Matching
- offset: 0x0bad60
size: 44
label: _ZN21SmallWanderBossBullet6appearEv
status: NotDecompiled
status: Matching
- offset: 0x0bad8c
size: 36
label: _ZN21SmallWanderBossBullet4killEv
status: NotDecompiled
status: Matching
- offset: 0x0badb0
size: 240
label: _ZN21SmallWanderBossBullet7controlEv
status: NotDecompiled
status: Matching
- offset: 0x0baea0
size: 152
label: _ZN21SmallWanderBossBullet12attackSensorEPN2al9HitSensorES2_
status: NotDecompiled
status: Matching
- offset: 0x0baf38
size: 216
label: _ZN21SmallWanderBossBullet10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_
status: NotDecompiled
status: Matching
- offset: 0x0bb010
size: 248
label: _ZN21SmallWanderBossBullet12appearAttachEPKN4sead8Matrix34IfEEPKNS0_7Vector3IfEE
status: NotDecompiled
status: Matching
- offset: 0x0bb108
size: 248
label: _ZN21SmallWanderBossBullet21appearAttachParabolicEPKN4sead8Matrix34IfEEPKNS0_7Vector3IfEE
status: NotDecompiled
status: Matching
- offset: 0x0bb200
size: 100
label: _ZN21SmallWanderBossBullet20tryStartFlyParabolicERKN4sead7Vector3IfEEf
status: NotDecompiled
status: Matching
- offset: 0x0bb264
size: 100
label: _ZN21SmallWanderBossBullet11startLaunchEv
status: NotDecompiled
status: Matching
- offset: 0x0bb2c8
size: 208
label: _ZN21SmallWanderBossBullet15exeAppearAttachEv
status: NotDecompiled
status: Matching
- offset: 0x0bb398
size: 260
label: _ZN21SmallWanderBossBullet6exeFlyEv
status: NotDecompiled
status: Matching
- offset: 0x0bb49c
size: 92
label: _ZN21SmallWanderBossBullet19resetPositionByAnimEv
status: NotDecompiled
status: Matching
- offset: 0x0bb4f8
size: 292
label: _ZN21SmallWanderBossBullet10exeFlyDownEv
status: NotDecompiled
status: Matching
- offset: 0x0bb61c
size: 252
label: _ZN21SmallWanderBossBullet16exeSignExplosionEv
status: NotDecompiled
status: Matching
- offset: 0x0bb718
size: 156
label: _ZN21SmallWanderBossBullet12exeExplosionEv
status: NotDecompiled
status: Matching
- offset: 0x0bb7b4
size: 8
label: _ZNK12_GLOBAL__N_127SmallWanderBossBulletNrvFly7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x0bb7bc
size: 8
label: _ZNK12_GLOBAL__N_133SmallWanderBossBulletNrvExplosion7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x0bb7c4
size: 212
label: _ZNK12_GLOBAL__N_136SmallWanderBossBulletNrvAppearAttach7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x0bb898
size: 212
label: _ZNK12_GLOBAL__N_145SmallWanderBossBulletNrvAppearAttachParabolic7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x0bb96c
size: 8
label: _ZNK12_GLOBAL__N_131SmallWanderBossBulletNrvFlyDown7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
- offset: 0x0bb974
size: 8
label: _ZNK12_GLOBAL__N_137SmallWanderBossBulletNrvSignExplosion7executeEPN2al11NerveKeeperE
status: NotDecompiled
status: Matching
guess: true
Boss/SmallWanderBoss/SmallWanderBossStateAttack.o:
'.text':

View file

@ -0,0 +1,284 @@
#include "Boss/SmallWanderBoss/SmallWanderBossBullet.h"
#include "Library/Demo/DemoFunction.h"
#include "Library/LiveActor/ActorActionFunction.h"
#include "Library/LiveActor/ActorCollisionFunction.h"
#include "Library/LiveActor/ActorFlagFunction.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/Math/MathUtil.h"
#include "Library/Math/ParabolicPath.h"
#include "Library/Nature/NatureUtil.h"
#include "Library/Nature/WaterSurfaceFinder.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "Library/Player/PlayerUtil.h"
#include "Util/PlayerCollisionUtil.h"
#include "Util/SensorMsgFunction.h"
#include "Util/WaterSurfaceShadow.h"
namespace {
NERVE_IMPL(SmallWanderBossBullet, Fly)
NERVE_IMPL(SmallWanderBossBullet, Explosion)
NERVE_IMPL(SmallWanderBossBullet, AppearAttach)
NERVE_IMPL_(SmallWanderBossBullet, AppearAttachParabolic, AppearAttach)
NERVE_IMPL(SmallWanderBossBullet, FlyDown)
NERVE_IMPL(SmallWanderBossBullet, SignExplosion)
NERVES_MAKE_NOSTRUCT(SmallWanderBossBullet, Fly, FlyDown, SignExplosion, Explosion, AppearAttach,
AppearAttachParabolic)
} // namespace
SmallWanderBossBullet::SmallWanderBossBullet(const char* name) : al::LiveActor(name) {
_108 = {1.0f, 1.0f, 1.0f};
mParabolicPath = nullptr;
mWaterSurfaceFinder = nullptr;
mAttachMtx = nullptr;
mAttachOffset = nullptr;
mExplosionStepMax = 1200;
}
void SmallWanderBossBullet::init(const al::ActorInitInfo& initInfo) {
al::initActorWithArchiveName(this, initInfo, "SmallWanderBossBullet", nullptr);
al::initNerve(this, &Fly, 0);
al::setSensorRadius(this, "Attack", 60.0f);
al::setSensorRadius(this, "Body", 75.0f);
al::setColliderRadius(this, 40.0f);
mParabolicPath = new al::ParabolicPath();
mWaterSurfaceFinder = new al::WaterSurfaceFinder(this);
mWaterSurfaceShadow = new WaterSurfaceShadow(initInfo, "WaterSurfaceShadow");
mWaterSurfaceShadow->setScale(8.0f);
makeActorDead();
}
void SmallWanderBossBullet::appear() {
al::LiveActor::appear();
al::showModelIfHide(this);
al::offCollide(this);
}
void SmallWanderBossBullet::kill() {
al::LiveActor::kill();
mWaterSurfaceShadow->disappearShadow();
}
void SmallWanderBossBullet::control() {
if (al::isNerve(this, &Explosion))
return;
sead::Vector3f groundPos;
groundPos.x = 0.0f;
groundPos.y = 0.0f;
const al::IUseCollision* collision = this;
groundPos.z = 0.0f;
f32 distance = 7500.0f;
rs::calcGroundHeight(&distance, &groundPos, collision, al::getTrans(this),
-al::getGravity(this), 0.0f, 7500.0f);
mWaterSurfaceShadow->update(al::getTrans(this), -al::getGravity(this), distance);
}
void SmallWanderBossBullet::attackSensor(al::HitSensor* self, al::HitSensor* other) {
if (al::isNerve(this, &Explosion))
return;
if (!al::isSensorEnemyAttack(self))
return;
if (al::isNerve(this, &AppearAttach) || al::isNerve(this, &AppearAttachParabolic))
return;
if (al::sendMsgEnemyAttack(other, self))
al::setNerve(this, &Explosion);
}
bool SmallWanderBossBullet::receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
al::HitSensor* self) {
if (rs::isMsgPlayerDisregardTargetMarker(message) ||
rs::isMsgPlayerDisregardHomingAttack(message)) {
return true;
}
if (rs::isMsgKillByMoonRockDemo(message)) {
al::killForceBeforeDemo(this);
return true;
}
if (!al::isSensorEnemyBody(self) || al::isNerve(this, &Explosion))
return false;
if (rs::isMsgCapReflect(message) || al::isMsgKickStoneAttackReflect(message) ||
rs::isMsgSeedAttack(message)) {
rs::requestHitReactionToAttacker(message, self, other);
al::setNerve(this, &Explosion);
return true;
}
return false;
}
void SmallWanderBossBullet::appearAttach(const sead::Matrix34f* attachMtx,
const sead::Vector3f* attachOffset) {
const sead::Vector3f* offsetArg = attachOffset;
const sead::Matrix34f* mtxArg = attachMtx;
mAttachMtx = mtxArg;
mAttachOffset = offsetArg;
sead::Vector3f* trans = al::getTransPtr(this);
const sead::Vector3f* offset = offsetArg ? offsetArg : &sead::Vector3f::zero;
trans->setMul(*mtxArg, *offset);
sead::Vector3f* front = al::getFrontPtr(this);
mtxArg->getBase(*front, 2);
appear();
al::setNerve(this, &AppearAttach);
}
void SmallWanderBossBullet::appearAttachParabolic(const sead::Matrix34f* attachMtx,
const sead::Vector3f* attachOffset) {
const sead::Vector3f* offsetArg = attachOffset;
const sead::Matrix34f* mtxArg = attachMtx;
mAttachMtx = mtxArg;
mAttachOffset = offsetArg;
sead::Vector3f* trans = al::getTransPtr(this);
const sead::Vector3f* offset = offsetArg ? offsetArg : &sead::Vector3f::zero;
trans->setMul(*mtxArg, *offset);
sead::Vector3f* front = al::getFrontPtr(this);
mtxArg->getBase(*front, 2);
appear();
al::setNerve(this, &AppearAttachParabolic);
}
bool SmallWanderBossBullet::tryStartFlyParabolic(const sead::Vector3f& front, f32 launchSpeed) {
if (!al::isGreaterEqualStep(this, 5))
return false;
al::setFront(this, front);
mLaunchSpeed = launchSpeed;
al::setNerve(this, &FlyDown);
return true;
}
void SmallWanderBossBullet::startLaunch() {
sead::Vector3f velocity = al::getFront(this) * 10.0f;
al::setVelocity(this, velocity);
al::setNerve(this, &Fly);
}
void SmallWanderBossBullet::exeAppearAttach() {
const sead::Matrix34f* attachMtx = mAttachMtx;
const sead::Vector3f* attachOffset = mAttachOffset;
sead::Vector3f* trans = al::getTransPtr(this);
const sead::Vector3f* offset = attachOffset ? attachOffset : &sead::Vector3f::zero;
trans->setMul(*attachMtx, *offset);
sead::Vector3f* front = al::getFrontPtr(this);
attachMtx->getBase(*front, 2);
}
void SmallWanderBossBullet::exeFly() {
mWaterSurfaceFinder->update(al::getTrans(this), sead::Vector3f::ey, 100.0f);
if (al::isFirstStep(this)) {
sead::Vector3f jointPos = sead::Vector3f::zero;
al::calcJointPos(&jointPos, this, "SmallWanderBossBullet");
al::resetPosition(this, jointPos);
al::startAction(this, "Fly");
al::onCollide(this);
}
if (al::isCollided(this) || mWaterSurfaceFinder->isFoundSurface()) {
if (mWaterSurfaceFinder->isFoundSurface())
al::tryAddRippleLarge(this, mWaterSurfaceFinder->getSurfacePosition());
al::startHitReaction(this, "破壊");
kill();
return;
}
if (al::isGreaterEqualStep(this, 600))
kill();
}
void SmallWanderBossBullet::resetPositionByAnim() {
sead::Vector3f jointPos = sead::Vector3f::zero;
al::calcJointPos(&jointPos, this, "SmallWanderBossBullet");
al::resetPosition(this, jointPos);
}
void SmallWanderBossBullet::exeFlyDown() {
if (al::isFirstStep(this)) {
al::onCollide(this);
const sead::Vector3f& front = al::getFront(this);
f32 randomSpeed = al::getRandom(-200.0f, 200.0f);
al::setVelocitySeparateHV(this, front, randomSpeed + 300.0f, 100.0f);
}
al::addVelocityToGravity(this, 0.98f);
al::scaleVelocityHV(this, 0.96f, 0.98f);
mWaterSurfaceFinder->update(al::getTrans(this), sead::Vector3f::ey, 40.0f);
if (al::isCollided(this) || mWaterSurfaceFinder->isFoundSurface()) {
if (mWaterSurfaceFinder->isFoundSurface())
al::tryAddRippleLarge(this, mWaterSurfaceFinder->getSurfacePosition());
al::offCollide(this);
al::setNerve(this, &SignExplosion);
return;
}
if (al::isGreaterEqualStep(this, 600)) {
al::offCollide(this);
al::setNerve(this, &SignExplosion);
}
}
void SmallWanderBossBullet::exeSignExplosion() {
mWaterSurfaceFinder->update(al::getTrans(this), sead::Vector3f::ey, 40.0f);
if (al::isFirstStep(this)) {
al::startAction(this, "SignExplosion");
mExplosionStepMax = 1200;
}
if (mExplosionStepMax == 1200 && al::isNearPlayer(this, 3000.0f)) {
s32 step = al::getNerveStep(this) + 90;
if (step >= 1200)
step = 1200;
mExplosionStepMax = step;
}
al::approachWaterSurfaceSpringDumper(this, mWaterSurfaceFinder, 0.0f, 12.0f, 1.0f, 0.022f,
0.93f);
if (al::isGreaterEqualStep(this, mExplosionStepMax))
al::setNerve(this, &Explosion);
}
void SmallWanderBossBullet::exeExplosion() {
if (al::isFirstStep(this)) {
if (mWaterSurfaceFinder->isFoundSurface()) {
al::tryAddRippleWithRange(this, mWaterSurfaceFinder->getSurfacePosition(), 0.25f,
300.0f, 1000.0f, 1000.0f);
}
al::startHitReaction(this, "破壊");
al::hideModelIfShow(this);
mWaterSurfaceShadow->disappearShadow();
}
if (al::isGreaterEqualStep(this, 30))
kill();
}

View file

@ -0,0 +1,54 @@
#pragma once
#include <math/seadMatrix.h>
#include <math/seadVector.h>
#include "Library/LiveActor/LiveActor.h"
namespace al {
struct ActorInitInfo;
class HitSensor;
class ParabolicPath;
class SensorMsg;
class WaterSurfaceFinder;
} // namespace al
class WaterSurfaceShadow;
class SmallWanderBossBullet : public al::LiveActor {
public:
SmallWanderBossBullet(const char* name);
void init(const al::ActorInitInfo& initInfo) override;
void appear() override;
void kill() 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;
void appearAttach(const sead::Matrix34f* attachMtx, const sead::Vector3f* attachOffset);
void appearAttachParabolic(const sead::Matrix34f* attachMtx,
const sead::Vector3f* attachOffset);
bool tryStartFlyParabolic(const sead::Vector3f& front, f32 launchSpeed);
void startLaunch();
void exeAppearAttach();
void exeFly();
void resetPositionByAnim();
void exeFlyDown();
void exeSignExplosion();
void exeExplosion();
private:
sead::Vector3f _108; // TODO: verify exact meaning
u32 _114; // TODO: verify exact meaning
const sead::Matrix34f* mAttachMtx;
const sead::Vector3f* mAttachOffset;
al::ParabolicPath* mParabolicPath;
al::WaterSurfaceFinder* mWaterSurfaceFinder;
WaterSurfaceShadow* mWaterSurfaceShadow;
f32 mLaunchSpeed; // TODO: verify exact usage
s32 mExplosionStepMax;
};
static_assert(sizeof(SmallWanderBossBullet) == 0x148);