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
|
||||
0x000000710004c1d8,AI_AIOrActionBase::ret1_0,8,_ZN4ksys3act2ai10ActionBase18updateForPreDeleteEv
|
||||
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
|
||||
0x000000710004c1f4,AI_AIOrActionBase::ret1_1,8,_ZN4ksys3act2ai10ActionBase12initChildrenERKNS_8AIDefSetEPN4sead4HeapE
|
||||
0x000000710004c1fc,AI_AIOrActionBase::ret0_5,8,_ZNK4ksys3act2ai10ActionBase15getCurrentChildEv
|
||||
|
@ -92259,24 +92259,24 @@
|
|||
0x00000071011ddfa8,AI_AIBase::dtorDelete,92,_ZN4ksys3act2ai2AiD0Ev
|
||||
0x00000071011de004,AI_AIBase::m25,132,_ZN4ksys3act2ai2Ai12initChildrenERKNS_8AIDefSetEPN4sead4HeapE
|
||||
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
|
||||
0x00000071011de4bc,AI_AIBase::x,76,
|
||||
0x00000071011de4bc,AI_AIBase::x,76,_ZN4ksys3act2ai2Ai24handlePendingChildChangeEv
|
||||
0x00000071011de508,sub_71011DE508,276,
|
||||
0x00000071011de61c,sub_71011DE61C,24,
|
||||
0x00000071011de634,AI_AIBase::hasCustomActionIndex,40,
|
||||
0x00000071011de65c,AI_AIBase::getChildStateIndexByName,344,
|
||||
0x00000071011de7b4,AI_AIBase::doChangeState,440,
|
||||
0x00000071011de96c,AI_AIBase::changeState,96,
|
||||
0x00000071011de9cc,AI_AIBase::m28,400,
|
||||
0x00000071011de634,AI_AIBase::hasCustomActionIndex,40,_ZNK4ksys3act2ai2Ai21hasPendingChildChangeEv
|
||||
0x00000071011de65c,AI_AIBase::getChildStateIndexByName,344,_ZNK4ksys3act2ai2Ai11getChildIdxERKN4sead14SafeStringBaseIcEE
|
||||
0x00000071011de7b4,AI_AIBase::doChangeState,440,_ZN4ksys3act2ai2Ai11changeChildEjPNS1_15InlineParamPackE
|
||||
0x00000071011de96c,AI_AIBase::changeState,96,_ZN4ksys3act2ai2Ai11changeChildEPKcPNS1_15InlineParamPackE
|
||||
0x00000071011de9cc,AI_AIBase::m28,400,_ZN4ksys3act2ai2Ai7reenterEPNS1_10ActionBaseERKN4sead14SafeStringBaseIcEE
|
||||
0x00000071011deb5c,AI_AIBase::m6,72,_ZNK4ksys3act2ai2Ai10isFlag4SetEv
|
||||
0x00000071011deba4,AI_AIBase::getCurrentChildState,52,_ZNK4ksys3act2ai2Ai15getCurrentChildEv
|
||||
0x00000071011debd8,AI_AIBase::isState,196,
|
||||
0x00000071011dec9c,ai::ActorAI::checkAction,188,
|
||||
0x00000071011ded58,sub_71011DED58,24,_ZN4ksys3act2ai2Ai14updateChildIdxEt
|
||||
0x00000071011ded70,AI_AIBase::m22,116,
|
||||
0x00000071011dede4,AI_AIBase::m31,224,
|
||||
0x00000071011deec4,AI_AIBase::m23,216,
|
||||
0x00000071011debd8,AI_AIBase::isState,196,_ZNK4ksys3act2ai2Ai14isCurrentChildERKN4sead14SafeStringBaseIcEE
|
||||
0x00000071011dec9c,ai::ActorAI::checkAction,188,_ZN4ksys3act2ai2Ai15isCurrentActionERKN4sead14SafeStringBaseIcEE
|
||||
0x00000071011ded58,sub_71011DED58,24,_ZN4ksys3act2ai2Ai14changeChildIdxEt
|
||||
0x00000071011ded70,AI_AIBase::m22,116,_ZN4ksys3act2ai2Ai16changeChildLaterERKN4sead14SafeStringBaseIcEE
|
||||
0x00000071011dede4,AI_AIBase::m31,224,_ZNK4ksys3act2ai2Ai8getNamesEPN4sead22BufferedSafeStringBaseIcEE
|
||||
0x00000071011deec4,AI_AIBase::m23,216,_ZNK4ksys3act2ai2Ai9getParamsEPNS1_18ParamNameTypePairsEb
|
||||
0x00000071011def9c,AI_AIBase::rtti1,204,_ZNK4ksys3act2ai2Ai27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x00000071011df068,AI_AIBase::rtti2,92,_ZNK4ksys3act2ai2Ai18getRuntimeTypeInfoEv
|
||||
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 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 s32 getNumChildren() const { return 0; }
|
||||
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;
|
||||
}
|
||||
|
||||
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() {
|
||||
calc_();
|
||||
|
||||
|
@ -77,7 +96,7 @@ void Ai::calc() {
|
|||
if (child)
|
||||
child->calc();
|
||||
|
||||
if (mPendingChildIdx != InvalidIdx && mChildIdx != mPendingChildIdx) {
|
||||
if (hasPendingChildChange()) {
|
||||
handlePendingChildChange_();
|
||||
auto* new_child = getCurrentChild();
|
||||
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 {
|
||||
auto* child = getCurrentChild();
|
||||
if (child)
|
||||
|
@ -99,13 +198,67 @@ ActionBase* Ai::getCurrentChild() const {
|
|||
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;
|
||||
mChildIdx = new_idx;
|
||||
mPrevChildIdx = prev_idx;
|
||||
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() {
|
||||
|
|
|
@ -12,26 +12,38 @@ public:
|
|||
~Ai() override;
|
||||
|
||||
bool isFlag4Set() const override;
|
||||
bool reenter_(ActionBase* other, bool x) 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;
|
||||
s32 getNumChildren() const override { return mChildren.size(); }
|
||||
bool initChildren(const AIDefSet& set, sead::Heap* heap) override;
|
||||
ActionBase* getCurrentChild() const override;
|
||||
ActionType getType() const override { return ActionType::AI; }
|
||||
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]; }
|
||||
virtual void getNames(sead::BufferedSafeString* out);
|
||||
virtual void getNames(sead::BufferedSafeString* out) const;
|
||||
|
||||
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:
|
||||
virtual void calc_() {}
|
||||
virtual void handlePendingChildChange_() { changeChildState(mPendingChildIdx); }
|
||||
void updateChildIdx(u16 new_idx);
|
||||
void changeChildState(u16 idx, InlineParamPack* params = nullptr);
|
||||
virtual void handlePendingChildChange_() { changeChild(mPendingChildIdx); }
|
||||
void changeChildIdx(u16 new_idx);
|
||||
|
||||
static constexpr u16 InvalidIdx = 0xffff;
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ KSYS_CHECK_SIZE_NX150(ParamNameType, 0x10);
|
|||
struct ParamNameTypePairs {
|
||||
void addPair(AIDefParamType type, const sead::SafeString& name, bool update_use_count);
|
||||
|
||||
sead::SafeArray<ParamNameType, 32> pairs;
|
||||
s32 count;
|
||||
sead::SafeArray<ParamNameType, 32> pairs{};
|
||||
s32 count = 0;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(ParamNameTypePairs, 0x208);
|
||||
|
||||
|
|
Loading…
Reference in New Issue