summaryrefslogtreecommitdiff
path: root/src/Game/Actor/Player
diff options
context:
space:
mode:
Diffstat (limited to 'src/Game/Actor/Player')
-rw-r--r--src/Game/Actor/Player/CMakeLists.txt9
-rw-r--r--src/Game/Actor/Player/actPlayerBase.cpp1
-rw-r--r--src/Game/Actor/Player/actPlayerBase.h19
-rw-r--r--src/Game/Actor/Player/actPlayerInfo.cpp134
-rw-r--r--src/Game/Actor/Player/actPlayerInfo.h123
-rw-r--r--src/Game/Actor/Player/actPlayerInfoBase.cpp6
-rw-r--r--src/Game/Actor/Player/actPlayerInfoStub.cpp19
7 files changed, 311 insertions, 0 deletions
diff --git a/src/Game/Actor/Player/CMakeLists.txt b/src/Game/Actor/Player/CMakeLists.txt
index 3632c164..f1b9b94e 100644
--- a/src/Game/Actor/Player/CMakeLists.txt
+++ b/src/Game/Actor/Player/CMakeLists.txt
@@ -1,2 +1,11 @@
add_subdirectory(AI)
add_subdirectory(Action)
+
+target_sources(uking PRIVATE
+ actPlayerBase.cpp
+ actPlayerBase.h
+ actPlayerInfo.cpp
+ actPlayerInfo.h
+ actPlayerInfoBase.cpp
+ actPlayerInfoStub.cpp
+)
diff --git a/src/Game/Actor/Player/actPlayerBase.cpp b/src/Game/Actor/Player/actPlayerBase.cpp
new file mode 100644
index 00000000..fcfa6d14
--- /dev/null
+++ b/src/Game/Actor/Player/actPlayerBase.cpp
@@ -0,0 +1 @@
+#include "Game/Actor/Player/actPlayerBase.h"
diff --git a/src/Game/Actor/Player/actPlayerBase.h b/src/Game/Actor/Player/actPlayerBase.h
new file mode 100644
index 00000000..8ff7b867
--- /dev/null
+++ b/src/Game/Actor/Player/actPlayerBase.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include <prim/seadSafeString.h>
+#include "KingSystem/ActorSystem/actActor.h"
+
+namespace uking::act {
+
+// TODO
+class PlayerBase : public ksys::act::Actor {
+public:
+ // FIXME: name for x and name+type for y
+ void switchEquipment(const sead::SafeString& slot, int frames, int x = -1,
+ const uintptr_t& y = {});
+
+ // FIXME: name for x
+ void setExtraLife(s32 extra_life, f32 x);
+};
+
+} // namespace uking::act
diff --git a/src/Game/Actor/Player/actPlayerInfo.cpp b/src/Game/Actor/Player/actPlayerInfo.cpp
new file mode 100644
index 00000000..ec44523f
--- /dev/null
+++ b/src/Game/Actor/Player/actPlayerInfo.cpp
@@ -0,0 +1,134 @@
+#include "Game/Actor/Player/actPlayerInfo.h"
+#include "Game/Actor/Player/actPlayerBase.h"
+#include "KingSystem/ActorSystem/actActorConstDataAccess.h"
+#include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h"
+#include "KingSystem/ActorSystem/actBaseProc.h"
+#include "KingSystem/ActorSystem/actBaseProcMgr.h"
+#include "KingSystem/GameData/gdtCommonFlagsUtils.h"
+#include "KingSystem/ksys.h"
+
+namespace uking::act {
+
+SEAD_SINGLETON_DISPOSER_IMPL(PlayerInfo)
+
+PlayerInfo::PlayerInfo() = default;
+PlayerInfo::~PlayerInfo() = default;
+
+bool PlayerInfo::init() {
+ return true;
+}
+
+void PlayerInfo::resetPlayer(PlayerBase* player) {
+ if (mPlayerActor == player) {
+ mPlayerActor = nullptr;
+ ksys::setPlayerLink(nullptr);
+ }
+}
+
+bool PlayerInfo::acquireHorse(ksys::act::BaseProc* horse) {
+ return mHorseLink.acquire(horse, false);
+}
+
+void PlayerInfo::setHorseLink(const ksys::act::BaseProcLink& horse_link) {
+ mHorseLink = horse_link;
+}
+
+PlayerBase* PlayerInfo::getPlayer() const {
+ if (!mPlayerActor) {
+ return nullptr;
+ }
+ ksys::act::BaseProcMgr::instance()->isAccessingProcSafe(mPlayerActor, nullptr);
+ return mPlayerActor;
+}
+
+PlayerBase* PlayerInfo::getPlayer_() const {
+ if (!mPlayerActor) {
+ return nullptr;
+ }
+ ksys::act::BaseProcMgr::instance()->isAccessingProcSafe(mPlayerActor, nullptr);
+ return mPlayerActor;
+}
+
+s32 PlayerInfo::getMaxLifeFromPlayerActor() const {
+ return mPlayerActor ? mPlayerActor->getMaxLife() : 0;
+}
+
+void PlayerInfo::setMaxHeartValue(s32 quarter_hearts) {
+ ksys::gdt::setFlag_MaxHartValue(quarter_hearts);
+ mMaxHeartValue = static_cast<f32>(quarter_hearts);
+}
+
+u32 PlayerInfo::getMaxHeartValue() const {
+ // Return type is unsigned, but the conversion is signed
+ return static_cast<s32>(mMaxHeartValue);
+}
+
+void PlayerInfo::updateMaxHeartValueFromGameData() {
+ mMaxHeartValue = static_cast<f32>(ksys::gdt::getFlag_MaxHartValue());
+}
+
+void PlayerInfo::setLifeForPlayerActor(s32 life) {
+ if (mPlayerActor) {
+ *mPlayerActor->getLife() = life;
+ }
+}
+
+s32 PlayerInfo::getLifeFromPlayerActor() const {
+ if (!mPlayerActor) {
+ return 0;
+ }
+ auto* life = mPlayerActor->getLife();
+ return life ? *life : 1;
+}
+
+void PlayerInfo::recoverLife() {
+ setLifeForPlayerActor(getMaxLifeFromPlayerActor());
+}
+
+void PlayerInfo::setStaminaCurrentMax(f32 max_stamina) {
+ ksys::gdt::setFlag_StaminaCurrentMax(max_stamina);
+ mStaminaCurrentMax = max_stamina;
+}
+
+f32 PlayerInfo::getStaminaCurrentMax() const {
+ return mStaminaCurrentMax;
+}
+
+void PlayerInfo::updateStaminaCurrentMaxFromGameData() {
+ mStaminaCurrentMax = ksys::gdt::getFlag_StaminaCurrentMax();
+}
+
+void PlayerInfo::setStaminaMax(f32 max_stamina) {
+ ksys::gdt::setFlag_StaminaMax(max_stamina);
+ mStaminaMax = max_stamina;
+}
+
+f32 PlayerInfo::getStaminaMax() const {
+ return mStaminaMax;
+}
+
+void PlayerInfo::updateStaminaMaxFromGameData() {
+ mStaminaMax = ksys::gdt::getFlag_StaminaMax();
+}
+
+PlayerBase* PlayerInfo::getPlayerUnchecked() {
+ return mPlayerActor;
+}
+
+sead::Vector3f& PlayerInfo::getPlayerPos() {
+ ksys::act::ActorConstDataAccess accessor;
+
+ ksys::act::acquireActor(&mPlayerLink, &accessor);
+ accessor.debugLog(1, "getPlayerPos");
+ return mPlayerPos;
+}
+
+sead::Vector3f& PlayerInfo::getPlayerPosForPostCalc() {
+ ksys::act::ActorConstDataAccess accessor;
+
+ ksys::act::acquireActor(&mPlayerLink, &accessor);
+ accessor.debugLog(0, "getPlayerPosForPostCalc");
+ return mPlayerPosForPostCalc;
+}
+
+} // namespace uking::act
diff --git a/src/Game/Actor/Player/actPlayerInfo.h b/src/Game/Actor/Player/actPlayerInfo.h
new file mode 100644
index 00000000..ee281d58
--- /dev/null
+++ b/src/Game/Actor/Player/actPlayerInfo.h
@@ -0,0 +1,123 @@
+#pragma once
+
+#include <heap/seadDisposer.h>
+#include <math/seadVector.h>
+#include "KingSystem/ActorSystem/actBaseProcLink.h"
+#include "container/seadRingBuffer.h"
+
+namespace ksys::act {
+class Actor;
+}
+
+namespace uking::act {
+
+class PlayerBase;
+
+class PlayerInfoBase {
+public:
+ PlayerInfoBase();
+ virtual ~PlayerInfoBase();
+};
+
+class PlayerInfo : public PlayerInfoBase {
+ SEAD_SINGLETON_DISPOSER(PlayerInfo)
+ PlayerInfo();
+ ~PlayerInfo() override;
+
+public:
+ ksys::act::BaseProcLink& getPlayerLink() { return mPlayerLink; }
+ bool init();
+ void setAndAcquirePlayer(PlayerBase* player); // requires PlayerOrEnemy and PlayerBase
+ void resetPlayer(PlayerBase* player);
+ bool acquireHorse(ksys::act::BaseProc* horse);
+ void setHorseLink(const ksys::act::BaseProcLink& horse_link);
+ PlayerBase* getPlayer() const;
+ PlayerBase* getPlayer_() const; // possibly duped by compiler?
+ ksys::act::Actor* getRiddenHorse() const; // requires PlayerBase vtable
+ void setMaxLifeForPlayerActor(s32 max_heart); // requires PlayerBase
+ s32 getMaxLifeFromPlayerActor() const;
+ void setMaxHeartValue(s32 quarter_hearts);
+ u32 getMaxHeartValue() const;
+ void updateMaxHeartValueFromGameData();
+ void setLifeForPlayerActor(s32 life);
+ s32 getLifeFromPlayerActor() const;
+ void updateCurrentHartFlagFromPlayerActor(); // TODO
+ void updateLifeAfterGameOver(); // requires a global flag
+ void
+ resetLifeToBeforeSwordPull(); // requires HeartDisplayMgr (0x25D6578) and PlayerBase vtable
+ void saveLifeInfoForSwordPull(); // requires PlayerBase vtable
+ void recoverLife();
+ void setStaminaCurrentMax(f32 max_stamina);
+ f32 getStaminaCurrentMax() const;
+ void updateStaminaCurrentMaxFromGameData();
+ void setStaminaMax(f32 max_stamina);
+ f32 getStaminaMax() const;
+ void updateStaminaMaxFromGameData();
+ void setMaxStaminaForPlayerActor(f32 max_stamina); // requires PlayerBase
+ f32 getMaxStaminaFromPlayerActor() const; // requires PlayerBase
+ void recoverStamina(); // requires PlayerBase
+ void recoverCondition(); // requires PlayerBase
+
+ PlayerBase* getPlayerUnchecked();
+
+ sead::Vector3f& getPlayerPos();
+ sead::Vector3f& getPlayerPosForPostCalc();
+
+ // TODO: name and PlayerBase vtable
+ sead::Vector3f& getPlayerM265();
+
+private:
+ // These are probably debug stuff that were removed
+ class Info1 : public PlayerInfoBase {
+ public:
+ Info1();
+ ~Info1() override;
+ } mInfo1;
+ class Info2 : public PlayerInfoBase {
+ public:
+ Info2();
+ ~Info2() override;
+ } mInfo2;
+ class Info3 : public PlayerInfoBase {
+ public:
+ Info3();
+ ~Info3() override;
+ } mInfo3;
+ class Info4 : public PlayerInfoBase {
+ public:
+ Info4();
+ ~Info4() override;
+ } mInfo4;
+ class Info5 : public PlayerInfoBase {
+ public:
+ Info5();
+ ~Info5() override;
+ } mInfo5;
+ class Info6 : public PlayerInfoBase {
+ public:
+ Info6();
+ ~Info6() override;
+ } mInfo6;
+ class Info7 : public PlayerInfoBase {
+ public:
+ Info7();
+ ~Info7() override;
+ } mInfo7;
+ PlayerBase* mPlayerActor = nullptr;
+ ksys::act::BaseProcLink mPlayerLink;
+ ksys::act::BaseProcLink mHorseLink;
+ sead::Vector3f mPlayerPos{0, 0, 0};
+ sead::Vector3f mPlayerPosForPostCalc{0, 0, 0};
+ f32 mMaxHeartValue = 0;
+ f32 mStaminaCurrentMax = 1000; // 1000 = 1 wheel
+ f32 mStaminaMax = 1000;
+ f32 mLifeBeforeSwordPull = 0;
+ f32 mExtraLifeBeforeSwordPull = 0;
+ sead::FixedRingBuffer<sead::Vector3f, 60> mPreviousPositions;
+ f32 _3a0 = 65535;
+ f32 _3a4 = 65535;
+ f32 _3a8 = -1;
+};
+KSYS_CHECK_SIZE_NX150(PlayerInfo, 0x3B0);
+
+} // namespace uking::act
diff --git a/src/Game/Actor/Player/actPlayerInfoBase.cpp b/src/Game/Actor/Player/actPlayerInfoBase.cpp
new file mode 100644
index 00000000..9972fb0f
--- /dev/null
+++ b/src/Game/Actor/Player/actPlayerInfoBase.cpp
@@ -0,0 +1,6 @@
+#include "Game/Actor/Player/actPlayerInfo.h"
+namespace uking::act {
+// these are separate from actPlayerInfo.cpp so clang doesn't inline/dedupe them
+[[gnu::noinline]] PlayerInfoBase::PlayerInfoBase() = default;
+[[gnu::noinline]] PlayerInfoBase::~PlayerInfoBase() = default;
+} // namespace uking::act
diff --git a/src/Game/Actor/Player/actPlayerInfoStub.cpp b/src/Game/Actor/Player/actPlayerInfoStub.cpp
new file mode 100644
index 00000000..e79c0ea3
--- /dev/null
+++ b/src/Game/Actor/Player/actPlayerInfoStub.cpp
@@ -0,0 +1,19 @@
+#include "Game/Actor/Player/actPlayerInfo.h"
+namespace uking::act {
+// these are separate from actPlayerInfo.cpp so clang doesn't inline/dedupe them
+PlayerInfo::Info1::Info1() = default;
+PlayerInfo::Info1::~Info1() = default;
+PlayerInfo::Info2::Info2() = default;
+PlayerInfo::Info2::~Info2() = default;
+PlayerInfo::Info3::Info3() = default;
+PlayerInfo::Info3::~Info3() = default;
+PlayerInfo::Info4::Info4() = default;
+PlayerInfo::Info4::~Info4() = default;
+PlayerInfo::Info5::Info5() = default;
+PlayerInfo::Info5::~Info5() = default;
+PlayerInfo::Info6::Info6() = default;
+PlayerInfo::Info6::~Info6() = default;
+PlayerInfo::Info7::Info7() = default;
+PlayerInfo::Info7::~Info7() = default;
+
+} // namespace uking::act