ksys/world: Implement AnimalMasterController

This commit is contained in:
Léo Lam 2021-05-05 17:41:06 +02:00
parent da65708ded
commit 7bda72574e
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
6 changed files with 128 additions and 7 deletions

View File

@ -89372,7 +89372,7 @@
0x00000071010e7000,wm::TimeMgr::handleNewDay,608,
0x00000071010e7260,nullsub_4540,4,
0x00000071010e7264,wm::TimeMgr::calc,2676,
0x00000071010e7cd8,wm::TimeMgr::AnimalMasterFlags::calc,772,
0x00000071010e7cd8,wm::TimeMgr::AnimalMasterFlags::calc,772,_ZN4ksys5world7TimeMgr22AnimalMasterController4calcEv
0x00000071010e7fdc,wm::TimeMgr::m7_null,4,_ZN4ksys5world7TimeMgr10calcType1_Ev
0x00000071010e7fe0,wm::TimeMgr::m8_null,4,_ZN4ksys5world7TimeMgr10calcType2_Ev
0x00000071010e7fe4,wm::TimeMgr::setNewTime,16,_ZN4ksys5world7TimeMgr23setTimeWithoutDayChecksEf

Can't render this file because it is too large.

View File

@ -102,6 +102,8 @@ public:
bool checkFlag18() const;
bool isPlayerTheConnectedParent() const;
const sead::Vector3f& getPreviousPos() const;
void setThisActorAsParent(BaseProc* child, bool delete_parent_on_delete);
void setThisActorAsChild(BaseProc* parent, bool delete_child_on_delete);

View File

@ -6,6 +6,8 @@
namespace ksys::act {
class ActorConstDataAccess;
// TODO: incomplete
class ActorSystem {
SEAD_SINGLETON_DISPOSER(ActorSystem)
@ -14,6 +16,8 @@ class ActorSystem {
public:
void onBaseProcMgrCalc();
bool getPlayer(ActorConstDataAccess* accessor);
bool getAutoPlacementActorPos(const sead::SafeString& name, sead::Vector3f* pos) const;
sead::Heap* getEmergencyHeap() const { return mEmergencyHeap; }

View File

@ -513,6 +513,11 @@ public:
const al::ByamlIter& getShopSoldOutInfoValues() const { return mShopSoldOutInfoValues; }
const u32* getShopSoldOutInfoHashes() const { return mShopSoldOutInfoHashes; }
void onAnimalMasterAppearance() {
mBitFlags.set(BitFlag::_8);
mResetFlags.set(ResetFlag::AnimalMaster);
}
private:
enum class BitFlag {
_1 = 0x1,
@ -539,7 +544,7 @@ private:
};
enum class ResetFlag {
AnimalMaster = 0x10,
};
struct MethodTreeNode {

View File

@ -1,4 +1,8 @@
#include "KingSystem/World/worldTimeMgr.h"
#include <random/seadGlobalRandom.h>
#include "KingSystem/ActorSystem/actActorConstDataAccess.h"
#include "KingSystem/ActorSystem/actActorSystem.h"
#include "KingSystem/Ecosystem/ecoUtil.h"
#include "KingSystem/GameData/gdtManager.h"
#include "KingSystem/World/worldManager.h"
@ -178,6 +182,103 @@ bool TimeMgr::isInRelicBattle() const {
return in_battle;
}
void TimeMgr::AnimalMasterController::calc() {
const auto num_days = Manager::instance()->getTimeMgr()->getNumberOfDays();
act::ActorConstDataAccess player_accessor;
act::ActorSystem::instance()->getPlayer(&player_accessor);
const int day_of_week = num_days % 7;
switch (state) {
case 0: {
if (Manager::instance()->getTimeMgr()->getMoonType() != MoonType::WaxingCrescent)
break;
bool exists;
if (gdt::Manager::instance() == nullptr)
break;
if (!gdt::Manager::instance()->getBool(existence_flag, &exists, true, true))
break;
if (exists)
break;
if (!player_accessor.hasProc())
break;
if (eco::currentAreaNumIs64(player_accessor.getPreviousPos()))
break;
appearance_hour = sead::GlobalRandom::instance()->getU32(23);
++state;
break;
}
case 1: {
if (!player_accessor.hasProc())
break;
if (eco::currentAreaNumIs64(player_accessor.getPreviousPos())) {
state = 0;
break;
}
int hour = Manager::instance()->getTimeMgr()->getHour();
if (hour != appearance_hour)
break;
hour += 24;
if (hour >= 24)
hour -= 24;
valid_hour = hour;
gdt::Manager::instance()->setBool(true, appearance_flag);
if (gdt::Manager::instance())
gdt::Manager::instance()->onAnimalMasterAppearance();
++state;
break;
}
case 2: {
if (Manager::instance()->getTimeMgr()->getHour() == valid_hour)
break;
start_day_of_week = day_of_week;
++state;
break;
}
case 3: {
u8 dow = day_of_week;
if (dow < start_day_of_week)
dow += 7;
const auto should_disappear = [this, dow](u8 day) {
if (u8(dow - start_day_of_week) >= 2)
return true;
return start_day_of_week != day &&
Manager::instance()->getTimeMgr()->getHour() >= valid_hour;
};
if (!should_disappear(day_of_week))
break;
gdt::Manager::instance()->setBool(false, appearance_flag);
++state;
break;
}
case 4: {
if (Manager::instance()->getTimeMgr()->getMoonType() == MoonType::WaxingCrescent)
break;
state = 0;
break;
}
}
}
void TimeMgr::calcType1_() {}
void TimeMgr::calcType2_() {}

View File

@ -75,6 +75,19 @@ public:
float getTemperatureMultiplier() const;
bool isTimeFlowingNormally() const;
int getTimeDivision() const { return mTimeDivision; }
sead::DelegateEvent<NewDayEvent>& getNewDaySignal() { return mNewDaySignal; }
float getTimeStep() const { return mTimeStep; }
float getBloodMoonTimer() const { return mBloodMoonTimer; }
int getNumberOfDays() const { return mNumberOfDays; }
bool isForceBloodyDay() const { return mForceBloodyDay; }
bool isPlayedDemo103Or997() const { return mPlayedDemo103Or997; }
bool isFindDungeonActivated() const { return mFindDungeonActivated; }
bool isResetGdtOnNextSceneUnloadForBloodMoon() const {
return mResetGdtOnNextSceneUnloadForBloodMoon;
}
bool wasBloodyDay() const { return mWasBloodyDay; }
protected:
void init_(sead::Heap* heap) override;
void calc_() override;
@ -87,10 +100,6 @@ private:
};
struct AnimalMasterController {
enum class State {
};
void calc();
void resetState() {
@ -102,7 +111,7 @@ private:
gdt::FlagHandle appearance_flag = gdt::InvalidHandle;
gdt::FlagHandle existence_flag = gdt::InvalidHandle;
State state{};
int state{};
int appearance_hour{};
int valid_hour{};
u8 start_day_of_week{};