1#include "Enemy/HackerDepthShadowMapCtrl.h"
2
3#include "Library/Area/AreaObj.h"
4#include "Library/Area/AreaObjUtil.h"
5#include "Library/Collision/CollisionPartsKeeperUtil.h"
6#include "Library/LiveActor/ActorAreaFunction.h"
7#include "Library/LiveActor/ActorCollisionFunction.h"
8#include "Library/LiveActor/ActorPoseUtil.h"
9#include "Library/Math/MathUtil.h"
10#include "Library/Placement/PlacementFunction.h"
11#include "Library/Shadow/ActorShadowUtil.h"
12
13#include "Player/PlayerCollider.h"
14
15HackerDepthShadowMapCtrl::HackerDepthShadowMapCtrl(al::LiveActor* actor, const char* shadowMapName,
16 f32 shadowLengthOffset, f32 lerpLength,
17 f32 lerpGradationLength)
18 : mActor(actor), mShadowMapName(shadowMapName), mShadowLengthOffset(shadowLengthOffset),
19 mLerpLength(lerpLength), mLerpGradationLength(lerpGradationLength) {
20 al::setEnableDepthShadowMapBottomGradation(actor, mapName: shadowMapName, isEnableBottomGradation: true);
21}
22
23void HackerDepthShadowMapCtrl::resetAndUpdate() {
24 f32 prevLerpLength = mLerpLength;
25 f32 prevLerpGradationLength = mLerpGradationLength;
26 mOnGroundTimer = 0;
27 mIsActive = false;
28 mLerpLength = 1.0f;
29 mLerpGradationLength = 1.0f;
30 update(playerCollider: nullptr);
31 mIsActive = true;
32 mLerpLength = prevLerpLength;
33 mLerpGradationLength = prevLerpGradationLength;
34}
35
36void HackerDepthShadowMapCtrl::update(PlayerCollider* playerCollider) {
37 if (playerCollider && mIsActive) {
38 if (playerCollider->get_70() >= 0.0f) {
39 if (mOnGroundTimer <= 2)
40 mOnGroundTimer++;
41 } else if (mOnGroundTimer > 0)
42 mOnGroundTimer--;
43 }
44
45 sead::Vector3f groundNormal = sead::Vector3f::ey;
46 f32 groundDistance;
47
48 al::AreaObj* shadowLengthArea = al::tryFindAreaObj(actor: mActor, name: "GroundShadowLengthReviseArea");
49
50 if (shadowLengthArea) {
51 const sead::Vector3f& actorTrans = al::getTrans(actor: mActor);
52 sead::Vector3f areaScale = {0.0f, 0.0f, 0.0f};
53 al::tryGetScale(scale: &areaScale, placementInfo: *shadowLengthArea->getPlacementInfo());
54
55 const sead::Matrix34f& areaMtx = al::getAreaObjBaseMtx(areaObj: shadowLengthArea);
56
57 sead::Vector3f areaPos;
58 areaMtx.getTranslation(o&: areaPos);
59
60 sead::Vector3f areaUp = {0.0f, 0.0f, 0.0f};
61 areaMtx.getBase(o&: areaUp, axis: 1);
62
63 sead::Vector3f offset = actorTrans;
64 offset -= areaPos;
65
66 al::verticalizeVec(out: &offset, vertical: areaUp, vec: offset);
67
68 sead::Vector3f offsetAreaPos = areaPos + offset;
69 sead::Vector3f difference = (offsetAreaPos - al::getTrans(actor: mActor));
70
71 shadowLengthArea->getAreaMtx().getBase(o&: groundNormal, axis: 1);
72 groundDistance = difference.length();
73
74 } else if (mIsActive && playerCollider && mOnGroundTimer >= 1) {
75 groundNormal = playerCollider->getCollidedGroundNormal();
76 groundDistance = 0.0f;
77 } else if (mIsActive && !playerCollider && al::isExistActorCollider(mActor) &&
78 al::isOnGround(mActor, 3)) {
79 groundNormal = al::getCollidedGroundNormal(mActor);
80 groundDistance = 0.0f;
81 } else {
82 groundDistance = 1700.0f;
83
84 sead::Vector3f hitPos;
85 sead::Vector3f hitNormal;
86 if (alCollisionUtil::getHitPosAndNormalOnArrow(
87 mActor, &hitPos, &hitNormal, al::getTrans(actor: mActor) + (sead::Vector3f::ey * 100.0f),
88 sead::Vector3f::ey * -1800.0f, nullptr, nullptr)) {
89 if (hitPos.y <= al::getTrans(actor: mActor).y) {
90 const sead::Vector3f& actorTrans = al::getTrans(actor: mActor);
91 groundDistance = actorTrans.y - hitPos.y;
92 groundNormal = hitNormal;
93 }
94 }
95 }
96
97 // 1 for wall, 0 for flat ground
98 f32 tilt = sead::Mathf::clamp(value: 1.0f - groundNormal.dot(t: sead::Vector3f::ey), low: 0.0f, high: 1.0f);
99
100 f32 gradationTargetLength = groundDistance + (tilt * 300.0f);
101 f32 targetLength;
102 if (shadowLengthArea)
103 targetLength = gradationTargetLength + 40.0f;
104 else {
105 gradationTargetLength += mShadowLengthOffset;
106 targetLength = gradationTargetLength * 1.8f;
107 }
108 f32 depthShadowLength = al::getDepthShadowMapLength(actor: mActor, mapName: mShadowMapName);
109 al::setDepthShadowMapLength(
110 actor: mActor, length: depthShadowLength * (1.0f - mLerpLength) + (targetLength * mLerpLength),
111 mapName: mShadowMapName);
112
113 if (al::isEnableDepthShadowMapBottomGradation(actor: mActor, mapName: mShadowMapName)) {
114 f32 currentLength = al::getDepthShadowMapLength(actor: mActor, mapName: mShadowMapName);
115 mGradationLength = ((1.0f - mLerpGradationLength) * mGradationLength) +
116 (gradationTargetLength * mLerpGradationLength);
117
118 al::setDepthShadowMapBottomGradationLength(
119 actor: mActor, mapName: mShadowMapName,
120 length: sead::Mathf::clampMin(val: (currentLength - mGradationLength) - (currentLength * 0.05f),
121 min_: 0.0f));
122 }
123}
124