summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem/actLodState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/KingSystem/ActorSystem/actLodState.cpp')
-rw-r--r--src/KingSystem/ActorSystem/actLodState.cpp332
1 files changed, 332 insertions, 0 deletions
diff --git a/src/KingSystem/ActorSystem/actLodState.cpp b/src/KingSystem/ActorSystem/actLodState.cpp
new file mode 100644
index 00000000..8625ab45
--- /dev/null
+++ b/src/KingSystem/ActorSystem/actLodState.cpp
@@ -0,0 +1,332 @@
+#include "KingSystem/ActorSystem/actLodState.h"
+#include "KingSystem/ActorSystem/actActor.h"
+#include "KingSystem/ActorSystem/actActorParam.h"
+#include "KingSystem/ActorSystem/actActorUtil.h"
+#include "KingSystem/Map/mapObject.h"
+#include "KingSystem/Map/mapPlacementAreaMgr.h"
+#include "KingSystem/Map/mapPlacementMgr.h"
+#include "KingSystem/Resource/Actor/resResourceLod.h"
+#include "KingSystem/System/OcclusionQueryCylinder.h"
+
+namespace ksys::act {
+
+// NON_MATCHING: reorders at the beginning because of initFlags -- should be equivalent
+LodState::LodState(sead::Heap* heap, sead::BitFlag32 flags, Actor* actor,
+ int disable_calc_skip_frame, float x)
+ : mFlags14(flags), mActor(actor), _44(x), mDisableCalcSkipFrame(disable_calc_skip_frame) {
+ initFlags();
+
+ if (mActor->getProfile().include("Enemy") || mActor->getProfile().include("Swarm") ||
+ mActor->getProfile().include("EnemySwarm")) {
+ _24 = 0;
+ }
+ if (mActor->getProfile().include("NPC")) {
+ _24 = 1;
+ }
+ if (mActor->getName() == "GameRomHorseBone") {
+ _24 = 1;
+ }
+ _25 = _24;
+
+ if (mActor->getMapObject()) {
+ mDispDistance = mActor->getMapObject()->getDispDistance();
+ }
+
+ const bool is_air_octa_platform = isAirOctaPlatform(mActor->getName());
+ if (!mActor->checkFlag(Actor::ActorFlag::_39) || mActor->getProfile().startsWith("Guardian")) {
+ if (is_air_octa_platform) {
+ mOcclusionQueryCylinder = new (heap) OcclusionQueryCylinder;
+ mOcclusionQueryCylinder->init(heap);
+ }
+ } else {
+ mOcclusionQueryCylinder = new (heap) OcclusionQueryCylinder;
+ mOcclusionQueryCylinder->init(heap);
+ }
+
+ if (is_air_octa_platform)
+ mFlags26.set(0x40);
+
+ if (auto* lod = mActor->getParam()->getRes().mLod) {
+ if (lod->mDisableConstActor.ref())
+ mFlags14.set(0x1000000);
+ mDistanceScale = lod->mDistanceScale.ref();
+ if (lod->mDisableCalcRescueDistLimit.ref())
+ mFlags14.set(0x4000000);
+ }
+
+ int type = 8;
+ if (mActor->getProfile().include("Giant") || mActor->getProfile().include("Guardian")) {
+ type = 1;
+ } else if (mActor->getProfile().include("Enemy") || mActor->getProfile().include("Swarm") ||
+ mActor->getProfile().include("EnemySwarm")) {
+ type = 0;
+ } else if (mActor->getProfile() == "NPC") {
+ type = 2;
+ } else if (mActor->getProfile().include("Horse")) {
+ type = 7;
+ } else if (mActor->getName().include("Insect")) {
+ type = 4;
+ } else if (mActor->getName().include("Fish")) {
+ type = 5;
+ } else if (mActor->getName().include("Weapon")) {
+ type = 6;
+ } else if (mActor->getName().include("Animal")) {
+ type = 3;
+ }
+ mActorType = type;
+ _70 = 60;
+
+ float dist = 500.0f;
+
+ if (!hasTag(mActor, tags::Door)) {
+ if (mActor->getName() == "SignalFireWood" ||
+ mActor->getName() == "DgnObj_EntranceShutter_A_01" ||
+ mActor->getName() == "DgnObj_WarpPoint_A_01" ||
+ mActor->getName() == "DgnObj_EntranceTerminal_A_01" ||
+ mActor->getName().startsWith("DgnObj_DungeonEntrance_A_01") ||
+ mActor->getName().startsWith("DgnObj_RemainsLithograph_A") ||
+ mActor->getName().startsWith("DgnObj_RemainsLithogragh_A") ||
+ mActor->getName() == "GreatFairyBeforeRevival" ||
+ mActor->getName() == "TwnObj_FairySpringClose_A_01" ||
+ mActor->getName() == "TwnObj_FairySpring_A_01" ||
+ mActor->getName() == "Rito_BrosRock_Relief" ||
+ mActor->getName() == "TwnObj_HyruleCastleSealCover_A_01" ||
+ mActor->getName() == "FldObj_DownloadTerminalBody_A_01" ||
+ mActor->getName() == "FldObj_DownloadTerminal_A_01" ||
+ mActor->getName() == "FldObj_MapTowerWingBefore_A_01" ||
+ mActor->getName() == "FldObj_MapTower_A_01" ||
+ mActor->getName().startsWith("Item_CookSet") ||
+ mActor->getName() == "DgnObj_WarpPointSP" ||
+ mActor->getName() == "DgnObj_EntranceTerminalSP" ||
+ mActor->getName() == "DgnObj_EntranceShutterSP" ||
+ mActor->getName() == "DgnObj_EntranceElevatorSP" ||
+ mActor->getName() == "DgnObj_DLC_ChampionsDungeonEntrance_A_01" ||
+ mActor->getName().startsWith("FldObj_DLC_HeroMapRelief_Mark_A") ||
+ mActor->getName().startsWith("FldObj_DLC_HeroMap_") ||
+ mActor->getName() == "FldObj_DLC_HeroMapRelief_A_01") {
+ _70 = 60;
+ dist = 10.0f;
+ } else if (mActor->getName() == "Bros_Rock_01" || mActor->getName() == "Bros_Rock_02" ||
+ mActor->getName() == "Bros_Rock_03" || mActor->getName() == "Bros_Rock_04" ||
+ mActor->getName() == "Bros_Rock_05") {
+ _70 = 60;
+ dist = 30.0f;
+ } else if (mActor->getName() == "TwnObj_GanonGrudgeSolid_Eyeball_A_01") {
+ _70 = 60;
+ dist = 110.0f;
+ } else if (mActor->getName().include("TwnObj_HyruleCastleObject") ||
+ mActor->getName().include("TwnObj_HyruleCastle_GateBridgeDoor")) {
+ _70 = 60;
+ dist = 50.0f;
+ } else if (mActor->getName() == "WallCrack" || mActor->getName() == "Obj_RockBroken_A_02" ||
+ mActor->getName() == "TwnObj_HyruleCastleSealCover_A_01" ||
+ mActor->getName() == "TwnObj_HyruleCastleMap_BossModel_A_01") {
+ _70 = 120;
+ dist = 100.0f;
+ } else if (mActor->getName().startsWith("MergedGrudge") && mActor->getMapObject()) {
+ int field_body_group = -1;
+ mActor->getMapObject()->getMubinIter().tryGetParamIntByKey(&field_body_group,
+ "FieldBodyGroup");
+ if (field_body_group >= 0) {
+ dist = 500.0f;
+ } else {
+ _70 = 60;
+ dist = 10.0f;
+ }
+ } else if (mActor->getName() == "FldObj_GoronCannonSwitch_A_01" ||
+ mActor->getName() == "FldObj_GoronCannon_A_01") {
+ _70 = 120;
+ dist = 50.0f;
+ } else if (mActor->getName().startsWith("Mannequin_")) {
+ _70 = 120;
+ dist = 5.0f;
+ } else if (mActor->getName().startsWith("KorokAnswerResponce") ||
+ mActor->getName().startsWith("FldObj_AreaStopClimbing")) {
+ _70 = 900;
+ dist = 0.0f;
+ } else if (is_air_octa_platform) {
+ _24 = 0;
+ u32 hashid = 0;
+ if (!actor->getMapObjIter().tryGetParamUIntByKey(&hashid, "HashId") ||
+ (hashid != 0x8F7A380B && hashid != 0x57F2CB61)) {
+ _78 = 85.0f;
+ mFlags26.set(0x30);
+ }
+ }
+ }
+
+ auto* pm = map::PlacementMgr::instance();
+ map::PlacementAreaMgr* ps1 = nullptr;
+ if (pm && pm->mPlacementActors && (ps1 = pm->mPlacementActors->mStruct1)) {
+ if (!ps1->mIsOneHitChallengeActive) {
+ if (ps1->mFlags.isOn(map::PlacementAreaMgr::Flag::FinalTrial)) {
+ if (actor->getName() == "DgnObj_DLC_IbutsuEx_Candle_A_01" ||
+ actor->getName() == "TBox_Dungeon_Stone" ||
+ actor->getName() == "DgnObj_DLC_SwordLight_A_01") {
+ _70 = 240;
+ dist = 10.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuExLava_A_01" ||
+ actor->getName() == "DgnObj_DLC_SwitchStep_A_01" ||
+ actor->getName() == "DgnObj_DLC_CapShutter" ||
+ actor->getName() == "DgnObj_DLC_IbutsuExD_AncientBallSwitch_A_01" ||
+ actor->getName() == "DungeonPit") {
+ _70 = 120;
+ dist = 50.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEx_F_GoalSystem_A_01" ||
+ actor->getName() == "DgnObj_DLC_GoalShield_A" ||
+ actor->getName() == "Npc_DungeonPriestDlc2nd_Boss" ||
+ actor->getName() == "DgnObj_DLC_IbutsuExFloor_A_02") {
+ _70 = 15;
+ dist = 30.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuExOutWall_A_01") {
+ _70 = 240;
+ dist = 0.0f;
+ } else if (actor->getName().include("CylinderWall")) {
+ _70 = 240;
+ dist = 65.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEx_A_01") {
+ _70 = 240;
+ dist = 125.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEx_F_02") {
+ _70 = 60;
+ dist = 30.0f;
+ } else if (actor->getName() == "DgnObj_RemainsTerminalBody_A" ||
+ actor->getName() == "FldObj_Terminal_A_01" ||
+ actor->getName() == "DgnObj_DLC_ShutterFence_A_01" ||
+ actor->getName() == "FldObj_DownloadTerminal_A_01" ||
+ actor->getName() == "EventTag") {
+ _70 = 60;
+ dist = 30.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEx_E_Faucet_A_01" ||
+ actor->getName() == "DgnObj_DLC_IbutsuEx_E_Faucet_A_02" ||
+ actor->getName() == "SwitchTimeLag" || actor->getName() == "Area" ||
+ actor->getName() == "ActorObserverTag") {
+ _70 = 60;
+ dist = 80.0f;
+ } else if (actor->getName() == "DgnObj_DLC_ShutterFence_A_01" ||
+ actor->getName() == "DgnObj_DLC_ShutterFenceFrame_A_01") {
+ _70 = 60;
+ dist = 120.0f;
+ } else if (actor->getName() == "DgnObj_ElectricCable_FinalTrial" ||
+ actor->getName() == "DgnObj_SwitchElectric0_FinalTrial" ||
+ actor->getName() == "DgnObj_DLC_IbutsuEx_B_ElectricWire_A_02") {
+ _70 = 60;
+ dist = 90.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEx_B_MagnePoleAcceptor_A_01") {
+ _70 = 60;
+ dist = 75.0f;
+ } else if (actor->getName() == "ElectricGenerator") {
+ _70 = 60;
+ dist = 35.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuExD_Hole_A_02") {
+ _70 = 60;
+ dist = 100.0f;
+ } else if (actor->getName() == "DgnObj_AncientBall_B_01") {
+ _70 = 60;
+ dist = 90.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEXD_FirePillar_A_01" ||
+ actor->getName() == "DgnObj_DLC_IbutsuEXD_FirePillar_A_02") {
+ _70 = 60;
+ dist = 75.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuExD_WallSpike_A_01" ||
+ actor->getName() == "DgnObj_DLC_IbutsuExD_Cylinder_A_01") {
+ _70 = 60;
+ dist = 60.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEx_E_WaterPump_A_01" ||
+ actor->getName() == "DgnObj_DungeonWater50x50_A_01") {
+ _70 = 60;
+ dist = 100.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEx_E_WaterPump_A_02") {
+ _70 = 60;
+ dist = 140.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEx_E_WaterPump_A_03") {
+ _70 = 60;
+ dist = 75.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEx_E_Shaft_A_01" ||
+ actor->getName() == "DgnObj_DLC_IbutsuObj_StonePoleAcceptor_A_01") {
+ _70 = 60;
+ dist = 50.0f;
+ } else if (actor->getName() == "DgnObj_DLC_IbutsuEx_E_Scaffold_A_02" ||
+ actor->getName() == "DgnObj_DLC_IbutsuEx_E_Scaffold_A_03") {
+ _70 = 60;
+ dist = 60.0f;
+ }
+ }
+ } else {
+ if (actor->getName() == "FldObj_FlagLarge_A_01") {
+ _70 = 120;
+ dist = 70.0f;
+ } else if (actor->getName() == "FldObj_SoilRock_MapTower_A_01" ||
+ actor->getName() == "TwnObj_HunterHouseLamp_A_02") {
+ _70 = 900;
+ dist = 0.0f;
+ } else if (actor->getName() == "TwnObj_GoddesStatue_A_01" ||
+ actor->getName() == "FireWoodDie") {
+ _70 = 120;
+ dist = 50.0f;
+ } else if (actor->getName().include("FenceWoodDamage") ||
+ actor->getName().startsWith("FldObj_Damage")) {
+ _70 = 30;
+ dist = 13.0f;
+ } else if (actor->getName().include("ShieldFence")) {
+ _70 = 30;
+ dist = 30.0f;
+ }
+ }
+ }
+ _6c = dist * dist;
+
+ float value_68 = 1.0;
+ if (mActor->getName().startsWith("Enemy_Lynel")) {
+ value_68 = 2.0;
+ }
+ _68 = value_68;
+
+ if (actor->getName() == "Npc_RitoHatago001" || actor->getName() == "Npc_TabantaHatago001" ||
+ actor->getName() == "Npc_FaronWoods001") {
+ mFlags8.set(0x100000000);
+ }
+
+ if (actor->getName().startsWith("Npc_Zora") && !actor->getName().isEqual("Npc_Zora003") &&
+ !actor->getName().isEqual("Npc_ZoraB001") && !actor->getName().isEqual("Npc_Zora004")) {
+ mFlags8.set(0x200000000);
+ }
+
+ _74 = 0.0f;
+ if (actor->checkFlag(Actor::ActorFlag::_29) && actor->getProfile() == "NPC") {
+ _74 = 900.0f;
+ }
+
+ if (actor->getName().startsWith("FldObj_FlagLarge")) {
+ _50 = 3.0f;
+ }
+}
+
+LodState::~LodState() {
+ if (mOcclusionQueryCylinder)
+ delete mOcclusionQueryCylinder;
+}
+
+// NON_MATCHING: ????? reordering
+void LodState::initFlags() {
+ _28 = 1.0;
+ _40 = 0.0;
+ mFlags26.reset(2);
+ mFlags8.set(0xFFFFFFFF'00000000);
+ if (!mFlags8.isOn(0x20000000)) {
+ mFlags8.reset(0xEFFFFFFF);
+ mFlags8.set(0xCFC360BF);
+ mFlags8.reset(0x40);
+ } else {
+ mFlags8.set(0xEFFFFFFF);
+ mFlags8.set(0xEFC360BF);
+ mFlags8.reset(0x40);
+ }
+ mFlags8.reset(0x3C9F00);
+ mFlags8.set(0x4000);
+ mFlags14.set(0x2000000);
+ _60 = 0xFFFF;
+ _64 = -3;
+}
+
+} // namespace ksys::act