diff --git a/data/odyssey_functions.csv b/data/odyssey_functions.csv index bdf00ee..87e9e71 100644 --- a/data/odyssey_functions.csv +++ b/data/odyssey_functions.csv @@ -26324,23 +26324,23 @@ Address,Quality,Size,Name 0x000000710042d22c,U,000008,_ZNK19PlayerAnimFrameCtrl15getCurrentFrameEv 0x000000710042d234,U,000008,_ZNK19PlayerAnimFrameCtrl7getRateEv 0x000000710042d23c,U,000044,_ZNK19PlayerAnimFrameCtrl11isActionEndEv -0x000000710042d268,U,000008,_ZN17PlayerAreaCheckerC2EPKN2al9LiveActorEPK17PlayerModelHolder -0x000000710042d270,U,000008,_ZNK17PlayerAreaChecker9isInWaterERKN4sead7Vector3IfEE -0x000000710042d278,U,000144,_ZNK17PlayerAreaChecker15isInWaterDoubleERKN4sead7Vector3IfEEf -0x000000710042d308,U,000172,_ZNK17PlayerAreaChecker18isInWaterWallCatchERKN4sead7Vector3IfEEf -0x000000710042d3b4,U,000008,_ZNK17PlayerAreaChecker12isInWaterIceERKN4sead7Vector3IfEE -0x000000710042d3bc,U,000148,_ZNK17PlayerAreaChecker18isInWaterIceDoubleERKN4sead7Vector3IfEEf -0x000000710042d450,U,000036,_ZNK17PlayerAreaChecker7isInWetERKN4sead7Vector3IfEE -0x000000710042d474,U,000036,_ZNK17PlayerAreaChecker8isInRiseERKN4sead7Vector3IfEE -0x000000710042d498,U,000036,_ZNK17PlayerAreaChecker14isInHackCancelERKN4sead7Vector3IfEE -0x000000710042d4bc,U,000068,_ZNK17PlayerAreaChecker12isInRecoveryEPPKN2al7AreaObjERKN4sead7Vector3IfEE -0x000000710042d500,U,000036,_ZNK17PlayerAreaChecker15isInRecoveryBanERKN4sead7Vector3IfEE -0x000000710042d524,U,000036,_ZNK17PlayerAreaChecker16isInWallClimbBanERKN4sead7Vector3IfEE -0x000000710042d548,U,000128,_ZNK17PlayerAreaChecker17isInForceRecoveryEPN4sead7Vector3IfEES3_PPKN2al7AreaObjERKS2_ -0x000000710042d5c8,U,000096,_ZNK17PlayerAreaChecker16isInShadowLengthEPfRKN4sead7Vector3IfEE -0x000000710042d628,U,000036,_ZNK17PlayerAreaChecker12isInCarryBanERKN4sead7Vector3IfEE -0x000000710042d64c,U,000036,_ZNK17PlayerAreaChecker16tryFindStainAreaERKN4sead7Vector3IfEE -0x000000710042d670,U,000036,_ZNK17PlayerAreaChecker26tryFindInvalidateInputFallERKN4sead7Vector3IfEE +0x000000710042d268,O,000008,_ZN17PlayerAreaCheckerC2EPKN2al9LiveActorEPK17PlayerModelHolder +0x000000710042d270,O,000008,_ZNK17PlayerAreaChecker9isInWaterERKN4sead7Vector3IfEE +0x000000710042d278,O,000144,_ZNK17PlayerAreaChecker15isInWaterDoubleERKN4sead7Vector3IfEEf +0x000000710042d308,O,000172,_ZNK17PlayerAreaChecker18isInWaterWallCatchERKN4sead7Vector3IfEEf +0x000000710042d3b4,O,000008,_ZNK17PlayerAreaChecker12isInWaterIceERKN4sead7Vector3IfEE +0x000000710042d3bc,O,000148,_ZNK17PlayerAreaChecker18isInWaterIceDoubleERKN4sead7Vector3IfEEf +0x000000710042d450,O,000036,_ZNK17PlayerAreaChecker7isInWetERKN4sead7Vector3IfEE +0x000000710042d474,O,000036,_ZNK17PlayerAreaChecker8isInRiseERKN4sead7Vector3IfEE +0x000000710042d498,O,000036,_ZNK17PlayerAreaChecker14isInHackCancelERKN4sead7Vector3IfEE +0x000000710042d4bc,O,000068,_ZNK17PlayerAreaChecker12isInRecoveryEPPKN2al7AreaObjERKN4sead7Vector3IfEE +0x000000710042d500,O,000036,_ZNK17PlayerAreaChecker15isInRecoveryBanERKN4sead7Vector3IfEE +0x000000710042d524,O,000036,_ZNK17PlayerAreaChecker16isInWallClimbBanERKN4sead7Vector3IfEE +0x000000710042d548,O,000128,_ZNK17PlayerAreaChecker17isInForceRecoveryEPN4sead7Vector3IfEES3_PPKN2al7AreaObjERKS2_ +0x000000710042d5c8,O,000096,_ZNK17PlayerAreaChecker16isInShadowLengthEPfRKN4sead7Vector3IfEE +0x000000710042d628,O,000036,_ZNK17PlayerAreaChecker12isInCarryBanERKN4sead7Vector3IfEE +0x000000710042d64c,O,000036,_ZNK17PlayerAreaChecker16tryFindStainAreaERKN4sead7Vector3IfEE +0x000000710042d670,O,000036,_ZNK17PlayerAreaChecker26tryFindInvalidateInputFallERKN4sead7Vector3IfEE 0x000000710042d694,U,000156,_ZN24PlayerBindableSensorListC2Ev 0x000000710042d730,U,000092,_ZN24PlayerBindableSensorList5clearEv 0x000000710042d78c,U,000096,_ZN24PlayerBindableSensorList6appendEPN2al9HitSensorEjfi diff --git a/lib/al/Library/Nature/NatureUtil.h b/lib/al/Library/Nature/NatureUtil.h new file mode 100644 index 0000000..71fc4b5 --- /dev/null +++ b/lib/al/Library/Nature/NatureUtil.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +namespace al { +class LiveActor; + +bool isInWaterPos(const LiveActor* actor, const sead::Vector3f& pos); +bool isInIceWaterPos(const LiveActor* actor, const sead::Vector3f& pos); + +} // namespace al diff --git a/src/Player/PlayerAreaChecker.cpp b/src/Player/PlayerAreaChecker.cpp new file mode 100644 index 0000000..65566f2 --- /dev/null +++ b/src/Player/PlayerAreaChecker.cpp @@ -0,0 +1,93 @@ +#include "Player/PlayerAreaChecker.h" + +#include "Library/Area/AreaObjUtil.h" +#include "Library/LiveActor/ActorPoseKeeper.h" +#include "Library/LiveActor/LiveActor.h" +#include "Library/Nature/NatureUtil.h" + +#include "System/GameDataHolderAccessor.h" +#include "Util/Area.h" +#include "Util/ObjUtil.h" + +PlayerAreaChecker::PlayerAreaChecker(const al::LiveActor* player, + const PlayerModelHolder* modelHolder) + : mPlayer(player), mModelHolder(modelHolder) {} + +bool PlayerAreaChecker::isInWater(const sead::Vector3f& pos) const { + return al::isInWaterPos(mPlayer, pos); +} + +bool PlayerAreaChecker::isInWaterDouble(const sead::Vector3f& pos, f32 gravityFactor) const { + return isInWater(pos) || isInWater(pos - al::getGravity(mPlayer) * gravityFactor); +} + +bool PlayerAreaChecker::isInWaterWallCatch(const sead::Vector3f& pos, f32 gravityFactor) const { + sead::Vector3f rootOffset = {0.0f, 0.0f, 0.0f}; + rs::calcOffsetAllRoot(&rootOffset, mModelHolder); + return isInWater(pos + rootOffset - al::getGravity(mPlayer) * gravityFactor); +} + +bool PlayerAreaChecker::isInWaterIce(const sead::Vector3f& pos) const { + return al::isInIceWaterPos(mPlayer, pos); +} + +bool PlayerAreaChecker::isInWaterIceDouble(const sead::Vector3f& pos, f32 gravityFactor) const { + // second one must be written like this to match + return isInWaterIce(pos) || + al::isInIceWaterPos(mPlayer, pos - al::getGravity(mPlayer) * gravityFactor); +} + +bool PlayerAreaChecker::isInWet(const sead::Vector3f& pos) const { + return al::isInAreaObj(mPlayer, "WetArea", pos); +} + +bool PlayerAreaChecker::isInRise(const sead::Vector3f& pos) const { + return al::isInAreaObj(mPlayer, "RiseArea", pos); +} + +bool PlayerAreaChecker::isInHackCancel(const sead::Vector3f& pos) const { + return al::isInAreaObj(mPlayer, "HackCancelArea", pos); +} + +bool PlayerAreaChecker::isInRecovery(const al::AreaObj** area, const sead::Vector3f& pos) const { + const al::AreaObj* recoveryArea = al::tryFindAreaObj(mPlayer, "RecoveryArea", pos); + if (recoveryArea) { + *area = recoveryArea; + return true; + } + return false; +} + +bool PlayerAreaChecker::isInRecoveryBan(const sead::Vector3f& pos) const { + return al::isInAreaObj(mPlayer, "RecoveryBanArea", pos); +} + +bool PlayerAreaChecker::isInWallClimbBan(const sead::Vector3f& pos) const { + return al::isInAreaObj(mPlayer, "InvalidateWallClimbArea", pos); +} + +bool PlayerAreaChecker::isInForceRecovery(sead::Vector3f* targetPos, sead::Vector3f* targetUp, + const al::AreaObj** area, + const sead::Vector3f& pos) const { + return rs::isKidsMode(mPlayer) && + rs::tryFindForceRecoveryArea(targetPos, targetUp, area, mPlayer, pos); +} + +bool PlayerAreaChecker::isInShadowLength(f32* shadowLength, const sead::Vector3f& pos) const { + const al::AreaObj* shadowArea = al::tryFindAreaObj(mPlayer, "PlayerShadowLengthArea", pos); + if (shadowArea) + return al::tryGetAreaObjArg(shadowLength, shadowArea, "ShadowLength"); + return false; +} + +bool PlayerAreaChecker::isInCarryBan(const sead::Vector3f& pos) const { + return al::isInAreaObj(mPlayer, "CarryBanArea", pos); +} + +const al::AreaObj* PlayerAreaChecker::tryFindStainArea(const sead::Vector3f& pos) const { + return al::tryFindAreaObj(mPlayer, "StainArea", pos); +} + +const al::AreaObj* PlayerAreaChecker::tryFindInvalidateInputFall(const sead::Vector3f& pos) const { + return al::tryFindAreaObj(mPlayer, "InvalidateInputFallArea", pos); +} diff --git a/src/Player/PlayerAreaChecker.h b/src/Player/PlayerAreaChecker.h new file mode 100644 index 0000000..0dfc005 --- /dev/null +++ b/src/Player/PlayerAreaChecker.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +namespace al { +class LiveActor; +class AreaObj; +} // namespace al +class PlayerModelHolder; + +class PlayerAreaChecker { +public: + PlayerAreaChecker(const al::LiveActor* player, const PlayerModelHolder* modelHolder); + bool isInWater(const sead::Vector3f& pos) const; + bool isInWaterDouble(const sead::Vector3f& pos, f32 gravityFactor) const; + bool isInWaterWallCatch(const sead::Vector3f& pos, f32 gravityFactor) const; + bool isInWaterIce(const sead::Vector3f& pos) const; + bool isInWaterIceDouble(const sead::Vector3f& pos, f32 gravityFactor) const; + bool isInWet(const sead::Vector3f& pos) const; + bool isInRise(const sead::Vector3f& pos) const; + bool isInHackCancel(const sead::Vector3f& pos) const; + bool isInRecovery(const al::AreaObj** area, const sead::Vector3f& pos) const; + bool isInRecoveryBan(const sead::Vector3f& pos) const; + bool isInWallClimbBan(const sead::Vector3f& pos) const; + bool isInForceRecovery(sead::Vector3f* targetPos, sead::Vector3f* targetUp, + const al::AreaObj** area, const sead::Vector3f& pos) const; + bool isInShadowLength(f32* shadowLength, const sead::Vector3f& pos) const; + bool isInCarryBan(const sead::Vector3f& pos) const; + const al::AreaObj* tryFindStainArea(const sead::Vector3f& pos) const; + const al::AreaObj* tryFindInvalidateInputFall(const sead::Vector3f& pos) const; + +private: + const al::LiveActor* mPlayer; + const PlayerModelHolder* mModelHolder; +}; + +static_assert(sizeof(PlayerAreaChecker) == 0x10); diff --git a/src/System/GameDataHolderAccessor.h b/src/System/GameDataHolderAccessor.h index 44da300..f91ca8d 100644 --- a/src/System/GameDataHolderAccessor.h +++ b/src/System/GameDataHolderAccessor.h @@ -16,5 +16,6 @@ public: }; namespace rs { -bool isInvalidChangeStage(const al::LiveActor*); -} +bool isInvalidChangeStage(const al::LiveActor* actor); +bool isKidsMode(const al::LiveActor* actor); +} // namespace rs diff --git a/src/Util/Area.h b/src/Util/Area.h index fff244f..db3b26e 100644 --- a/src/Util/Area.h +++ b/src/Util/Area.h @@ -4,8 +4,13 @@ namespace al { class LiveActor; +class AreaObj; +class IUseAreaObj; } // namespace al namespace rs { -bool isInChangeStageArea(const al::LiveActor*, const sead::Vector3f*); +bool isInChangeStageArea(const al::LiveActor* actor, const sead::Vector3f* pos); +bool tryFindForceRecoveryArea(sead::Vector3f* targetPos, sead::Vector3f* targetUp, + const al::AreaObj** area, const al::IUseAreaObj* obj, + const sead::Vector3f& pos); } // namespace rs diff --git a/src/Util/ObjUtil.h b/src/Util/ObjUtil.h index f699dd4..5c5e2d5 100644 --- a/src/Util/ObjUtil.h +++ b/src/Util/ObjUtil.h @@ -6,6 +6,7 @@ namespace al { class CollisionParts; class LiveActor; } // namespace al +class PlayerModelHolder; namespace rs { @@ -21,4 +22,6 @@ bool findGrabCeilPosWallHit(const al::CollisionParts**, sead::Vector3f*, sead::V sead::Vector3f*, const al::LiveActor*, const sead::Vector3f&, const sead::Vector3f&, f32, f32, f32); +void calcOffsetAllRoot(sead::Vector3f* offset, const PlayerModelHolder* model); + } // namespace rs