diff --git a/data/uking_functions.csv b/data/uking_functions.csv index eed7d215..f9c156a7 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -41676,9 +41676,9 @@ 0x00000071006a1b50,AI_Query_RandomChoiceExceptOnFlag::ctor,108,_ZN5uking5query24RandomChoiceExceptOnFlagC1ERKN4ksys3act2ai5Query7InitArgE 0x00000071006a1bbc,AI_Query_RandomChoiceExceptOnFlag::dtor,20,_ZN5uking5query24RandomChoiceExceptOnFlagD1Ev 0x00000071006a1bd0,AI_Query_RandomChoiceExceptOnFlag::dtorDelete,52,_ZN5uking5query24RandomChoiceExceptOnFlagD0Ev -0x00000071006a1c04,AI_Query_RandomChoiceExceptOnFlag::doQuery,1120, +0x00000071006a1c04,AI_Query_RandomChoiceExceptOnFlag::doQuery,1120,_ZN5uking5query24RandomChoiceExceptOnFlag7doQueryEv 0x00000071006a2064,AI_Query_RandomChoiceExceptOnFlag::m10,336,_ZN5uking5query24RandomChoiceExceptOnFlag10loadParamsERKN4evfl8QueryArgE -0x00000071006a21b4,AI_Query_RandomChoiceExceptOnFlag::loadParams,324,_ZN5uking5query24RandomChoiceExceptOnFlag10loadParamsEv +0x00000071006a21b4,AI_Query_RandomChoiceExceptOnFlag::loadParams,324,_ZN5uking5query24RandomChoiceExceptOnFlag10loadParamsEv? 0x00000071006a22f8,AI_Query_RandomChoiceExceptOnFlag::rtti1,204,_ZNK5uking5query24RandomChoiceExceptOnFlag27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE 0x00000071006a23c4,AI_Query_RandomChoiceExceptOnFlag::rtti2,92,_ZNK5uking5query24RandomChoiceExceptOnFlag18getRuntimeTypeInfoEv 0x00000071006a2420,sub_71006A2420,260, diff --git a/src/Game/AI/Query/queryRandomChoiceExceptOnFlag.cpp b/src/Game/AI/Query/queryRandomChoiceExceptOnFlag.cpp index 923985be..0dbf20c9 100644 --- a/src/Game/AI/Query/queryRandomChoiceExceptOnFlag.cpp +++ b/src/Game/AI/Query/queryRandomChoiceExceptOnFlag.cpp @@ -1,5 +1,8 @@ #include "Game/AI/Query/queryRandomChoiceExceptOnFlag.h" #include +#include +#include +#include "KingSystem/GameData/gdtManager.h" namespace uking::query { @@ -8,9 +11,48 @@ RandomChoiceExceptOnFlag::RandomChoiceExceptOnFlag(const InitArg& arg) RandomChoiceExceptOnFlag::~RandomChoiceExceptOnFlag() = default; -// FIXME: implement +static bool isFlagForbidden(const sead::SafeString& flag) { + bool value = false; + if (flag.isEmpty()) + return true; + if (!ksys::gdt::Manager::instance()->getParamBypassPerm().get().getBool(&value, flag)) + return true; + return value; +} + +// TODO: stack issues for the booleans in isFlagForbidden int RandomChoiceExceptOnFlag::doQuery() { - return -1; + using Manager = ksys::gdt::Manager; + if (!Manager::instance()) + return 10; + + sead::BitFlag16 forbidden_values; +#define CHECK_FLAG_(BIT) forbidden_values.changeBit(BIT, isFlagForbidden(mCheckFlag##BIT)); + CHECK_FLAG_(0) + CHECK_FLAG_(1) + CHECK_FLAG_(2) + CHECK_FLAG_(3) + CHECK_FLAG_(4) + CHECK_FLAG_(5) + CHECK_FLAG_(6) + CHECK_FLAG_(7) + CHECK_FLAG_(8) + CHECK_FLAG_(9) +#undef CHECK_FLAG_ + + const auto num_allowed_values = 10 - forbidden_values.countOnBit(); + if (num_allowed_values == 0) + return 10; + + s32 count = sead::GlobalRandom::instance()->getU32(num_allowed_values) + 1; + for (s32 i = 0; i < 10; ++i) { + if (forbidden_values.isOffBit(i)) { + if (count < 2) + return i; + --count; + } + } + return 10; } void RandomChoiceExceptOnFlag::loadParams(const evfl::QueryArg& arg) {