diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 67a2f8fb..f40e4444 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -80406,7 +80406,7 @@ Address,Quality,Size,Name 0x0000007100ee7880,O,000012,_ZN4ksys3act19getDefaultDropActorEv 0x0000007100ee788c,U,000036,Actor::createDrops 0x0000007100ee78b0,U,001192,eco::getEcosystemActorName -0x0000007100ee7d58,U,000344,eco::sub_7100EE7D58 +0x0000007100ee7d58,O,000344,_ZN4ksys3act17getRandomAreaItemEPN4sead14SafeStringBaseIcEERKNS_3eco12AreaItemTypeERKNS1_7Vector3IfEE 0x0000007100ee7eb0,O,000056,_ZN4ksys3act22isInSatoriMountainAreaERKN4sead7Vector3IfEE 0x0000007100ee7ee8,U,002112, 0x0000007100ee8728,U,000388, diff --git a/src/KingSystem/ActorSystem/actActorUtil.cpp b/src/KingSystem/ActorSystem/actActorUtil.cpp index 95062d8e..798506b8 100644 --- a/src/KingSystem/ActorSystem/actActorUtil.cpp +++ b/src/KingSystem/ActorSystem/actActorUtil.cpp @@ -1,6 +1,7 @@ #include "KingSystem/ActorSystem/actActorUtil.h" #include #include +#include #include "KingSystem/ActorSystem/Profiles/actRopeBase.h" #include "KingSystem/ActorSystem/actActor.h" #include "KingSystem/ActorSystem/actActorConstDataAccess.h" @@ -586,6 +587,35 @@ bool getSameGroupActorName(sead::SafeString* name, const sead::SafeString& actor return true; } +bool getRandomAreaItem(sead::SafeString* item, const eco::AreaItemType& type, + const sead::Vector3f& pos) { + auto* eco = eco::Ecosystem::instance(); + if (!eco) + return false; + + const int area = eco->getFieldMapArea(pos.x, pos.z); + eco::AreaItemSet items; + eco->getAreaItems(area, type, &items); + + int chosen_idx = -1; + int running_total = 0; + + for (int idx = 0; idx < items.count; ++idx) { + const int num = items.items[idx].num; + running_total += num; + if (int(sead::GlobalRandom::instance()->getU32(running_total)) < num) + chosen_idx = idx; + } + + if (chosen_idx < 0) { + *item = sead::SafeString::cEmptyString; + return false; + } + + *item = items.items[chosen_idx].name; + return true; +} + bool isInSatoriMountainArea(const sead::Vector3f& pos) { return eco::Ecosystem::instance()->getFieldMapArea(pos.x, pos.z) == 64; } diff --git a/src/KingSystem/ActorSystem/actActorUtil.h b/src/KingSystem/ActorSystem/actActorUtil.h index e940f301..2e0a576e 100644 --- a/src/KingSystem/ActorSystem/actActorUtil.h +++ b/src/KingSystem/ActorSystem/actActorUtil.h @@ -7,6 +7,10 @@ namespace al { class ByamlIter; } +namespace ksys::eco { +enum class AreaItemType; +} + namespace ksys::map { class Object; } @@ -167,6 +171,8 @@ bool getSameGroupActorName(sead::SafeString* name, const sead::SafeString& actor s32 getSelectedChoiceIdx(s32 max, const char* query_name); +bool getRandomAreaItem(sead::SafeString* item, const eco::AreaItemType& type, + const sead::Vector3f& pos); bool isInSatoriMountainArea(const sead::Vector3f& pos); } // namespace ksys::act