mirror of https://github.com/zeldaret/botw.git
ksys/act: Implement most other base Ai functions
Remaining: two ASList functions we can't implement yet
This commit is contained in:
parent
eb7cd029ad
commit
dd99768dc1
|
@ -1321,7 +1321,7 @@
|
||||||
0x000000710004c1d0,AI_AIOrActionBase::ret0_4,8,_ZN4ksys3act2ai10ActionBase15handleMessage2_EPNS_3mes7MessageE
|
0x000000710004c1d0,AI_AIOrActionBase::ret0_4,8,_ZN4ksys3act2ai10ActionBase15handleMessage2_EPNS_3mes7MessageE
|
||||||
0x000000710004c1d8,AI_AIOrActionBase::ret1_0,8,_ZN4ksys3act2ai10ActionBase18updateForPreDeleteEv
|
0x000000710004c1d8,AI_AIOrActionBase::ret1_0,8,_ZN4ksys3act2ai10ActionBase18updateForPreDeleteEv
|
||||||
0x000000710004c1e0,AI_AIOrActionBase::m19_null,4,_ZN4ksys3act2ai10ActionBase11onPreDeleteEv
|
0x000000710004c1e0,AI_AIOrActionBase::m19_null,4,_ZN4ksys3act2ai10ActionBase11onPreDeleteEv
|
||||||
0x000000710004c1e4,AI_AIOrActionBase::ret0_0,8,_ZN4ksys3act2ai10ActionBase11changeChildERKN4sead14SafeStringBaseIcEE
|
0x000000710004c1e4,AI_AIOrActionBase::ret0_0,8,_ZN4ksys3act2ai10ActionBase16changeChildLaterERKN4sead14SafeStringBaseIcEE
|
||||||
0x000000710004c1ec,AI_AIOrActionBase::ret0_1,8,_ZNK4ksys3act2ai10ActionBase14getNumChildrenEv
|
0x000000710004c1ec,AI_AIOrActionBase::ret0_1,8,_ZNK4ksys3act2ai10ActionBase14getNumChildrenEv
|
||||||
0x000000710004c1f4,AI_AIOrActionBase::ret1_1,8,_ZN4ksys3act2ai10ActionBase12initChildrenERKNS_8AIDefSetEPN4sead4HeapE
|
0x000000710004c1f4,AI_AIOrActionBase::ret1_1,8,_ZN4ksys3act2ai10ActionBase12initChildrenERKNS_8AIDefSetEPN4sead4HeapE
|
||||||
0x000000710004c1fc,AI_AIOrActionBase::ret0_5,8,_ZNK4ksys3act2ai10ActionBase15getCurrentChildEv
|
0x000000710004c1fc,AI_AIOrActionBase::ret0_5,8,_ZNK4ksys3act2ai10ActionBase15getCurrentChildEv
|
||||||
|
@ -92259,24 +92259,24 @@
|
||||||
0x00000071011ddfa8,AI_AIBase::dtorDelete,92,_ZN4ksys3act2ai2AiD0Ev
|
0x00000071011ddfa8,AI_AIBase::dtorDelete,92,_ZN4ksys3act2ai2AiD0Ev
|
||||||
0x00000071011de004,AI_AIBase::m25,132,_ZN4ksys3act2ai2Ai12initChildrenERKNS_8AIDefSetEPN4sead4HeapE
|
0x00000071011de004,AI_AIBase::m25,132,_ZN4ksys3act2ai2Ai12initChildrenERKNS_8AIDefSetEPN4sead4HeapE
|
||||||
0x00000071011de088,AI_AIBase::initChildStates,580,_ZN4ksys3act2ai2Ai13initChildren_EiPPKcRN4sead6BufferItEEPNS6_4HeapE
|
0x00000071011de088,AI_AIBase::initChildStates,580,_ZN4ksys3act2ai2Ai13initChildren_EiPPKcRN4sead6BufferItEEPNS6_4HeapE
|
||||||
0x00000071011de2cc,AI_AIBase::x_0,340,
|
0x00000071011de2cc,AI_AIBase::x_0,340,_ZN4ksys3act2ai2Ai24gatherParamsFromChildrenEPN4sead4HeapE
|
||||||
0x00000071011de420,AI_AIBase::calcRecursively,156,_ZN4ksys3act2ai2Ai4calcEv
|
0x00000071011de420,AI_AIBase::calcRecursively,156,_ZN4ksys3act2ai2Ai4calcEv
|
||||||
0x00000071011de4bc,AI_AIBase::x,76,
|
0x00000071011de4bc,AI_AIBase::x,76,_ZN4ksys3act2ai2Ai24handlePendingChildChangeEv
|
||||||
0x00000071011de508,sub_71011DE508,276,
|
0x00000071011de508,sub_71011DE508,276,
|
||||||
0x00000071011de61c,sub_71011DE61C,24,
|
0x00000071011de61c,sub_71011DE61C,24,
|
||||||
0x00000071011de634,AI_AIBase::hasCustomActionIndex,40,
|
0x00000071011de634,AI_AIBase::hasCustomActionIndex,40,_ZNK4ksys3act2ai2Ai21hasPendingChildChangeEv
|
||||||
0x00000071011de65c,AI_AIBase::getChildStateIndexByName,344,
|
0x00000071011de65c,AI_AIBase::getChildStateIndexByName,344,_ZNK4ksys3act2ai2Ai11getChildIdxERKN4sead14SafeStringBaseIcEE
|
||||||
0x00000071011de7b4,AI_AIBase::doChangeState,440,
|
0x00000071011de7b4,AI_AIBase::doChangeState,440,_ZN4ksys3act2ai2Ai11changeChildEjPNS1_15InlineParamPackE
|
||||||
0x00000071011de96c,AI_AIBase::changeState,96,
|
0x00000071011de96c,AI_AIBase::changeState,96,_ZN4ksys3act2ai2Ai11changeChildEPKcPNS1_15InlineParamPackE
|
||||||
0x00000071011de9cc,AI_AIBase::m28,400,
|
0x00000071011de9cc,AI_AIBase::m28,400,_ZN4ksys3act2ai2Ai7reenterEPNS1_10ActionBaseERKN4sead14SafeStringBaseIcEE
|
||||||
0x00000071011deb5c,AI_AIBase::m6,72,_ZNK4ksys3act2ai2Ai10isFlag4SetEv
|
0x00000071011deb5c,AI_AIBase::m6,72,_ZNK4ksys3act2ai2Ai10isFlag4SetEv
|
||||||
0x00000071011deba4,AI_AIBase::getCurrentChildState,52,_ZNK4ksys3act2ai2Ai15getCurrentChildEv
|
0x00000071011deba4,AI_AIBase::getCurrentChildState,52,_ZNK4ksys3act2ai2Ai15getCurrentChildEv
|
||||||
0x00000071011debd8,AI_AIBase::isState,196,
|
0x00000071011debd8,AI_AIBase::isState,196,_ZNK4ksys3act2ai2Ai14isCurrentChildERKN4sead14SafeStringBaseIcEE
|
||||||
0x00000071011dec9c,ai::ActorAI::checkAction,188,
|
0x00000071011dec9c,ai::ActorAI::checkAction,188,_ZN4ksys3act2ai2Ai15isCurrentActionERKN4sead14SafeStringBaseIcEE
|
||||||
0x00000071011ded58,sub_71011DED58,24,_ZN4ksys3act2ai2Ai14updateChildIdxEt
|
0x00000071011ded58,sub_71011DED58,24,_ZN4ksys3act2ai2Ai14changeChildIdxEt
|
||||||
0x00000071011ded70,AI_AIBase::m22,116,
|
0x00000071011ded70,AI_AIBase::m22,116,_ZN4ksys3act2ai2Ai16changeChildLaterERKN4sead14SafeStringBaseIcEE
|
||||||
0x00000071011dede4,AI_AIBase::m31,224,
|
0x00000071011dede4,AI_AIBase::m31,224,_ZNK4ksys3act2ai2Ai8getNamesEPN4sead22BufferedSafeStringBaseIcEE
|
||||||
0x00000071011deec4,AI_AIBase::m23,216,
|
0x00000071011deec4,AI_AIBase::m23,216,_ZNK4ksys3act2ai2Ai9getParamsEPNS1_18ParamNameTypePairsEb
|
||||||
0x00000071011def9c,AI_AIBase::rtti1,204,_ZNK4ksys3act2ai2Ai27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
0x00000071011def9c,AI_AIBase::rtti1,204,_ZNK4ksys3act2ai2Ai27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||||
0x00000071011df068,AI_AIBase::rtti2,92,_ZNK4ksys3act2ai2Ai18getRuntimeTypeInfoEv
|
0x00000071011df068,AI_AIBase::rtti2,92,_ZNK4ksys3act2ai2Ai18getRuntimeTypeInfoEv
|
||||||
0x00000071011df0c4,ai::AIs::ctor,28,_ZN4ksys3act2ai3AisC1Ev
|
0x00000071011df0c4,ai::AIs::ctor,28,_ZN4ksys3act2ai3AisC1Ev
|
||||||
|
|
Can't render this file because it is too large.
|
|
@ -100,7 +100,7 @@ public:
|
||||||
virtual void calc() {}
|
virtual void calc() {}
|
||||||
virtual void getCurrentName(sead::BufferedSafeString* name, ActionBase* last) const;
|
virtual void getCurrentName(sead::BufferedSafeString* name, ActionBase* last) const;
|
||||||
|
|
||||||
virtual ActionBase* changeChild(const sead::SafeString& name) { return nullptr; }
|
virtual ActionBase* changeChildLater(const sead::SafeString& name) { return nullptr; }
|
||||||
virtual void getParams(ParamNameTypePairs* pairs, bool update_use_count) const;
|
virtual void getParams(ParamNameTypePairs* pairs, bool update_use_count) const;
|
||||||
virtual s32 getNumChildren() const { return 0; }
|
virtual s32 getNumChildren() const { return 0; }
|
||||||
virtual bool initChildren(const AIDefSet& set, sead::Heap* heap) { return true; }
|
virtual bool initChildren(const AIDefSet& set, sead::Heap* heap) { return true; }
|
||||||
|
|
|
@ -70,6 +70,25 @@ bool Ai::initChildren_(s32 num_children, const char** names, sead::Buffer<u16>&
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Ai::gatherParamsFromChildren(sead::Heap* heap) {
|
||||||
|
if (mFlags.isOff(Flag::DynamicParamChild) || mFlags.isOn(Flag::_20))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
ParamNameTypePairs pairs;
|
||||||
|
for (auto* child : mChildren) {
|
||||||
|
if (auto* ai = sead::DynamicCast<Ai>(child)) {
|
||||||
|
if (ai->mFlags.isOn(Flag::DynamicParamChild) && ai->mFlags.isOff(Flag::_20) &&
|
||||||
|
!ai->gatherParamsFromChildren(heap)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
child->getParams(&pairs, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
mFlags.set(Flag::_20);
|
||||||
|
return mParams.load(*mActor, pairs, mChildren.size(), heap);
|
||||||
|
}
|
||||||
|
|
||||||
void Ai::calc() {
|
void Ai::calc() {
|
||||||
calc_();
|
calc_();
|
||||||
|
|
||||||
|
@ -77,7 +96,7 @@ void Ai::calc() {
|
||||||
if (child)
|
if (child)
|
||||||
child->calc();
|
child->calc();
|
||||||
|
|
||||||
if (mPendingChildIdx != InvalidIdx && mChildIdx != mPendingChildIdx) {
|
if (hasPendingChildChange()) {
|
||||||
handlePendingChildChange_();
|
handlePendingChildChange_();
|
||||||
auto* new_child = getCurrentChild();
|
auto* new_child = getCurrentChild();
|
||||||
if (new_child)
|
if (new_child)
|
||||||
|
@ -85,6 +104,86 @@ void Ai::calc() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Ai::handlePendingChildChange() {
|
||||||
|
if (!hasPendingChildChange())
|
||||||
|
return false;
|
||||||
|
handlePendingChildChange_();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Ai::hasPendingChildChange() const {
|
||||||
|
return mPendingChildIdx != InvalidIdx && mChildIdx != mPendingChildIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 Ai::getChildIdx(const sead::SafeString& name) const {
|
||||||
|
const s32 idx = mChildren.binarySearch(
|
||||||
|
name, +[](ActionBase* const& action, const sead::SafeString& key) {
|
||||||
|
if (action == nullptr)
|
||||||
|
return 0;
|
||||||
|
return sead::SafeString(action->getName()).compare(key);
|
||||||
|
});
|
||||||
|
return idx == -1 ? InvalidIdx : idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ai::changeChild(u32 idx, InlineParamPack* params) {
|
||||||
|
const auto do_change = [&](InlineParamPack* pack) {
|
||||||
|
auto* current_child = getCurrentChild();
|
||||||
|
mNewChildIdx = idx;
|
||||||
|
if (current_child)
|
||||||
|
current_child->leave();
|
||||||
|
|
||||||
|
changeChildIdx(idx);
|
||||||
|
if (mChildren[idx])
|
||||||
|
mChildren[idx]->enter(pack, getName());
|
||||||
|
|
||||||
|
setRootAiFlag(RootAiFlag::_100);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mFlags.isOff(Flag::DynamicParamChild) || params) {
|
||||||
|
do_change(params);
|
||||||
|
} else {
|
||||||
|
InlineParamPack pack;
|
||||||
|
copyParams(&pack, false);
|
||||||
|
do_change(&pack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ai::changeChild(const char* name, InlineParamPack* params) {
|
||||||
|
const auto idx = getChildIdx(name);
|
||||||
|
if (idx != InvalidIdx)
|
||||||
|
changeChild(idx, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Ai::reenter(ActionBase* other, const sead::SafeString& context) {
|
||||||
|
auto* ai = sead::DynamicCast<Ai>(other);
|
||||||
|
if (!ai)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ai->getNumChildren() != getNumChildren())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mPendingChildIdx = InvalidIdx;
|
||||||
|
|
||||||
|
const bool reenter_ret = reenter_(ai, false);
|
||||||
|
|
||||||
|
if (mFlags.isOn(Flag::_40)) {
|
||||||
|
if (auto* child = getCurrentChild())
|
||||||
|
child->leave();
|
||||||
|
mFlags.reset(Flag::_40);
|
||||||
|
}
|
||||||
|
|
||||||
|
mPrevChildIdx = ai->mPrevChildIdx;
|
||||||
|
mChildIdx = ai->mChildIdx;
|
||||||
|
if (!reenter_ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto* other_child = ai->getCurrentChild();
|
||||||
|
auto* child = getCurrentChild();
|
||||||
|
if (!other_child || !child)
|
||||||
|
return true;
|
||||||
|
return child->takeOver(other_child, getName());
|
||||||
|
}
|
||||||
|
|
||||||
bool Ai::isFlag4Set() const {
|
bool Ai::isFlag4Set() const {
|
||||||
auto* child = getCurrentChild();
|
auto* child = getCurrentChild();
|
||||||
if (child)
|
if (child)
|
||||||
|
@ -99,13 +198,67 @@ ActionBase* Ai::getCurrentChild() const {
|
||||||
return mChildren[mChildIdx];
|
return mChildren[mChildIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ai::updateChildIdx(u16 new_idx) {
|
bool Ai::isCurrentChild(const sead::SafeString& name) const {
|
||||||
|
const auto* child = getCurrentChild();
|
||||||
|
if (!child)
|
||||||
|
return false;
|
||||||
|
return name == child->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Ai::isCurrentAction(const sead::SafeString& name) {
|
||||||
|
auto* action = getCurrentAction();
|
||||||
|
if (!action)
|
||||||
|
return false;
|
||||||
|
return name == action->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ai::changeChildIdx(u16 new_idx) {
|
||||||
const auto prev_idx = mChildIdx;
|
const auto prev_idx = mChildIdx;
|
||||||
mChildIdx = new_idx;
|
mChildIdx = new_idx;
|
||||||
mPrevChildIdx = prev_idx;
|
mPrevChildIdx = prev_idx;
|
||||||
mPendingChildIdx = InvalidIdx;
|
mPendingChildIdx = InvalidIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActionBase* Ai::changeChildLater(const sead::SafeString& name) {
|
||||||
|
const auto idx = getChildIdx(name);
|
||||||
|
if (idx == InvalidIdx)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (idx == mChildIdx)
|
||||||
|
return getCurrentChild();
|
||||||
|
|
||||||
|
mPendingChildIdx = idx;
|
||||||
|
return mChildren[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ai::getNames(sead::BufferedSafeString* out) const {
|
||||||
|
if (mPrevChildIdx == InvalidIdx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto* child = mChildren[mPrevChildIdx];
|
||||||
|
if (!child)
|
||||||
|
return;
|
||||||
|
|
||||||
|
out->appendWithFormat("/%s", child->getName());
|
||||||
|
if (auto* child_ai = sead::DynamicCast<const Ai>(child))
|
||||||
|
child_ai->getNames(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ai::getParams(ParamNameTypePairs* pairs, bool update_use_count) const {
|
||||||
|
auto* ptr = this;
|
||||||
|
do {
|
||||||
|
ptr->ActionBase::getParams(pairs, update_use_count);
|
||||||
|
if (ptr->mFlags.isOff(Flag::DynamicParamChild))
|
||||||
|
return;
|
||||||
|
if (!sead::IsDerivedFrom<Ai>(ptr))
|
||||||
|
return;
|
||||||
|
if (ptr->getNumChildren() <= 0)
|
||||||
|
return;
|
||||||
|
ptr = static_cast<const Ai*>(ptr->getChild(0));
|
||||||
|
update_use_count = false;
|
||||||
|
} while (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
Ais::Ais() = default;
|
Ais::Ais() = default;
|
||||||
|
|
||||||
Ais::~Ais() {
|
Ais::~Ais() {
|
||||||
|
|
|
@ -12,26 +12,38 @@ public:
|
||||||
~Ai() override;
|
~Ai() override;
|
||||||
|
|
||||||
bool isFlag4Set() const override;
|
bool isFlag4Set() const override;
|
||||||
bool reenter_(ActionBase* other, bool x) override;
|
|
||||||
void calc() override;
|
void calc() override;
|
||||||
ActionBase* changeChild(const sead::SafeString& name) override;
|
ActionBase* changeChildLater(const sead::SafeString& name) override;
|
||||||
void getParams(ParamNameTypePairs* pairs, bool update_use_count) const override;
|
void getParams(ParamNameTypePairs* pairs, bool update_use_count) const override;
|
||||||
s32 getNumChildren() const override { return mChildren.size(); }
|
s32 getNumChildren() const override { return mChildren.size(); }
|
||||||
bool initChildren(const AIDefSet& set, sead::Heap* heap) override;
|
bool initChildren(const AIDefSet& set, sead::Heap* heap) override;
|
||||||
ActionBase* getCurrentChild() const override;
|
ActionBase* getCurrentChild() const override;
|
||||||
ActionType getType() const override { return ActionType::AI; }
|
ActionType getType() const override { return ActionType::AI; }
|
||||||
bool reenter(ActionBase* other, const sead::SafeString& context) override;
|
bool reenter(ActionBase* other, const sead::SafeString& context) override;
|
||||||
void postLeave() override { updateChildIdx(InvalidIdx); }
|
void postLeave() override { changeChildIdx(InvalidIdx); }
|
||||||
ActionBase* getChild(s32 idx) const override { return mChildren[idx]; }
|
ActionBase* getChild(s32 idx) const override { return mChildren[idx]; }
|
||||||
virtual void getNames(sead::BufferedSafeString* out);
|
virtual void getNames(sead::BufferedSafeString* out) const;
|
||||||
|
|
||||||
bool gatherParamsFromChildren(sead::Heap* heap);
|
bool gatherParamsFromChildren(sead::Heap* heap);
|
||||||
|
|
||||||
|
void changeAS(const char* as_name, bool b, int x, int y);
|
||||||
|
// TODO: figure out what this actually does and rename
|
||||||
|
bool checkAS(int x, int y);
|
||||||
|
|
||||||
|
/// @returns whether there was a pending child change.
|
||||||
|
bool handlePendingChildChange();
|
||||||
|
bool hasPendingChildChange() const;
|
||||||
|
s32 getChildIdx(const sead::SafeString& name) const;
|
||||||
|
void changeChild(u32 idx, InlineParamPack* params = nullptr);
|
||||||
|
void changeChild(const char* name, InlineParamPack* params = nullptr);
|
||||||
|
|
||||||
|
bool isCurrentChild(const sead::SafeString& name) const;
|
||||||
|
bool isCurrentAction(const sead::SafeString& name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void calc_() {}
|
virtual void calc_() {}
|
||||||
virtual void handlePendingChildChange_() { changeChildState(mPendingChildIdx); }
|
virtual void handlePendingChildChange_() { changeChild(mPendingChildIdx); }
|
||||||
void updateChildIdx(u16 new_idx);
|
void changeChildIdx(u16 new_idx);
|
||||||
void changeChildState(u16 idx, InlineParamPack* params = nullptr);
|
|
||||||
|
|
||||||
static constexpr u16 InvalidIdx = 0xffff;
|
static constexpr u16 InvalidIdx = 0xffff;
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ KSYS_CHECK_SIZE_NX150(ParamNameType, 0x10);
|
||||||
struct ParamNameTypePairs {
|
struct ParamNameTypePairs {
|
||||||
void addPair(AIDefParamType type, const sead::SafeString& name, bool update_use_count);
|
void addPair(AIDefParamType type, const sead::SafeString& name, bool update_use_count);
|
||||||
|
|
||||||
sead::SafeArray<ParamNameType, 32> pairs;
|
sead::SafeArray<ParamNameType, 32> pairs{};
|
||||||
s32 count;
|
s32 count = 0;
|
||||||
};
|
};
|
||||||
KSYS_CHECK_SIZE_NX150(ParamNameTypePairs, 0x208);
|
KSYS_CHECK_SIZE_NX150(ParamNameTypePairs, 0x208);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue