summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2020-12-02 23:33:33 +0100
committerLéo Lam <leo@leolam.fr>2020-12-03 01:45:28 +0100
commit5b523db03b954fd55cc1ab6b83a9655f5cdcae72 (patch)
treefd7026baa0c952e82f7e644697efdcbf30b5526f /src/KingSystem/ActorSystem
parentbfbe2db425d0bfa4d03315053f0bcebd3a077618 (diff)
ksys/act: Implement more ActorUtil functions
Diffstat (limited to 'src/KingSystem/ActorSystem')
-rw-r--r--src/KingSystem/ActorSystem/actActor.h18
-rw-r--r--src/KingSystem/ActorSystem/actActorConstDataAccess.h1
-rw-r--r--src/KingSystem/ActorSystem/actActorUtil.cpp257
-rw-r--r--src/KingSystem/ActorSystem/actActorUtil.h18
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