summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem
diff options
context:
space:
mode:
Diffstat (limited to 'src/KingSystem/ActorSystem')
-rw-r--r--src/KingSystem/ActorSystem/actInfoData.cpp321
-rw-r--r--src/KingSystem/ActorSystem/actInfoData.h43
2 files changed, 360 insertions, 4 deletions
diff --git a/src/KingSystem/ActorSystem/actInfoData.cpp b/src/KingSystem/ActorSystem/actInfoData.cpp
index 54499e40..af03b8a3 100644
--- a/src/KingSystem/ActorSystem/actInfoData.cpp
+++ b/src/KingSystem/ActorSystem/actInfoData.cpp
@@ -1,6 +1,8 @@
#include "KingSystem/ActorSystem/actInfoData.h"
+#include <KingSystem/Resource/resModelResourceDivide.h>
#include <codec/seadHashCRC32.h>
#include <math/seadMathNumbers.h>
+#include "KingSystem/Event/evtManager.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/Byaml/ByamlArrayIter.h"
#include "KingSystem/Utils/Byaml/ByamlData.h"
@@ -63,6 +65,58 @@ void InfoData::init(u8* data, sead::Heap* heap, sead::Heap* debug_heap) {
mSystemSameGroupActorNameIdx = mRootIter->getKeyIndex("systemSameGroupActorName");
}
+void InfoData::getModelInfo(const char* actor, InfoData::ModelInfo& info) const {
+ const char** ptr;
+ al::ByamlIter iter;
+ if (!getActorIter(&iter, actor)) {
+ static_cast<void>(logFailure(actor));
+ ptr = &info.bfres;
+ } else {
+ const auto getFloat = [&](f32* value, const char* key, float default_) {
+ if (!iter.tryGetFloatByKey(value, key))
+ *value = default_;
+ };
+
+ getFloat(&info.baseScale.x, "baseScaleX", 1.0);
+ getFloat(&info.baseScale.y, "baseScaleY", 1.0);
+ getFloat(&info.baseScale.z, "baseScaleZ", 1.0);
+
+ getFloat(&info.addColor.r, "addColorR", 0.0);
+ getFloat(&info.addColor.g, "addColorG", 0.0);
+ getFloat(&info.addColor.b, "addColorB", 0.0);
+ getFloat(&info.addColor.a, "addColorA", 0.0);
+
+ getFloat(&info.mulColor.r, "mulColorR", 1.0);
+ getFloat(&info.mulColor.g, "mulColorG", 1.0);
+ getFloat(&info.mulColor.b, "mulColorB", 1.0);
+ getFloat(&info.mulColor.a, "mulColorA", 1.0);
+
+ if (!iter.tryGetStringByKey(&info.bfres, "bfres"))
+ info.bfres = nullptr;
+
+ if (!iter.tryGetStringByKey(&info.mainModel, "mainModel"))
+ info.mainModel = nullptr;
+
+ if (!info.bfres)
+ return;
+
+ if (info.mainModel) {
+ const char* model_resource =
+ res::ModelResourceDivide::instance()->getModelResource(info.bfres, info.mainModel);
+ if (model_resource)
+ info.bfres = model_resource;
+ }
+
+ if (!info.bfres || sead::SafeString(info.bfres) != "dammy_data")
+ return;
+
+ info.bfres = nullptr;
+ ptr = &info.mainModel;
+ }
+
+ *ptr = nullptr;
+}
+
bool InfoData::getActorIter(al::ByamlIter* iter, const char* actor, bool x) const {
const u32 hash = sead::HashCRC32::calcStringHash(actor);
@@ -193,6 +247,93 @@ void InfoData::getHomeAreas(const char* actor, HomeAreas& info) const {
}
}
+void InfoData::getInvalidLifeConditions(const char* actor, InvalidLifeConditions& info) const {
+ al::ByamlIter iter;
+ if (!getActorIter(&iter, actor))
+ return;
+
+ al::ByamlData data;
+ al::ByamlHashIter hash_iter{iter.getRootNode()};
+
+ if (hash_iter.getDataByKey(&data, mInvalidTimesIdx)) {
+ al::ByamlIter it{iter.getData(), iter.getData() + data.getValue()};
+ for (s32 i = 0, n = it.getSize(); i < n; ++i) {
+ const char* time = nullptr;
+ if (!it.tryGetStringByIndex(&time, i))
+ continue;
+
+ info.times[info.num_times] = time;
+ ++info.num_times;
+ }
+ }
+
+ if (hash_iter.getDataByKey(&data, mInvalidWeathersIdx)) {
+ al::ByamlIter it{iter.getData(), iter.getData() + data.getValue()};
+ for (s32 i = 0, n = it.getSize(); i < n; ++i) {
+ const char* weather = nullptr;
+ if (!it.tryGetStringByIndex(&weather, i))
+ continue;
+
+ info.weathers[info.num_weathers] = weather;
+ ++info.num_weathers;
+ }
+ }
+}
+
+bool InfoData::hasTag(const char* actor, const char* tag) const {
+ al::ByamlIter iter;
+ return getActorIter(&iter, actor) && hasTag(iter, sead::HashCRC32::calcStringHash(tag));
+}
+
+bool InfoData::hasTag(const al::ByamlIter& actor_iter, u32 tag) const {
+ al::ByamlHashIter tags_iter{actor_iter.getRootNode()};
+ al::ByamlData data;
+ if (!tags_iter.getDataByKey(&data, mTagsIdx))
+ return false;
+
+ al::ByamlIter iter{actor_iter.getData(), actor_iter.getData() + data.getValue()};
+ if (!iter.isValid())
+ return false;
+
+ // Binary search.
+
+ s32 a = 0;
+ s32 b = iter.getSize();
+ if (b <= 0)
+ return false;
+
+ al::ByamlHashIter hash_iter{iter.getRootNode()};
+ const auto pair_table = hash_iter.getPairTable();
+
+ while (a < b) {
+ const s32 idx = (a + b) / 2;
+
+ const auto* pair = &pair_table[idx];
+ if (!pair)
+ break;
+
+ al::ByamlData hash_data{pair};
+ u32 hash;
+ if (!iter.tryConvertUInt(&hash, &hash_data))
+ break;
+
+ if (hash == tag)
+ return true;
+
+ if (hash >= tag)
+ b = idx;
+ else
+ a = idx + 1;
+ }
+
+ return false;
+}
+
+bool InfoData::hasTag(const char* actor, u32 tag_hash) const {
+ al::ByamlIter iter;
+ return getActorIter(&iter, actor) && hasTag(iter, tag_hash);
+}
+
const char* InfoData::getSameGroupActorName(const char* actor) const {
al::ByamlIter iter;
return [&] {
@@ -209,6 +350,52 @@ const char* InfoData::getSameGroupActorName(const char* actor) const {
}();
}
+const char* InfoData::getSameGroupActorName(const al::ByamlIter& iter) const {
+ al::ByamlHashIter hash_iter{iter.getRootNode()};
+ al::ByamlData data;
+ if (hash_iter.getDataByKey(&data, mSystemSameGroupActorNameIdx)) {
+ const char* name;
+ if (iter.tryConvertString(&name, &data))
+ return name;
+ }
+ return sead::SafeString::cEmptyString.cstr();
+}
+
+s32 InfoData::getTerrainTextures(const char* actor, InfoData::TerrainTextures& info) const {
+ al::ByamlIter iter;
+ if (!getActorIter(&iter, actor))
+ return 0;
+
+ al::ByamlIter textures_iter;
+ if (!iter.tryGetIterByKey(&textures_iter, "terrainTextures"))
+ return 0;
+
+ s32 count = 0;
+ for (s32 i = 0; i < textures_iter.getSize(); ++i) {
+ u32 value;
+ textures_iter.tryGetUIntByIndex(&value, i);
+
+ if (u8(value) != 0xFF)
+ info.textures[count++] = u8(value);
+ if (u8(value >> 8) != 0xFF)
+ info.textures[count++] = u8(value >> 8);
+ if (u8(value >> 16) != 0xFF)
+ info.textures[count++] = u8(value >> 16);
+ if (u8(value >> 24) != 0xFF)
+ info.textures[count++] = u8(value >> 24);
+ }
+ return count;
+}
+
+bool InfoData::getDrops(al::ByamlIter* drops_iter, const char* actor) const {
+ al::ByamlIter iter;
+ return getActorIter(&iter, actor) && iter.tryGetIterByKey(drops_iter, "drops");
+}
+
+const char* InfoData::getName(const char* actor) const {
+ return getString(actor, "name", "");
+}
+
const char* InfoData::getString(const char* actor, const char* key,
const sead::SafeString& default_, bool x) const {
al::ByamlIter iter;
@@ -218,6 +405,10 @@ const char* InfoData::getString(const char* actor, const char* key,
return getStringByKey(iter, key, default_);
}
+const char* InfoData::getUnknown(const char* actor, u32) const {
+ return actor;
+}
+
const char* InfoData::getSLinkUser(const char* actor) const {
al::ByamlIter iter;
if (!getActorIter(&iter, actor))
@@ -255,6 +446,15 @@ bool InfoData::getActorProfile(const char** profile, const char* actor) const {
return false;
}
+bool InfoData::getActorProfile(const char** profile, const al::ByamlIter& iter) const {
+ al::ByamlHashIter hash_iter{iter.getRootNode()};
+ al::ByamlData data;
+ if (hash_iter.getDataByKey(&data, mProfileIdx))
+ return iter.tryConvertString(profile, &data);
+ *profile = "Dummy";
+ return false;
+}
+
s32 InfoData::getInt(const char* actor, const char* key, s32 default_, bool x) const {
al::ByamlIter iter;
if (!getActorIter(&iter, actor, x))
@@ -289,8 +489,129 @@ bool InfoData::getBoolByKey(const al::ByamlIter& iter, const char* key, bool def
return iter.tryGetBoolByKey(&value, key) ? value != 0 : default_;
}
+bool InfoData::getActorIter(al::ByamlIter* iter, u32 hash, bool x) const {
+ // Perform a binary search.
+ s32 a = 0;
+ s32 b = mNumActors;
+ while (a < b) {
+ const s32 idx = (a + b) / 2;
+ const u32 hash_i = mHashes[idx];
+
+ if (hash_i == hash) {
+ *iter = al::ByamlIter(mActorsBytes, mActorsBytes + mActorOffsets[idx]);
+ return true;
+ }
+
+ if (hash_i >= hash)
+ b = idx;
+ else
+ a = idx + 1;
+ }
+
+ if (x)
+ static_cast<void>(evt::Manager::instance()->getActiveEvent());
+
+ return false;
+}
+
+bool InfoData::hasBurnableParam(const al::ByamlIter& iter) {
+ al::ByamlIter chemical_it;
+ if (!iter.tryGetIterByKey(&chemical_it, "Chemical"))
+ return false;
+ s32 dummy = 0;
+ return chemical_it.tryGetIntByKey(&dummy, "Burnable");
+}
+
+bool InfoData::hasCapaciterParam(const al::ByamlIter& iter) {
+ al::ByamlIter chemical_it;
+ if (!iter.tryGetIterByKey(&chemical_it, "Chemical"))
+ return false;
+ s32 dummy = 0;
+ return chemical_it.tryGetIntByKey(&dummy, "Capaciter");
+}
+
+bool InfoData::hasCapaciterParam(const char* actor) const {
+ al::ByamlIter iter;
+ return getActorIter(&iter, actor) && hasCapaciterParam(iter);
+}
+
f32 InfoData::getScale(const char* actor) const {
return getFloat(actor, "actorScale", 1.0);
}
+f32 InfoData::getAdjustedLookAtOffsetY(const char* actor) const {
+ al::ByamlIter iter;
+ if (!getActorIter(&iter, actor))
+ return 0.0;
+
+ return iter.getFloatByKey("lookAtOffsetY") + iter.getFloatByKey("rigidBodyCenterY");
+}
+
+f32 InfoData::getCursorOffsetY(const char* actor) const {
+ return getFloat(actor, "cursorOffsetY", 0.0, false);
+}
+
+f32 InfoData::getTraverseDist(const char* actor) const {
+ return getFloat(actor, "traverseDist", 0.0);
+}
+
+bool InfoData::getYLimitAlgorithm(const char** algorithm, const char* actor) const {
+ *algorithm = getString(actor, "yLimitAlgorithm", "NoLimit");
+ return algorithm != nullptr;
+}
+
+f32 InfoData::getAabbNorm(const char* actor, bool x) const {
+ sead::Vector3f min, max;
+ if (getAAbbMinMax(actor, &min, &max, x))
+ return sead::norm2(max - min);
+ return 0.0;
+}
+
+bool InfoData::getAAbbMinMax(const char* actor, sead::Vector3f* min, sead::Vector3f* max,
+ bool x) const {
+ al::ByamlIter iter;
+ if (!getActorIter(&iter, actor, x))
+ return false;
+
+ bool min_ok, max_ok;
+
+ if (al::tryGetByamlV3f(min, iter, "aabbMin")) {
+ min_ok = true;
+ } else {
+ *min = sead::Vector3f::zero;
+ min_ok = false;
+ }
+
+ if (al::tryGetByamlV3f(max, iter, "aabbMax")) {
+ max_ok = true;
+ } else {
+ *max = sead::Vector3f::zero;
+ max_ok = false;
+ }
+
+ return min_ok && max_ok;
+}
+
+s32 InfoData::getSortKey(const char* actor) const {
+ return getInt(actor, "sortKey", 0, false);
+}
+
+f32 InfoData::getBoundingForTraverse(const char* actor) const {
+ return getFloat(actor, "boundingForTraverse", 0, false);
+}
+
+f32 InfoData::getAabbNormHalf(const char* actor) const {
+ return getAabbNorm(actor, true) * 0.5f;
+}
+
+bool InfoData::isHasFar(const char* actor) const {
+ return getBool(actor, "isHasFar", false, false);
+}
+
+bool InfoData::hasDropEntry(const char* actor, const char* key) const {
+ al::ByamlIter iter;
+ getDrops(&iter, actor);
+ return iter.isExistKey(key);
+}
+
} // namespace ksys::act
diff --git a/src/KingSystem/ActorSystem/actInfoData.h b/src/KingSystem/ActorSystem/actInfoData.h
index 56a84e6f..a576bc74 100644
--- a/src/KingSystem/ActorSystem/actInfoData.h
+++ b/src/KingSystem/ActorSystem/actInfoData.h
@@ -6,6 +6,7 @@
#include <heap/seadDisposer.h>
#include <math/seadVector.h>
#include <prim/seadSafeString.h>
+#include "KingSystem/ActorSystem/actTag.h"
#include "KingSystem/Utils/Types.h"
namespace al {
@@ -68,6 +69,19 @@ public:
};
KSYS_CHECK_SIZE_NX150(HomeAreas, 0x18);
+ struct InvalidLifeConditions {
+ s32 num_times;
+ sead::SafeArray<sead::SafeString, 16> times;
+ s32 num_weathers;
+ sead::SafeArray<sead::SafeString, 16> weathers;
+ };
+ KSYS_CHECK_SIZE_NX150(InvalidLifeConditions, 0x210);
+
+ struct TerrainTextures {
+ sead::SafeArray<u8, 0x20> textures;
+ };
+ KSYS_CHECK_SIZE_NX150(TerrainTextures, 0x20);
+
void init(u8* data, sead::Heap* heap, sead::Heap* debug_heap);
void getModelInfo(const char* actor, ModelInfo& info) const;
@@ -76,16 +90,37 @@ public:
void getRecipeInfo(const char* actor, RecipeInfo& info) const;
void getLocators(const char* actor, Locators& info) const;
void getHomeAreas(const char* actor, HomeAreas& info) const;
- // TODO: invalid time function
- // TODO: tag functions
+ void getInvalidLifeConditions(const char* actor, InvalidLifeConditions& info) const;
+ bool hasTag(const char* actor, const char* tag) const;
+ bool hasTag(const al::ByamlIter& actor_iter, u32 tag_hash) const;
+ bool hasTag(const char* actor, u32 tag_hash) const;
const char* getSameGroupActorName(const char* actor) const;
- // TODO: more functions
+ const char* getSameGroupActorName(const al::ByamlIter& iter) const;
+ s32 getTerrainTextures(const char* actor, TerrainTextures& info) const;
+ bool getDrops(al::ByamlIter* drops_iter, const char* actor) const;
+ const char* getName(const char* actor) const;
+ const char* getUnknown(const char* actor, u32 x) const;
const char* getSLinkUser(const char* actor) const;
bool getSLinkAndELinkUsers(const char* actor, const char** elink, const char** slink) const;
const char* getXLinkUser(const char* actor) const;
bool getActorProfile(const char** profile, const char* actor) const;
- // TODO: more functions
+ bool getActorProfile(const char** profile, const al::ByamlIter& iter) const;
+ bool getActorIter(al::ByamlIter* iter, u32 actor_name_hash, bool x = true) const;
+ static bool hasBurnableParam(const al::ByamlIter& iter);
+ static bool hasCapaciterParam(const al::ByamlIter& iter);
+ bool hasCapaciterParam(const char* actor) const;
f32 getScale(const char* actor) const;
+ f32 getAdjustedLookAtOffsetY(const char* actor) const;
+ f32 getCursorOffsetY(const char* actor) const;
+ f32 getTraverseDist(const char* actor) const;
+ bool getYLimitAlgorithm(const char** algorithm, const char* actor) const;
+ f32 getAabbNorm(const char* actor, bool x) const;
+ bool getAAbbMinMax(const char* actor, sead::Vector3f* min, sead::Vector3f* max, bool x) const;
+ s32 getSortKey(const char* actor) const;
+ f32 getBoundingForTraverse(const char* actor) const;
+ f32 getAabbNormHalf(const char* actor) const;
+ bool isHasFar(const char* actor) const;
+ bool hasDropEntry(const char* actor, const char* key) const;
const char* getString(const char* actor, const char* key, const sead::SafeString& default_,
bool x = true) const;