mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-29 20:14:41 +00:00
110 lines
3.6 KiB
C++
110 lines
3.6 KiB
C++
#include "Library/Movement/EnemyStateBlowDown.h"
|
|
|
|
#include "Library/LiveActor/ActorActionFunction.h"
|
|
#include "Library/LiveActor/ActorClippingFunction.h"
|
|
#include "Library/LiveActor/ActorCollisionFunction.h"
|
|
#include "Library/LiveActor/ActorFlagFunction.h"
|
|
#include "Library/LiveActor/ActorMovementFunction.h"
|
|
#include "Library/LiveActor/ActorPoseUtil.h"
|
|
#include "Library/LiveActor/ActorSensorUtil.h"
|
|
#include "Library/Math/MathUtil.h"
|
|
|
|
const al::EnemyStateBlowDownParam sEnemyStateBlowDownParam = al::EnemyStateBlowDownParam();
|
|
|
|
namespace al {
|
|
EnemyStateBlowDown::EnemyStateBlowDown(LiveActor* actor, const EnemyStateBlowDownParam* param,
|
|
const char* name)
|
|
: ActorStateBase(name, actor), mParam(param) {
|
|
if (!mParam)
|
|
mParam = &sEnemyStateBlowDownParam;
|
|
}
|
|
|
|
void EnemyStateBlowDown::start(const HitSensor* other) {
|
|
sead::Vector3f dir = getSensorPos(other) - getTrans(mActor);
|
|
|
|
verticalizeVec(&dir, getGravity(mActor), dir);
|
|
|
|
if (!tryNormalizeOrZero(&dir))
|
|
calcFrontDir(&dir, mActor);
|
|
|
|
start(-dir);
|
|
}
|
|
|
|
void EnemyStateBlowDown::start(const sead::Vector3f& dir) {
|
|
if (mParam->isFaceAwayFromActor)
|
|
faceToDirection(mActor, -dir);
|
|
|
|
auto* actor = mActor;
|
|
sead::Vector3f direction = dir * mParam->velocityStrength;
|
|
sead::Vector3f gravity = getGravity(actor);
|
|
sead::Vector3f velocity = gravity * mParam->gravityStrength;
|
|
setVelocity(actor, direction - velocity);
|
|
}
|
|
|
|
void EnemyStateBlowDown::start(const HitSensor* other, const HitSensor* self) {
|
|
sead::Vector3f dir = getSensorPos(other) - getSensorPos(self);
|
|
|
|
verticalizeVec(&dir, getGravity(mActor), dir);
|
|
|
|
if (!tryNormalizeOrZero(&dir))
|
|
calcFrontDir(&dir, mActor);
|
|
|
|
start(-dir);
|
|
}
|
|
|
|
void EnemyStateBlowDown::start(const LiveActor* attacker) {
|
|
sead::Vector3f dir;
|
|
calcFrontDir(&dir, attacker);
|
|
|
|
start(-dir);
|
|
}
|
|
|
|
void EnemyStateBlowDown::appear() {
|
|
NerveStateBase::appear();
|
|
if (isInvalidClipping(mActor))
|
|
mIsInvalidClipping = true;
|
|
else {
|
|
invalidateClipping(mActor);
|
|
mIsInvalidClipping = false;
|
|
}
|
|
mBlowDownTimer = 0;
|
|
}
|
|
|
|
void EnemyStateBlowDown::kill() {
|
|
NerveStateBase::kill();
|
|
if (!mIsInvalidClipping)
|
|
validateClipping(mActor);
|
|
}
|
|
|
|
void EnemyStateBlowDown::control() {
|
|
if (mBlowDownTimer == 0) {
|
|
if (mParam->actionName)
|
|
startAction(mActor, mParam->actionName);
|
|
if (isExistActorCollider(mActor))
|
|
onCollide(mActor);
|
|
}
|
|
if ((mParam->blowDownLength <= mBlowDownTimer) ||
|
|
(mParam->actionName && isActionOneTime(mActor, mParam->actionName) &&
|
|
isActionEnd(mActor)) ||
|
|
(isExistActorCollider(mActor) && isOnGround(mActor, 0))) {
|
|
kill();
|
|
return;
|
|
}
|
|
addVelocityToGravity(mActor, mParam->velocityMultiplier);
|
|
scaleVelocity(mActor, mParam->velocityScale);
|
|
mBlowDownTimer++;
|
|
}
|
|
|
|
EnemyStateBlowDownParam::EnemyStateBlowDownParam() = default;
|
|
|
|
EnemyStateBlowDownParam::EnemyStateBlowDownParam(const char* actionName) : actionName(actionName) {}
|
|
|
|
EnemyStateBlowDownParam::EnemyStateBlowDownParam(const char* actionName, f32 velocityStrength,
|
|
f32 gravityStrength, f32 velocityMultiplier,
|
|
f32 velocityScale, s32 blowDownLength,
|
|
bool isFaceAwayFromActor)
|
|
: actionName(actionName), velocityStrength(velocityStrength), gravityStrength(gravityStrength),
|
|
velocityMultiplier(velocityMultiplier), velocityScale(velocityScale),
|
|
blowDownLength(blowDownLength), isFaceAwayFromActor(isFaceAwayFromActor) {}
|
|
} // namespace al
|