1#include "Player/PlayerAreaChecker.h"
2
3#include "Library/Area/AreaObjUtil.h"
4#include "Library/LiveActor/ActorPoseUtil.h"
5#include "Library/LiveActor/LiveActor.h"
6#include "Library/Nature/NatureUtil.h"
7
8#include "System/GameDataUtil.h"
9#include "Util/AreaUtil.h"
10#include "Util/ObjUtil.h"
11
12PlayerAreaChecker::PlayerAreaChecker(const al::LiveActor* player,
13 const PlayerModelHolder* modelHolder)
14 : mPlayer(player), mModelHolder(modelHolder) {}
15
16bool PlayerAreaChecker::isInWater(const sead::Vector3f& pos) const {
17 return al::isInWaterPos(mPlayer, pos);
18}
19
20bool PlayerAreaChecker::isInWaterDouble(const sead::Vector3f& pos, f32 gravityFactor) const {
21 return isInWater(pos) || isInWater(pos: pos - al::getGravity(actor: mPlayer) * gravityFactor);
22}
23
24bool PlayerAreaChecker::isInWaterWallCatch(const sead::Vector3f& pos, f32 gravityFactor) const {
25 sead::Vector3f rootOffset = {0.0f, 0.0f, 0.0f};
26 rs::calcOffsetAllRoot(offset: &rootOffset, model: mModelHolder);
27 return isInWater(pos: pos + rootOffset - al::getGravity(actor: mPlayer) * gravityFactor);
28}
29
30bool PlayerAreaChecker::isInWaterIce(const sead::Vector3f& pos) const {
31 return al::isInIceWaterPos(mPlayer, pos);
32}
33
34bool PlayerAreaChecker::isInWaterIceDouble(const sead::Vector3f& pos, f32 gravityFactor) const {
35 // second one must be written like this to match
36 return isInWaterIce(pos) ||
37 al::isInIceWaterPos(mPlayer, pos - al::getGravity(actor: mPlayer) * gravityFactor);
38}
39
40bool PlayerAreaChecker::isInWet(const sead::Vector3f& pos) const {
41 return al::isInAreaObj(areaUser: mPlayer, name: "WetArea", position: pos);
42}
43
44bool PlayerAreaChecker::isInRise(const sead::Vector3f& pos) const {
45 return al::isInAreaObj(areaUser: mPlayer, name: "RiseArea", position: pos);
46}
47
48bool PlayerAreaChecker::isInHackCancel(const sead::Vector3f& pos) const {
49 return al::isInAreaObj(areaUser: mPlayer, name: "HackCancelArea", position: pos);
50}
51
52bool PlayerAreaChecker::isInRecovery(const al::AreaObj** area, const sead::Vector3f& pos) const {
53 const al::AreaObj* recoveryArea = al::tryFindAreaObj(areaUser: mPlayer, name: "RecoveryArea", position: pos);
54 if (recoveryArea) {
55 *area = recoveryArea;
56 return true;
57 }
58 return false;
59}
60
61bool PlayerAreaChecker::isInRecoveryBan(const sead::Vector3f& pos) const {
62 return al::isInAreaObj(areaUser: mPlayer, name: "RecoveryBanArea", position: pos);
63}
64
65bool PlayerAreaChecker::isInWallClimbBan(const sead::Vector3f& pos) const {
66 return al::isInAreaObj(areaUser: mPlayer, name: "InvalidateWallClimbArea", position: pos);
67}
68
69bool PlayerAreaChecker::isInForceRecovery(sead::Vector3f* targetPos, sead::Vector3f* targetUp,
70 const al::AreaObj** area,
71 const sead::Vector3f& pos) const {
72 return rs::isKidsMode(actor: mPlayer) &&
73 rs::tryFindForceRecoveryArea(targetPos, targetRotate: targetUp, area, user: mPlayer, trans: pos);
74}
75
76bool PlayerAreaChecker::isInShadowLength(f32* shadowLength, const sead::Vector3f& pos) const {
77 const al::AreaObj* shadowArea = al::tryFindAreaObj(areaUser: mPlayer, name: "PlayerShadowLengthArea", position: pos);
78 if (shadowArea)
79 return al::tryGetAreaObjArg(outArg: shadowLength, areaObj: shadowArea, key: "ShadowLength");
80 return false;
81}
82
83bool PlayerAreaChecker::isInCarryBan(const sead::Vector3f& pos) const {
84 return al::isInAreaObj(areaUser: mPlayer, name: "CarryBanArea", position: pos);
85}
86
87const al::AreaObj* PlayerAreaChecker::tryFindStainArea(const sead::Vector3f& pos) const {
88 return al::tryFindAreaObj(areaUser: mPlayer, name: "StainArea", position: pos);
89}
90
91const al::AreaObj* PlayerAreaChecker::tryFindInvalidateInputFall(const sead::Vector3f& pos) const {
92 return al::tryFindAreaObj(areaUser: mPlayer, name: "InvalidateInputFallArea", position: pos);
93}
94