ksys/act: Implement most other base Ai functions

Remaining: two ASList functions we can't implement yet
This commit is contained in:
Léo Lam 2020-12-30 17:51:35 +01:00
parent eb7cd029ad
commit dd99768dc1
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
5 changed files with 191 additions and 26 deletions

View File

@ -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.

View File

@ -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; }

View File

@ -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() {

View File

@ -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;

View File

@ -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);