diff options
| author | Léo Lam <leo@leolam.fr> | 2020-12-02 23:33:33 +0100 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2020-12-03 01:45:28 +0100 |
| commit | 5b523db03b954fd55cc1ab6b83a9655f5cdcae72 (patch) | |
| tree | fd7026baa0c952e82f7e644697efdcbf30b5526f /src/KingSystem/ActorSystem | |
| parent | bfbe2db425d0bfa4d03315053f0bcebd3a077618 (diff) | |
ksys/act: Implement more ActorUtil functions
Diffstat (limited to 'src/KingSystem/ActorSystem')
| -rw-r--r-- | src/KingSystem/ActorSystem/actActor.h | 18 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actActorConstDataAccess.h | 1 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actActorUtil.cpp | 257 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actActorUtil.h | 18 |
4 files changed, 280 insertions, 14 deletions
diff --git a/src/KingSystem/ActorSystem/actActor.h b/src/KingSystem/ActorSystem/actActor.h index 83315c02..71608780 100644 --- a/src/KingSystem/ActorSystem/actActor.h +++ b/src/KingSystem/ActorSystem/actActor.h @@ -1,5 +1,6 @@ #pragma once +#include <prim/seadTypedBitFlag.h> #include "KingSystem/ActorSystem/actBaseProc.h" namespace ksys { @@ -11,6 +12,12 @@ class ActorParam; class Actor : public BaseProc { public: + enum class StasisFlag { + _1 = 1, + _2 = 2, + _4 = 4, + }; + Actor(); // FIXME ~Actor() override; @@ -27,10 +34,15 @@ public: void nullsub_4649(); // Some kind of logging which has been excluded from the build? + const sead::TypedBitFlag<StasisFlag>& getStasisFlags() const { return mStasisFlags; } + protected: - u8 TEMP1[0x3F4]; // FIXME - ActorParam* mActorParam; - u8 TEMP2[0x2C0]; // FIXME + /* 0x008 */ u8 TEMP_0x008[0x3F4]; // FIXME + /* 0x570 */ ActorParam* mActorParam; + /* 0x578 */ u8 TEMP_0x578[0x710 - 0x578]; + // The name could be incorrect. + /* 0x710 */ sead::TypedBitFlag<StasisFlag> mStasisFlags; + /* 0x714 */ u8 TEMP_0x714[0x838 - 0x714]; // FIXME }; KSYS_CHECK_SIZE_NX150(Actor, 0x838); diff --git a/src/KingSystem/ActorSystem/actActorConstDataAccess.h b/src/KingSystem/ActorSystem/actActorConstDataAccess.h index b5125a03..ba4c4ed5 100644 --- a/src/KingSystem/ActorSystem/actActorConstDataAccess.h +++ b/src/KingSystem/ActorSystem/actActorConstDataAccess.h @@ -9,6 +9,7 @@ namespace ksys::act { class ActorConstDataAccess : public ActorLinkConstDataAccess { public: ActorConstDataAccess() = default; + explicit ActorConstDataAccess(BaseProc* proc) : ActorLinkConstDataAccess(proc) {} bool acquireActor(const ActorLinkConstDataAccess& other); diff --git a/src/KingSystem/ActorSystem/actActorUtil.cpp b/src/KingSystem/ActorSystem/actActorUtil.cpp index f7e37ebe..095d7500 100644 --- a/src/KingSystem/ActorSystem/actActorUtil.cpp +++ b/src/KingSystem/ActorSystem/actActorUtil.cpp @@ -1,4 +1,5 @@ #include "KingSystem/ActorSystem/actActorUtil.h" +#include <container/seadSafeArray.h> #include "KingSystem/ActorSystem/actActor.h" #include "KingSystem/ActorSystem/actActorConstDataAccess.h" #include "KingSystem/ActorSystem/actActorParam.h" @@ -8,7 +9,10 @@ #include "KingSystem/GameData/gdtManager.h" #include "KingSystem/Map/mapObject.h" #include "KingSystem/Map/mapPlacementMgr.h" +#include "KingSystem/Resource/GeneralParamList/resGParamListObjectNpc.h" #include "KingSystem/Resource/resResourceActorLink.h" +#include "KingSystem/Resource/resResourceGParamList.h" +#include "KingSystem/Utils/Byaml/Byaml.h" #include "KingSystem/World/worldManager.h" namespace ksys::act { @@ -21,9 +25,20 @@ ActorConstDataAccess getAccessor(BaseProcLink* link) { return accessor; } -const char* sArrowTypes[] = { - "NormalArrow", "BombArrow_A", "AncientArrow", "FireArrow", "IceArrow", "ElectricArrow", -}; +ActorConstDataAccess getAccessor(Actor* actor) { + ActorConstDataAccess accessor{actor}; + return accessor; +} + +sead::SafeString sDefaultDropActor = "Item_Fruit_A"; +sead::SafeArray<const char*, 6> sArrowTypes{{ + "NormalArrow", + "BombArrow_A", + "AncientArrow", + "FireArrow", + "IceArrow", + "ElectricArrow", +}}; gdt::FlagHandle sAnimalMasterAppearanceHandle = gdt::InvalidHandle; gdt::FlagHandle sFairyCountCheckHandle = gdt::InvalidHandle; gdt::FlagHandle sIsGetStopTimerLv2Handle = gdt::InvalidHandle; @@ -160,4 +175,240 @@ auto initSpawnConditionGameDataFlags_dummy() { return sIsGetStopTimerLv2Handle; } +// NON_MATCHING: redundant branches in the original code. +bool hasAnyRevivalTag(const sead::SafeString& actor) { + auto* info = InfoData::instance(); + al::ByamlIter iter; + if (!info || !info->getActorIter(&iter, actor.cstr())) + return false; + + for (auto tag : { + tags::RevivalBloodyMoon, + tags::RevivalRandom, + tags::RevivalNone, + tags::RevivalNoneForUsed, + tags::RevivalRandomForDrop, + tags::RevivalNoneForDrop, + tags::RevivalUnderGodTime, + }) { + if (info->hasTag(iter, tag)) + return true; + } + return false; +} + +bool hasStopTimerMiddleTag(Actor* actor) { + return hasTag(actor, tags::StopTimerMiddle); +} + +bool hasStopTimerShortTag(Actor* actor) { + return hasTag(actor, tags::StopTimerShort); +} + +// NON_MATCHING: ??? +const char* arrowTypeToString(ArrowType idx) { + return sArrowTypes[u32(idx)]; +} + +ArrowType arrowTypeFromString(const sead::SafeString& name) { + for (s32 i = 0; i < sArrowTypes.size(); ++i) { + if (name == sArrowTypes[i]) + return ArrowType(i); + } + return ArrowType::Invalid; +} + +ZukanType getZukanType(al::ByamlIter* iter) { + if (!iter) + return ZukanType::Invalid; + + auto* info = InfoData::instance(); + + if (info->hasTag(*iter, tags::ZukanAnimal)) + return ZukanType::Animal; + + if (info->hasTag(*iter, tags::ZukanEnemy)) + return ZukanType::Enemy; + + if (info->hasTag(*iter, tags::ZukanSozai)) + return ZukanType::Sozai; + + if (info->hasTag(*iter, tags::ZukanWeapon)) + return ZukanType::Weapon; + + if (info->hasTag(*iter, tags::ZukanOther)) + return ZukanType::Other; + + return ZukanType::Invalid; +} + +ZukanType getZukanType(Actor* actor) { + if (!actor) + return ZukanType::Invalid; + + if (hasTag(actor, tags::ZukanAnimal)) + return ZukanType::Animal; + + if (hasTag(actor, tags::ZukanEnemy)) + return ZukanType::Enemy; + + if (hasTag(actor, tags::ZukanSozai)) + return ZukanType::Sozai; + + if (hasTag(actor, tags::ZukanWeapon)) + return ZukanType::Weapon; + + if (hasTag(actor, tags::ZukanOther)) + return ZukanType::Other; + + return ZukanType::Invalid; +} + +static bool isProfile(const ActorConstDataAccess& accessor, const sead::SafeString& profile) { + return accessor.hasProc() && accessor.getProfile() == profile; +} + +bool isPlayerProfile(const ActorConstDataAccess& accessor) { + return isProfile(accessor, "Player"); +} + +bool isPlayerProfile(Actor* actor) { + return isPlayerProfile(getAccessor(actor)); +} + +bool isPlayerProfile(BaseProcLink* link) { + return isPlayerProfile(getAccessor(link)); +} + +const sead::SafeString& getDefaultDropActor() { + return sDefaultDropActor; +} + +bool isCameraProfile(Actor* actor) { + return isProfile(getAccessor(actor), "Camera"); +} + +bool isNPCProfile(const ActorConstDataAccess& accessor) { + return isProfile(accessor, "NPC"); +} + +bool isNPCProfile(Actor* actor) { + return isNPCProfile(getAccessor(actor)); +} + +bool isNPCProfile(BaseProcLink* link) { + return isNPCProfile(getAccessor(link)); +} + +bool isNPCOffPodFromWeapon(Actor* actor) { + if (!actor) + return false; + + auto* gparam = actor->getParam()->getRes().mGParamList; + if (!gparam) + return false; + + const auto* npc_param = gparam->getNpc(); + return npc_param && npc_param->mIsOffPodFromWeapon.ref(); +} + +bool isDemoNPCProfile(Actor* actor) { + return isProfile(getAccessor(actor), "DemoNPC"); +} + +bool isEnemyProfile(const ActorConstDataAccess& accessor) { + if (!accessor.hasProc()) + return false; + + const auto& profile = accessor.getProfile(); + + return profile == "Enemy" || profile == "GiantEnemy" || profile == "Guardian" || + profile == "GuardianComponent" || profile == "LastBoss" || profile == "GelEnemy" || + profile == "EnemySwarm" || profile == "SiteBoss" || profile == "Sandworm" || + profile == "Dragon"; +} + +bool isEnemyProfile(Actor* actor) { + return isEnemyProfile(getAccessor(actor)); +} + +bool isEnemyProfile(BaseProcLink* link) { + return isEnemyProfile(getAccessor(link)); +} + +bool isGuardianProfile(BaseProcLink* link) { + const auto accessor = getAccessor(link); + if (!accessor.hasProc()) + return false; + + const auto& profile = accessor.getProfile(); + return profile == "Guardian" || profile == "GuardianComponent"; +} + +bool isLargeEnemy(const ActorConstDataAccess& accessor) { + if (!accessor.hasProc()) + return false; + + const auto& profile = accessor.getProfile(); + return profile == "GiantEnemy" || profile == "LastBoss" || profile == "SiteBoss" || + profile == "Sandworm" || profile == "Dragon"; +} + +bool isLargeEnemy(Actor* actor) { + return isLargeEnemy(getAccessor(actor)); +} + +bool isGanonBeast(const ActorConstDataAccess& accessor) { + return accessor.hasProc() && accessor.getName() == "Enemy_GanonBeast"; +} + +bool isGanonBeast(BaseProcLink* link) { + return isGanonBeast(getAccessor(link)); +} + +bool isNotLivingCreature(Actor* actor) { + return isNotLivingCreature(getAccessor(actor)); +} + +bool isNotLivingCreature(const ActorConstDataAccess& accessor) { + if (isPlayerProfile(accessor)) + return false; + if (isNPCProfile(accessor)) + return false; + if (isEnemyProfile(accessor)) + return false; + if (isHorseProfile(accessor)) + return false; + if (isPreyOrSwarm(accessor)) + return false; + return true; +} + +bool isNotLivingCreature(BaseProcLink* link) { + return isNotLivingCreature(getAccessor(link)); +} + +bool isWeaponProfile(const ActorConstDataAccess& accessor) { + if (!accessor.hasProc()) + return false; + return isWeaponProfile(accessor.getName()); +} + +bool isWeaponProfile(const sead::SafeString& actor) { + const char* profile = nullptr; + InfoData::instance()->getActorProfile(&profile, actor.cstr()); + return sead::SafeString(profile).startsWith("Weapon"); +} + +bool isHorseProfile(const ActorConstDataAccess& accessor) { + return isProfile(accessor, "Horse"); +} + +bool isPreyOrSwarm(const ActorConstDataAccess& accessor) { + if (!accessor.hasProc()) + return false; + const auto& profile = accessor.getProfile(); + return profile == "Prey" || profile == "Swarm"; +} + } // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actActorUtil.h b/src/KingSystem/ActorSystem/actActorUtil.h index 1841c55f..f13b8cbc 100644 --- a/src/KingSystem/ActorSystem/actActorUtil.h +++ b/src/KingSystem/ActorSystem/actActorUtil.h @@ -73,7 +73,7 @@ bool hasAnyRevivalTag(const sead::SafeString& actor); bool hasStopTimerMiddleTag(Actor* actor); bool hasStopTimerShortTag(Actor* actor); -bool canBeStasised(Actor* actor); +bool canBeStasised(Actor* actor, bool force); void highlightStasisableActors(bool on); @@ -108,14 +108,14 @@ bool isLargeEnemy(Actor* actor); bool isGanonBeast(const ActorConstDataAccess& accessor); bool isGanonBeast(BaseProcLink* link); -bool isHumanOrOtherAnimal(Actor* actor); -bool isHumanOrOtherAnimal(const ActorConstDataAccess& accessor); -bool isHumanOrOtherAnimal(BaseProcLink* link); +bool isNotLivingCreature(Actor* actor); +bool isNotLivingCreature(const ActorConstDataAccess& accessor); +bool isNotLivingCreature(BaseProcLink* link); -bool isWeaponName(const ActorConstDataAccess& accessor); -bool isWeaponName(const sead::SafeString& actor); -bool isWeaponName(Actor* actor); -bool isWeaponName(BaseProcLink* link); +bool isWeaponProfile(const ActorConstDataAccess& accessor); +bool isWeaponProfile(const sead::SafeString& actor); +bool isWeaponProfile(Actor* actor); +bool isWeaponProfile(BaseProcLink* link); bool isWeaponOrArmor(const ActorConstDataAccess& accessor); bool isWeaponOrArmor(Actor* actor); @@ -154,4 +154,6 @@ bool isAlive(BaseProcLink* link); bool isAirOctaPlatform(const sead::SafeString& name); bool isAirOctaPlatformDlc(const sead::SafeString& name); +const sead::SafeString& getDefaultDropActor(); + } // namespace ksys::act |
