| 1 | #include "Library/Movement/EnemyStateBlowDown.h" |
| 2 | |
| 3 | #include "Library/LiveActor/ActorActionFunction.h" |
| 4 | #include "Library/LiveActor/ActorClippingFunction.h" |
| 5 | #include "Library/LiveActor/ActorCollisionFunction.h" |
| 6 | #include "Library/LiveActor/ActorFlagFunction.h" |
| 7 | #include "Library/LiveActor/ActorMovementFunction.h" |
| 8 | #include "Library/LiveActor/ActorPoseUtil.h" |
| 9 | #include "Library/LiveActor/ActorSensorUtil.h" |
| 10 | #include "Library/Math/MathUtil.h" |
| 11 | |
| 12 | const al::EnemyStateBlowDownParam sEnemyStateBlowDownParam = al::EnemyStateBlowDownParam(); |
| 13 | |
| 14 | namespace al { |
| 15 | EnemyStateBlowDown::EnemyStateBlowDown(LiveActor* actor, const EnemyStateBlowDownParam* param, |
| 16 | const char* name) |
| 17 | : ActorStateBase(name, actor), mParam(param) { |
| 18 | if (!mParam) |
| 19 | mParam = &sEnemyStateBlowDownParam; |
| 20 | } |
| 21 | |
| 22 | void EnemyStateBlowDown::start(const HitSensor* sensor) { |
| 23 | sead::Vector3f dir = getSensorPos(sensor) - getTrans(actor: mActor); |
| 24 | |
| 25 | verticalizeVec(out: &dir, vertical: getGravity(actor: mActor), vec: dir); |
| 26 | |
| 27 | if (!tryNormalizeOrZero(out: &dir)) |
| 28 | calcFrontDir(front: &dir, actor: mActor); |
| 29 | |
| 30 | start(-dir); |
| 31 | } |
| 32 | |
| 33 | void EnemyStateBlowDown::start(const sead::Vector3f& dir) { |
| 34 | if (mParam->faceAwayFromActor) |
| 35 | faceToDirection(actor: mActor, dir: -dir); |
| 36 | |
| 37 | auto* actor = mActor; |
| 38 | sead::Vector3f direction = dir * mParam->velocityStrength; |
| 39 | sead::Vector3f gravity = getGravity(actor); |
| 40 | sead::Vector3f velocity = gravity * mParam->gravityStrength; |
| 41 | setVelocity(actor, vel: direction - velocity); |
| 42 | } |
| 43 | |
| 44 | void EnemyStateBlowDown::start(const HitSensor* sensor1, const HitSensor* sensor2) { |
| 45 | sead::Vector3f dir = getSensorPos(sensor1) - getSensorPos(sensor2); |
| 46 | |
| 47 | verticalizeVec(out: &dir, vertical: getGravity(actor: mActor), vec: dir); |
| 48 | |
| 49 | if (!tryNormalizeOrZero(out: &dir)) |
| 50 | calcFrontDir(front: &dir, actor: mActor); |
| 51 | |
| 52 | start(dir: -dir); |
| 53 | } |
| 54 | |
| 55 | void EnemyStateBlowDown::start(const LiveActor* actor) { |
| 56 | sead::Vector3f dir; |
| 57 | calcFrontDir(front: &dir, actor); |
| 58 | |
| 59 | start(dir: -dir); |
| 60 | } |
| 61 | |
| 62 | void EnemyStateBlowDown::appear() { |
| 63 | al::NerveStateBase::appear(); |
| 64 | if (isInvalidClipping(mActor)) |
| 65 | mIsInvalidClipping = true; |
| 66 | else { |
| 67 | invalidateClipping(actor: mActor); |
| 68 | mIsInvalidClipping = false; |
| 69 | } |
| 70 | mBlowDownTimer = 0; |
| 71 | } |
| 72 | |
| 73 | void EnemyStateBlowDown::kill() { |
| 74 | al::NerveStateBase::kill(); |
| 75 | if (!mIsInvalidClipping) |
| 76 | validateClipping(actor: mActor); |
| 77 | } |
| 78 | |
| 79 | void EnemyStateBlowDown::control() { |
| 80 | if (mBlowDownTimer == 0) { |
| 81 | if (mParam->actionName) |
| 82 | startAction(actor: mActor, actionName: mParam->actionName); |
| 83 | if (isExistActorCollider(mActor)) |
| 84 | onCollide(actor: mActor); |
| 85 | } |
| 86 | if ((mParam->blowDownLength <= mBlowDownTimer) || |
| 87 | (mParam->actionName && isActionOneTime(actor: mActor, actionName: mParam->actionName) && |
| 88 | isActionEnd(actor: mActor)) || |
| 89 | (isExistActorCollider(mActor) && isOnGround(mActor, 0))) { |
| 90 | kill(); |
| 91 | return; |
| 92 | } |
| 93 | addVelocityToGravity(actor: mActor, force: mParam->velocityMultiplier); |
| 94 | scaleVelocity(actor: mActor, factor: mParam->velocityScale); |
| 95 | mBlowDownTimer++; |
| 96 | } |
| 97 | |
| 98 | EnemyStateBlowDownParam::EnemyStateBlowDownParam() {} |
| 99 | |
| 100 | EnemyStateBlowDownParam::EnemyStateBlowDownParam(const char* actionName) : actionName(actionName) {} |
| 101 | |
| 102 | EnemyStateBlowDownParam::EnemyStateBlowDownParam(const char* actionName, f32 velocityStrength, |
| 103 | f32 gravityStrength, f32 velocityMultiplier, |
| 104 | f32 velocityScale, s32 blowDownLength, |
| 105 | bool faceAwayFromActor) |
| 106 | : actionName(actionName), velocityStrength(velocityStrength), gravityStrength(gravityStrength), |
| 107 | velocityMultiplier(velocityMultiplier), velocityScale(velocityScale), |
| 108 | blowDownLength(blowDownLength), faceAwayFromActor(faceAwayFromActor) {} |
| 109 | } // namespace al |
| 110 | |