mirror of
https://github.com/zeldaret/botw
synced 2026-09-06 18:51:07 -04:00
ksys::qst begin
This commit is contained in:
@@ -12,6 +12,7 @@ add_subdirectory(Framework)
|
||||
add_subdirectory(Map)
|
||||
add_subdirectory(Mii)
|
||||
add_subdirectory(Physics)
|
||||
add_subdirectory(Quest)
|
||||
add_subdirectory(Sound)
|
||||
add_subdirectory(System)
|
||||
add_subdirectory(Terrain)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
target_sources(uking PRIVATE
|
||||
qstActorData.cpp
|
||||
qstActorData.h
|
||||
qstIndicator.cpp
|
||||
qstIndicator.h
|
||||
qstManager.cpp
|
||||
qstManager.h
|
||||
qstQuest.cpp
|
||||
qstQuest.h
|
||||
qstStep.cpp
|
||||
qstStep.h
|
||||
)
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "KingSystem/Quest/qstActorData.h"
|
||||
#include "KingSystem/Utils/Byaml/Byaml.h"
|
||||
|
||||
namespace ksys::qst {
|
||||
|
||||
CameraTarget::~CameraTarget() = default;
|
||||
|
||||
ActorData::ActorData(sead::Heap* heap) {
|
||||
this->heap = heap;
|
||||
}
|
||||
|
||||
ActorData::~ActorData() {
|
||||
for (int i = 0; i < targets.size(); ++i) {
|
||||
/// @bug The object is destructed twice (UB).
|
||||
std::destroy_at(targets[i]);
|
||||
delete targets[i];
|
||||
}
|
||||
targets.freeBuffer();
|
||||
}
|
||||
|
||||
bool ActorData::init(al::ByamlIter* iter, sead::BufferedSafeString* out_message) {
|
||||
if (iter == nullptr)
|
||||
return true;
|
||||
|
||||
sead::FixedSafeString<16> key("CameraTargets");
|
||||
al::ByamlIter target_iter;
|
||||
|
||||
if (!iter->tryGetIterByKey(&target_iter, key.cstr()))
|
||||
return true;
|
||||
|
||||
if (!targets.tryAllocBuffer(target_iter.getSize(), heap)) {
|
||||
// Failed to setup photo target storage buffer. (Insufficient memory?)
|
||||
out_message->format("写真対象格納バッファの設定に失敗しました。(メモリ不足?)");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < target_iter.getSize(); ++i) {
|
||||
const char* string = nullptr;
|
||||
bool result = target_iter.tryGetStringByIndex(&string, i);
|
||||
|
||||
if (string == nullptr || !result) {
|
||||
// Failed to get the photo target (%d).
|
||||
out_message->format("写真対象(%d)の取得に失敗しました。", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* target = new (heap, std::nothrow_t()) CameraTarget();
|
||||
if (target == nullptr) {
|
||||
// Failed to allocate photo target information (%d).
|
||||
out_message->format("写真対象情報(%d)の生成に失敗しました。");
|
||||
return false;
|
||||
}
|
||||
|
||||
target->enabled = false;
|
||||
target->name = string;
|
||||
targets.pushBack(target);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const CameraTarget* ActorData::getTarget(int idx) const {
|
||||
if (targets.size() < 1 || idx < 0 || idx >= targets.size())
|
||||
return nullptr;
|
||||
return targets[idx];
|
||||
}
|
||||
|
||||
void ActorData::disableAllTargets() {
|
||||
for (int i = 0; i < targets.size(); ++i)
|
||||
targets[i]->enabled = false;
|
||||
}
|
||||
|
||||
void ActorData::enableAllTargets() {
|
||||
for (int i = 0; i < targets.size(); ++i) {
|
||||
targets[i]->enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ksys::qst
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <container/seadPtrArray.h>
|
||||
#include <heap/seadHeap.h>
|
||||
#include <prim/seadSafeString.h>
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
|
||||
namespace al {
|
||||
class ByamlIter;
|
||||
}
|
||||
|
||||
namespace ksys::qst {
|
||||
|
||||
struct CameraTarget {
|
||||
virtual ~CameraTarget();
|
||||
bool enabled;
|
||||
sead::SafeString name;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(CameraTarget, 0x20);
|
||||
|
||||
struct ActorData {
|
||||
ActorData(sead::Heap* heap);
|
||||
virtual ~ActorData();
|
||||
|
||||
bool init(al::ByamlIter* iter, sead::BufferedSafeString* out_message);
|
||||
const CameraTarget* getTarget(int idx) const;
|
||||
void disableAllTargets();
|
||||
void enableAllTargets();
|
||||
|
||||
sead::PtrArray<CameraTarget> targets;
|
||||
sead::Heap* heap;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(ActorData, 0x20);
|
||||
|
||||
} // namespace ksys::qst
|
||||
@@ -0,0 +1,194 @@
|
||||
#include "KingSystem/Quest/qstIndicator.h"
|
||||
#include "KingSystem/Quest/qstStep.h"
|
||||
|
||||
namespace ksys::qst {
|
||||
|
||||
Indicator::Indicator(Step* step, sead::Heap* heap) {
|
||||
this->heap = heap;
|
||||
this->step = step;
|
||||
}
|
||||
|
||||
Indicator::~Indicator() {
|
||||
finalize();
|
||||
}
|
||||
|
||||
// NON_MATCHING: Confusing control flow
|
||||
bool Indicator::init(al::ByamlIter* iter, sead::BufferedSafeString* out_message) {
|
||||
if (!iter->isValid()) {
|
||||
// Step (%s) is invalid data.
|
||||
out_message->format("ステップ(%s)は無効なデータです。", step->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
sead::FixedSafeString<32> actor_key("IndicatorActors");
|
||||
sead::FixedSafeString<32> param_key("");
|
||||
al::ByamlIter actor_iter;
|
||||
if (iter->tryGetIterByKey(&actor_iter, actor_key.cstr())) {
|
||||
if (!actor_iter.isValid()) {
|
||||
// Parameter [%s] for step (%s) is invalid data.
|
||||
out_message->format("ステップ(%s)のパラメータ [%s] は無効なデータです。", step->name,
|
||||
actor_key.cstr());
|
||||
return false;
|
||||
}
|
||||
|
||||
int size = actor_iter.getSize();
|
||||
if (size >= 1) {
|
||||
if (!actors.tryAllocBuffer(size, heap, 8)) {
|
||||
// Failed to set the actor indicator storage buffer for step (%s). (Insufficient
|
||||
// memory?)
|
||||
out_message->format(
|
||||
"ステップ(%s)のアクター光点格納バッファの設定に失敗しました。(メモリ不足?)",
|
||||
step->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
al::ByamlIter param_iter;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (!actor_iter.tryGetIterByIndex(¶m_iter, i)) {
|
||||
// Failed to get the actor indicator (%d) for step (%s).
|
||||
out_message->format("ステップ(%s)のアクター光点(%d)の取得に失敗しました。",
|
||||
step->name, i);
|
||||
return false;
|
||||
}
|
||||
if (!param_iter.isValid()) {
|
||||
// Actor indicator (%d) in step (%s) is invalid data.
|
||||
out_message->format("ステップ(%s)のアクター光点(%d)は無効なデータです。",
|
||||
step->name, i);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool has_far = false;
|
||||
const char* instance_name = &sead::SafeString::cNullChar;
|
||||
sead::Vector3f location = sead::Vector3f::zero;
|
||||
const char* name = &sead::SafeString::cNullChar;
|
||||
const char* off_flag = &sead::SafeString::cNullChar;
|
||||
bool is_remains = false;
|
||||
|
||||
param_key.format("HasFar");
|
||||
if (!param_iter.tryGetBoolByKey(&has_far, param_key.cstr())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
param_key.format("InstanceName");
|
||||
if (!param_iter.tryGetStringByKey(&instance_name, param_key.cstr())) {
|
||||
// Failed to get parameter [%s] of actor indicator (%d) for step (%s).
|
||||
out_message->format(
|
||||
"ステップ(%s)のアクター光点(%d)のパラメータ [%s] の取得に失敗しました。",
|
||||
step->name, i, param_key.cstr());
|
||||
break;
|
||||
}
|
||||
|
||||
param_key.format("Location");
|
||||
if (!al::tryGetByamlV3f(&location, param_iter, param_key.cstr())) {
|
||||
// Failed to get parameter [%s] of actor indicator (%d) for step (%s).
|
||||
out_message->format(
|
||||
"ステップ(%s)のアクター光点(%d)のパラメータ [%s] の取得に失敗しました。",
|
||||
step->name, i, param_key.cstr());
|
||||
break;
|
||||
}
|
||||
|
||||
param_key.format("Name");
|
||||
if (!param_iter.tryGetStringByKey(&name, param_key.cstr())) {
|
||||
// Failed to get parameter [%s] of actor indicator (%d) for step (%s).
|
||||
out_message->format(
|
||||
"ステップ(%s)のアクター光点(%d)のパラメータ [%s] の取得に失敗しました。",
|
||||
step->name, i, param_key.cstr());
|
||||
break;
|
||||
}
|
||||
|
||||
param_key.format("OffFlag");
|
||||
if (!param_iter.tryGetStringByKey(&off_flag, param_key.cstr())) {
|
||||
// Failed to get parameter [%s] of actor indicator (%d) for step (%s).
|
||||
out_message->format(
|
||||
"ステップ(%s)のアクター光点(%d)のパラメータ [%s] の取得に失敗しました。",
|
||||
step->name, i, param_key.cstr());
|
||||
break;
|
||||
}
|
||||
|
||||
param_key.format("IsRemains");
|
||||
param_iter.tryGetBoolByKey(&is_remains, param_key.cstr());
|
||||
|
||||
IndicatorActor* actor = actors.emplaceBack();
|
||||
actor->has_far = has_far;
|
||||
actor->instance_name = instance_name;
|
||||
actor->location = location;
|
||||
actor->name = name;
|
||||
actor->off_flag = off_flag;
|
||||
actor->is_remains = is_remains;
|
||||
actor->hash_instance_name = sead::HashCRC32::calcStringHash(instance_name);
|
||||
actor->hash_name = sead::HashCRC32::calcStringHash(name);
|
||||
|
||||
if (actor == nullptr) {
|
||||
// Failed to generate actor indicator information (%d) for step (%s).
|
||||
out_message->format("ステップ(%s)のアクター光点情報(%d)の生成に失敗しました。",
|
||||
step->name, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sead::FixedSafeString<32> loc_key("IndicatorLocations");
|
||||
al::ByamlIter loc_iter;
|
||||
if (iter->tryGetIterByKey(&loc_iter, loc_key.cstr())) {
|
||||
if (!loc_iter.isValid()) {
|
||||
// Parameter [%s] for step (%s) is invalid data.
|
||||
out_message->format("ステップ(%s)のパラメータ [%s] は無効なデータです。", step->name,
|
||||
loc_key.cstr());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
acquireActors();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Indicator::finalize() {
|
||||
actors.freeBuffer();
|
||||
_28.freeBuffer();
|
||||
}
|
||||
|
||||
void Indicator::acquireActors() {
|
||||
sead::FixedSafeString<64> s;
|
||||
|
||||
for (int i = 0; i < actors.size(); ++i) {
|
||||
IndicatorActor* actor = actors[i];
|
||||
if (actor == nullptr)
|
||||
continue;
|
||||
|
||||
act::BaseProc* proc = Manager::sub_7100FD5848(actor->name, actor->instance_name);
|
||||
if (proc != nullptr) {
|
||||
if (actor->is_remains == 1) {
|
||||
actor->link.acquire(proc, false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (actor->has_far) {
|
||||
s = actor->name;
|
||||
s.append("_Far");
|
||||
proc = Manager::sub_7100FD5848(s, actor->instance_name);
|
||||
if (proc != nullptr) {
|
||||
if (actor->is_remains == 1) {
|
||||
actor->link.acquire(proc, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const IndicatorActor* Indicator::sub_7100FD54E4(int idx) const {
|
||||
if (actors.size() < 1 || idx < 0 || idx >= actors.size())
|
||||
return nullptr;
|
||||
return actors[idx];
|
||||
}
|
||||
|
||||
const IndicatorActor* Indicator::sub_7100FD5518(int idx) const {
|
||||
if (_28.size() < 1 || idx < 0 || idx >= _28.size())
|
||||
return nullptr;
|
||||
return _28[idx];
|
||||
}
|
||||
|
||||
IndicatorActor::~IndicatorActor() = default;
|
||||
|
||||
} // namespace ksys::qst
|
||||
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <heap/seadHeap.h>
|
||||
#include "KingSystem/Quest/qstManager.h"
|
||||
#include "KingSystem/Utils/Byaml/Byaml.h"
|
||||
|
||||
namespace ksys::qst {
|
||||
|
||||
struct Step;
|
||||
|
||||
struct IndicatorActor {
|
||||
IndicatorActor();
|
||||
virtual ~IndicatorActor();
|
||||
|
||||
act::BaseProcLink link;
|
||||
bool has_far;
|
||||
const char* instance_name;
|
||||
sead::Vector3f location;
|
||||
const char* name;
|
||||
const char* off_flag;
|
||||
u32 is_remains;
|
||||
u32 hash_name = 0;
|
||||
u32 hash_instance_name = 0;
|
||||
void* _58;
|
||||
};
|
||||
|
||||
struct Indicator {
|
||||
Indicator(Step* step, sead::Heap* heap);
|
||||
virtual ~Indicator();
|
||||
|
||||
bool init(al::ByamlIter* iter, sead::BufferedSafeString* out_message);
|
||||
void finalize();
|
||||
|
||||
void acquireActors();
|
||||
void sub_7100FD4FC4();
|
||||
const IndicatorActor* sub_7100FD54E4(int idx) const;
|
||||
const IndicatorActor* sub_7100FD5518(int idx) const;
|
||||
|
||||
sead::ObjArray<IndicatorActor> actors;
|
||||
sead::ObjArray<IndicatorActor> _28;
|
||||
sead::Heap* heap;
|
||||
Step* step;
|
||||
};
|
||||
|
||||
} // namespace ksys::qst
|
||||
@@ -0,0 +1,139 @@
|
||||
|
||||
#include "KingSystem/Quest/qstManager.h"
|
||||
#include "KingSystem/Quest/qstActorData.h"
|
||||
#include "KingSystem/Utils/HeapUtil.h"
|
||||
#include "KingSystem/Utils/SafeDelete.h"
|
||||
|
||||
namespace ksys::qst {
|
||||
|
||||
SEAD_SINGLETON_DISPOSER_IMPL(Manager)
|
||||
|
||||
Manager::~Manager() {
|
||||
cleanUp();
|
||||
util::safeDeleteHeap(mHeap);
|
||||
}
|
||||
|
||||
void Manager::init(sead::Heap* heap) {
|
||||
if (sDisable)
|
||||
return;
|
||||
|
||||
mHeap = util::DualHeap::tryCreate(0x99999, "QuestHeap", heap, util::getDebugHeap(), 8,
|
||||
sead::Heap::cHeapDirection_Forward, true);
|
||||
cleanUp();
|
||||
|
||||
_e4 = -0x51;
|
||||
mFlags = 0;
|
||||
_28 = _2c;
|
||||
_2c = 0;
|
||||
_30 = 0;
|
||||
}
|
||||
|
||||
void Manager::cleanUp() {
|
||||
_44 = 0;
|
||||
_48.freeBuffer();
|
||||
mQuests.freeBuffer();
|
||||
mHandle.unloadAndResetUnitFlag20000();
|
||||
}
|
||||
|
||||
bool Manager::isQuestActor(act::Actor* actor) const {
|
||||
for (int i = 0; i < mQuests.size(); ++i) {
|
||||
const auto* quest = mQuests[i];
|
||||
if (quest->x_6(actor))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// NON_MATCHING: leftovers from a stripped debug function
|
||||
void Manager::auto0(act::Actor* actor) {
|
||||
if (actor == nullptr)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < mQuests.size(); ++i) {
|
||||
Quest* quest = mQuests[i];
|
||||
if (quest->_c != 2 && quest->flagStuff())
|
||||
quest->x_9(actor);
|
||||
}
|
||||
}
|
||||
|
||||
bool Manager::auto4(act::Actor* actor) const {
|
||||
auto end = mQuests.end();
|
||||
for (auto it = mQuests.begin(); it != end; ++it) {
|
||||
if (it->_c != 2 && it->flagStuff() && !it->x_8(actor))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// NON_MATCHING: loops are nonmatching
|
||||
bool Manager::sub_7100FD78F8() {
|
||||
s32 size = mQuests.size();
|
||||
u32 data_count = 0;
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
data_count += mQuests[i]->_148;
|
||||
}
|
||||
|
||||
if (data_count == 0)
|
||||
return true;
|
||||
if (!_48.tryAllocBuffer(data_count, mHeap, 8))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
s32 num2 = mQuests[i]->_148;
|
||||
for (int j = 0; j < num2; ++j) {
|
||||
ActorData* data = mQuests[i]->sub_7100FDA5F8(j);
|
||||
if (data != nullptr) {
|
||||
_48.pushBack(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Manager::sub_7100FD7B30(const sead::SafeString& quest_name, const sead::SafeString& step_name,
|
||||
bool setAocVersionFlag1) {
|
||||
return setQuestStep(quest_name, step_name, false, false, setAocVersionFlag1);
|
||||
}
|
||||
|
||||
bool Manager::setQuestStepFromEvent(const sead::SafeString& quest_name,
|
||||
const sead::SafeString& step_name, bool force_run_telop,
|
||||
bool setAocVersionFlag1) {
|
||||
return setQuestStep(quest_name, step_name, true, force_run_telop, setAocVersionFlag1);
|
||||
}
|
||||
|
||||
// NON_MATCHING: quest is dereferenced several times
|
||||
bool Manager::setQuestStep(const sead::SafeString& quest_name, const sead::SafeString& step_name,
|
||||
bool copy_name, bool force_run_telop, bool setAocVersionFlag1) {
|
||||
u32 hash = sead::HashCRC32::calcStringHash(quest_name.cstr());
|
||||
Quest* quest;
|
||||
for (auto& q : mQuests) {
|
||||
if (q._c - 1 <= 1 && q.mNameHash == hash) {
|
||||
quest = &q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (quest == nullptr)
|
||||
return false;
|
||||
|
||||
quest->setField31();
|
||||
|
||||
quest->_e8.copy(step_name);
|
||||
|
||||
quest->_e0 = false;
|
||||
quest->mForceRunTelop = false;
|
||||
|
||||
if (copy_name) {
|
||||
quest->_e0 = true;
|
||||
const char* x = quest->x_11();
|
||||
if (step_name.isEmpty())
|
||||
quest->_e8.copy(sead::SafeString(x));
|
||||
}
|
||||
if (force_run_telop)
|
||||
quest->mForceRunTelop = true;
|
||||
if (setAocVersionFlag1)
|
||||
quest->mAocVersionFlags |= 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ksys::qst
|
||||
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <container/seadObjArray.h>
|
||||
#include <heap/seadDisposer.h>
|
||||
#include <prim/seadSafeString.h>
|
||||
#include "KingSystem/Quest/qstQuest.h"
|
||||
#include "KingSystem/Resource/resHandle.h"
|
||||
#include "agl/Utils/aglParameter.h"
|
||||
|
||||
namespace ksys::qst {
|
||||
|
||||
struct Quest;
|
||||
|
||||
class Manager {
|
||||
SEAD_SINGLETON_DISPOSER(Manager)
|
||||
public:
|
||||
Manager();
|
||||
virtual ~Manager();
|
||||
|
||||
void init(sead::Heap* heap);
|
||||
void cleanUp();
|
||||
|
||||
void auto0(act::Actor* actor);
|
||||
bool auto4(act::Actor* actor) const;
|
||||
|
||||
bool sub_7100FD78F8();
|
||||
|
||||
bool sub_7100FD7B30(const sead::SafeString& quest_name, const sead::SafeString& step_name,
|
||||
bool setAocVersionFlag1);
|
||||
bool setQuestStepFromEvent(const sead::SafeString& quest_name,
|
||||
const sead::SafeString& step_name, bool force_run_telop,
|
||||
bool setAocVersionFlag1);
|
||||
bool setQuestStep(const sead::SafeString& quest_name, const sead::SafeString& step_name,
|
||||
bool copy_name, bool force_run_telop, bool setAocVersionFlag1);
|
||||
|
||||
bool isQuestActor(act::Actor* actor) const;
|
||||
static act::BaseProc* sub_7100FD5848(const sead::SafeString& s1, const sead::SafeString& s2);
|
||||
|
||||
private:
|
||||
u32 _28;
|
||||
u32 _2c;
|
||||
u32 _30;
|
||||
void* temp;
|
||||
u32 temp2;
|
||||
u32 _44;
|
||||
sead::PtrArray<ActorData> _48;
|
||||
u32 _58;
|
||||
u32 temp3;
|
||||
u32 temp4;
|
||||
res::Handle mHandle;
|
||||
sead::ObjArray<Quest> mQuests;
|
||||
sead::Heap* mHeap = nullptr;
|
||||
u16 mFlags;
|
||||
u32 _e4;
|
||||
s32 _e8 = -1;
|
||||
u32 _d0 = 0;
|
||||
|
||||
static bool sDisable;
|
||||
};
|
||||
|
||||
} // namespace ksys::qst
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "KingSystem/Quest/qstQuest.h"
|
||||
#include "agl/Utils/aglParameter.h"
|
||||
|
||||
namespace ksys::qst {
|
||||
|
||||
// chunks missing
|
||||
Quest::~Quest() {
|
||||
mSteps.freeBuffer();
|
||||
}
|
||||
|
||||
// NON_MATCHING
|
||||
Quest::Quest(const sead::SafeString& name, sead::Heap* heap) : mName(name), mHeap(heap) {
|
||||
_8 = 0;
|
||||
_c = 0;
|
||||
_10 = 0;
|
||||
mNameHash = agl::utl::ParameterBase::calcHash(mName);
|
||||
mAocVersionFlags = 0;
|
||||
}
|
||||
|
||||
void Quest::initFlags(gdt::Manager* gdm) {
|
||||
if (gdm == nullptr)
|
||||
return;
|
||||
|
||||
mReady = gdm->getBoolHandle([&] {
|
||||
sead::FixedSafeString<64> ready;
|
||||
ready.format("%s_Ready", mName.cstr());
|
||||
return ready;
|
||||
}());
|
||||
|
||||
mCancelled = gdm->getBoolHandle([&] {
|
||||
sead::FixedSafeString<64> cancelled;
|
||||
cancelled.format("%s_Cancelled", mName.cstr());
|
||||
return cancelled;
|
||||
}());
|
||||
|
||||
switch (mQuestDependencyFlagType) {
|
||||
default:
|
||||
mDependencyFlag = gdt::InvalidHandle;
|
||||
break;
|
||||
case 0:
|
||||
mDependencyFlag = gdm->getBoolHandle(mQuestDependencyFlag);
|
||||
break;
|
||||
case 1:
|
||||
mDependencyFlag = gdm->getF32Handle(mQuestDependencyFlag);
|
||||
break;
|
||||
case 2:
|
||||
mDependencyFlag = gdm->getS32Handle(mQuestDependencyFlag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Quest::setField31() {
|
||||
_31 = 1;
|
||||
}
|
||||
|
||||
bool Quest::x_1() const {
|
||||
bool result = false;
|
||||
|
||||
if (gdt::Manager::instance() == nullptr || mCancelled == gdt::InvalidHandle)
|
||||
return result;
|
||||
|
||||
gdt::Manager::instance()->getBool(mCancelled, &result, true);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Quest::x_3() {
|
||||
if (_c == 1 || _c == 2)
|
||||
return;
|
||||
|
||||
auto handle = mReady;
|
||||
if (handle != ksys::gdt::InvalidHandle) {
|
||||
bool result = false;
|
||||
auto* gdm = gdt::Manager::instance();
|
||||
if (gdm != nullptr) {
|
||||
if (gdm->getBool(handle, &result, true); !result)
|
||||
gdm->setBool(true, handle);
|
||||
}
|
||||
}
|
||||
_8 = _c;
|
||||
_c = 1;
|
||||
_10 = 0;
|
||||
}
|
||||
|
||||
bool Quest::x_6(act::Actor* actor) const {
|
||||
if (!isStepUnderSize() || !mSteps[_140]->attention_off)
|
||||
return false;
|
||||
|
||||
return mSteps[_140]->sub_7100FDB89C(actor);
|
||||
}
|
||||
|
||||
bool Quest::x_7() const {
|
||||
if (!isStepUnderSize())
|
||||
return false;
|
||||
|
||||
return mSteps[_140]->attention_off;
|
||||
}
|
||||
|
||||
bool Quest::x_8(act::Actor* actor) {
|
||||
if (isStepUnderCapacity())
|
||||
mSteps[_140]->sub_7100FDB538(actor, mName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Quest::x_9(act::Actor* actor) {
|
||||
if (isStepUnderCapacity())
|
||||
mSteps[_140]->sub_7100FDB794(actor);
|
||||
}
|
||||
|
||||
const char* Quest::x_11() {
|
||||
if (!isNextStepUnderSize())
|
||||
return &sead::SafeString::cNullChar;
|
||||
|
||||
return mSteps[_140 + 1]->name;
|
||||
}
|
||||
|
||||
} // namespace ksys::qst
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "KingSystem/GameData/gdtManager.h"
|
||||
#include "KingSystem/Quest/qstStep.h"
|
||||
#include "KingSystem/Resource/resHandle.h"
|
||||
#include "KingSystem/Utils/Byaml/Byaml.h"
|
||||
|
||||
namespace ksys::qst {
|
||||
|
||||
struct Step;
|
||||
|
||||
struct Quest {
|
||||
public:
|
||||
Quest(const sead::SafeString& name, sead::Heap* heap);
|
||||
virtual ~Quest();
|
||||
|
||||
bool isStepUnderCapacity() const { return (_140 >= 0 && _140 < mSteps.capacity()); }
|
||||
bool isStepUnderSize() const { return (_140 >= 0 && _140 < mSteps.size()); }
|
||||
bool isNextStepUnderSize() const { return (_140 + 1 >= 0 && _140 + 1 < mSteps.size()); }
|
||||
|
||||
bool x_6(act::Actor* actor) const;
|
||||
void initFlags(gdt::Manager* gdm);
|
||||
bool flagStuff() const;
|
||||
void setField31();
|
||||
ActorData* sub_7100FDA5F8(int idx);
|
||||
|
||||
bool x_1() const;
|
||||
void x_3();
|
||||
bool x_7() const;
|
||||
bool x_8(act::Actor* actor);
|
||||
void x_9(act::Actor* actor);
|
||||
void x_10(const sead::SafeString& s);
|
||||
const char* x_11();
|
||||
|
||||
u32 _8 = 0;
|
||||
u32 _c = 0;
|
||||
u32 _10;
|
||||
|
||||
gdt::FlagHandle mReady = gdt::InvalidHandle;
|
||||
gdt::FlagHandle mCancelled = gdt::InvalidHandle;
|
||||
gdt::FlagHandle mDependencyFlag = gdt::InvalidHandle;
|
||||
const char* mQuestDependencyFlag = &sead::SafeString::cNullChar;
|
||||
|
||||
u32 mQuestDependencyFlagType = 3;
|
||||
|
||||
u32 mNameHash = 0;
|
||||
u8 mNotPostNote = 0;
|
||||
u8 _31 = 0;
|
||||
u8 _32 = 0;
|
||||
u8 _33 = 0;
|
||||
const char* mLocation = &sead::SafeString::cNullChar;
|
||||
sead::FixedSafeString<64> mName;
|
||||
const char* mOrderer = &sead::SafeString::cNullChar;
|
||||
sead::ObjArray<Step> mSteps;
|
||||
const char* mType = &sead::SafeString::cNullChar;
|
||||
sead::Heap* mHeap;
|
||||
al::ByamlIter* mDataIter = nullptr;
|
||||
u32 mAocVersionFlags = 0;
|
||||
u32 _dc = 0;
|
||||
u8 _e0 = 0;
|
||||
u8 mForceRunTelop = 0;
|
||||
u8 _e2 = 0;
|
||||
u8 _e3 = 0;
|
||||
u32 _e4 = 0;
|
||||
sead::FixedSafeString<64> _e8;
|
||||
s32 _140 = -1; // current or next step?
|
||||
u8 _144 = 0;
|
||||
u32 _148 = 0;
|
||||
u32 _14c;
|
||||
void* _150 = nullptr;
|
||||
};
|
||||
|
||||
} // namespace ksys::qst
|
||||
@@ -0,0 +1,97 @@
|
||||
#include "KingSystem/Quest/qstStep.h"
|
||||
#include <memory>
|
||||
#include "KingSystem/Quest/qstActorData.h"
|
||||
#include "KingSystem/Quest/qstIndicator.h"
|
||||
|
||||
namespace ksys::qst {
|
||||
|
||||
// NON_MATCHING: regalloc
|
||||
Step::Step(const u8** iter_data, sead::Heap* heap) : heap(heap) {
|
||||
if (*iter_data != nullptr) {
|
||||
iter = new (heap, std::nothrow_t()) al::ByamlIter(*iter_data);
|
||||
}
|
||||
}
|
||||
|
||||
bool Step::sub_7100FDB89C(act::Actor* actor) const {
|
||||
for (int i = 0; i < links.size(); ++i) {
|
||||
if (!links[i]->link.hasProc())
|
||||
continue;
|
||||
if (links[i]->link.hasProcById(actor))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Step::sub_7100FDB538(act::Actor* actor, const sead::SafeString& name) const {
|
||||
if (actor == nullptr)
|
||||
return false;
|
||||
if (!_28)
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < links.size(); ++i) {
|
||||
sead::SafeString actName(actor->getName());
|
||||
sead::SafeString uniqName(actor->getUniqueName());
|
||||
if (actName != links[i]->name)
|
||||
continue;
|
||||
|
||||
if (uniqName != links[i]->unique_name)
|
||||
continue;
|
||||
|
||||
if (links[i]->sub_71012B43D0(actor, name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Step::initActorData([[maybe_unused]] u32 unused, sead::BufferedSafeString* out_message) {
|
||||
if (actor_data != nullptr) {
|
||||
// The photo object has already been created.
|
||||
out_message->format("写真対象は既に作成されています。");
|
||||
return false;
|
||||
}
|
||||
|
||||
actor_data = new (heap, std::nothrow_t()) ActorData(heap);
|
||||
if (actor_data == nullptr) {
|
||||
// Due to insufficient memory, photo data could not be created.
|
||||
out_message->format("メモリ不足のため、写真情報を作成できませんでした。");
|
||||
return false;
|
||||
}
|
||||
return actor_data->init(iter, out_message);
|
||||
}
|
||||
|
||||
bool Step::initIndicator([[maybe_unused]] u32 unused, sead::BufferedSafeString* out_message) {
|
||||
if (indicator_info != nullptr) {
|
||||
// The indicator information has already been created.
|
||||
out_message->format("光点情報は既に作成されています。");
|
||||
return false;
|
||||
}
|
||||
|
||||
indicator_info = new (heap, std::nothrow_t()) Indicator(this, heap);
|
||||
if (indicator_info == nullptr) {
|
||||
// Due to insufficient memory, indicator information could not be created.
|
||||
out_message->format("メモリ不足のため、光点情報を作成できませんでした。");
|
||||
return false;
|
||||
}
|
||||
return indicator_info->init(iter, out_message);
|
||||
}
|
||||
|
||||
bool Step::sub_7100FDC2A4(al::ByamlIter* iter) {
|
||||
al::ByamlIter evt_iter;
|
||||
al::ByamlIter trg_iter;
|
||||
const char* value;
|
||||
|
||||
if (!iter->tryGetIterByKey(&evt_iter, "TriggerEvents"))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < evt_iter.getSize(); ++i) {
|
||||
if (evt_iter.tryGetIterByIndex(&trg_iter, i) && trg_iter.isValid() &&
|
||||
trg_iter.tryGetStringByKey(&value, "Trigger")) {
|
||||
if (sead::SafeString("StepStart") == value)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace ksys::qst
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <container/seadObjArray.h>
|
||||
#include <container/seadPtrArray.h>
|
||||
#include "KingSystem/ActorSystem/actActor.h"
|
||||
#include "KingSystem/ActorSystem/actBaseProcLink.h"
|
||||
#include "KingSystem/GameData/gdtFlagHandle.h"
|
||||
#include "KingSystem/Utils/Byaml/Byaml.h"
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
|
||||
namespace ksys::qst {
|
||||
|
||||
struct ActorData;
|
||||
struct Indicator;
|
||||
|
||||
struct Step {
|
||||
struct ActLink {
|
||||
void* _0;
|
||||
act::BaseProcLink link;
|
||||
void* _18;
|
||||
const char* name;
|
||||
void* _28;
|
||||
void* _30;
|
||||
void* _38;
|
||||
void* _40;
|
||||
const char* unique_name;
|
||||
|
||||
bool sub_71012B43D0(act::Actor* actor, const sead::SafeString& name) const;
|
||||
};
|
||||
|
||||
Step(const u8** iter_data, sead::Heap* heap);
|
||||
virtual ~Step();
|
||||
|
||||
bool sub_7100FDB89C(act::Actor* actor) const;
|
||||
bool sub_7100FDB538(act::Actor* actor, const sead::SafeString& name) const;
|
||||
bool sub_7100FDB794(act::Actor* actor) const;
|
||||
bool initActorData(u32 unused, sead::BufferedSafeString* out_message);
|
||||
bool initIndicator(u32 unused, sead::BufferedSafeString* out_message);
|
||||
bool sub_7100FDC2A4(al::ByamlIter* iter);
|
||||
|
||||
sead::ObjArray<ActLink> links;
|
||||
u32 _28 = 0;
|
||||
gdt::FlagHandle dep_flag = gdt::InvalidHandle;
|
||||
const char* dep_flag_name = &sead::SafeString::cNullChar;
|
||||
u32 _38 = 3;
|
||||
u32 _3c = 0;
|
||||
bool attention_off = false;
|
||||
const char* message_name = &sead::SafeString::cNullChar;
|
||||
const char* name = &sead::SafeString::cNullChar;
|
||||
gdt::FlagHandle next_flag = gdt::InvalidHandle;
|
||||
const char* next_flag_name = &sead::SafeString::cNullChar;
|
||||
sead::Heap* heap = nullptr;
|
||||
ActorData* actor_data = nullptr;
|
||||
Indicator* indicator_info = nullptr;
|
||||
al::ByamlIter* iter = nullptr;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(Step, 0x88);
|
||||
|
||||
} // namespace ksys::qst
|
||||
Reference in New Issue
Block a user