mirror of https://github.com/zeldaret/botw.git
Merge pull request #81 from ThePixelGamer/PlacementStruct
PlacementStruct1
This commit is contained in:
commit
0e00e340ee
|
@ -73108,35 +73108,35 @@ Address,Quality,Size,Name
|
|||
0x0000007100d1c81c,U,000156,ActorQuestLink::x_2
|
||||
0x0000007100d1c8b8,U,000004,nullsub_3740
|
||||
0x0000007100d1c8bc,U,000004,j__ZdlPv_840
|
||||
0x0000007100d1c8c0,U,001536,PlacementStruct1::ctor
|
||||
0x0000007100d1cec0,U,000012,PlacementStruct1::dtor
|
||||
0x0000007100d1cecc,U,005804,PlacementStruct1::parseObj
|
||||
0x0000007100d1e578,U,001080,PlacementStruct1::x
|
||||
0x0000007100d1e9b0,U,000372,PlacementStruct1::x_1
|
||||
0x0000007100d1eb24,U,002484,PlacementStruct1::postPlaceActorsUpdateFlagsAndLazyTraverse
|
||||
0x0000007100d1f4d8,U,000244,placement::getIsPlayedDemo145AndFirstInCastleBossRoom
|
||||
0x0000007100d1f5cc,U,000360,PlacementStruct1::x_8
|
||||
0x0000007100d1f734,U,000460,PlacementStruct1::x_7
|
||||
0x0000007100d1f900,U,000460,PlacementStruct1::x_5
|
||||
0x0000007100d1facc,U,000460,PlacementStruct1::x_6
|
||||
0x0000007100d1fc98,U,000388,PlacementStruct1::x_10
|
||||
0x0000007100d1fe1c,U,000092,
|
||||
0x0000007100d1fe78,U,003412,PlacementStruct1::shouldSkipSpawnOneHitChallengeActor
|
||||
0x0000007100d20bcc,U,003772,PlacementStruct1::shouldSkipSpawn
|
||||
0x0000007100d21a88,U,000436,PlacementStruct1::x_3
|
||||
0x0000007100d21c3c,U,000416,PlacementStruct1::x_2
|
||||
0x0000007100d21ddc,U,001820,PlacementStruct1::x_9
|
||||
0x0000007100d224f8,U,000436,PlacementStruct1::x_12
|
||||
0x0000007100d226ac,U,000700,
|
||||
0x0000007100d22968,U,000724,
|
||||
0x0000007100d22c3c,U,000700,
|
||||
0x0000007100d22ef8,U,000724,
|
||||
0x0000007100d231cc,U,001728,PlacementStruct1::x_11
|
||||
0x0000007100d2388c,U,002640,PlacementStruct1::x_4
|
||||
0x0000007100d242dc,U,000292,PlacementStruct1::x_13
|
||||
0x0000007100d24400,U,000156,PlacementStruct1::postPlaceActors1
|
||||
0x0000007100d2449c,U,000412,PlacementStruct1::x_0
|
||||
0x0000007100d24638,U,000684,sinitPlacementStruct1
|
||||
0x0000007100d1c8c0,W,001536,_ZN4ksys3map16PlacementAreaMgrC1Ev
|
||||
0x0000007100d1cec0,O,000012,_ZN4ksys3map16PlacementAreaMgrD1Ev
|
||||
0x0000007100d1cecc,W,005804,_ZN4ksys3map16PlacementAreaMgr10parseAreasERKN4sead14SafeStringBaseIcEERKNS0_9MubinIterE
|
||||
0x0000007100d1e578,U,001080,_ZN4ksys3map16PlacementAreaMgr1xEv
|
||||
0x0000007100d1e9b0,O,000372,_ZN4ksys3map16PlacementAreaMgr11addLinkPairERKiS3_
|
||||
0x0000007100d1eb24,U,002484,PlacementAreaMgr::postPlaceActorsUpdateFlagsAndLazyTraverse
|
||||
0x0000007100d1f4d8,U,000244,PlacementAreaMgr::getIsPlayedDemo145AndFirstInCastleBossRoom
|
||||
0x0000007100d1f5cc,O,000360,_ZN4ksys3map16PlacementAreaMgr20insideInnerHideTransERKi
|
||||
0x0000007100d1f734,O,000460,_ZN4ksys3map16PlacementAreaMgr19insideInnerHideBaseERKi
|
||||
0x0000007100d1f900,O,000460,_ZN4ksys3map16PlacementAreaMgr19insideInnerHideCalcERKi
|
||||
0x0000007100d1facc,O,000460,_ZN4ksys3map16PlacementAreaMgr19insideInnerHideLoadERKi
|
||||
0x0000007100d1fc98,O,000388,_ZN4ksys3map16PlacementAreaMgr15loadDemoCullingERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d1fe1c,O,000092,_ZN4ksys3map16PlacementAreaMgr17unloadDemoCullingEv
|
||||
0x0000007100d1fe78,U,003412,PlacementAreaMgr::shouldSkipSpawnOneHitChallengeActor
|
||||
0x0000007100d20bcc,U,003772,PlacementAreaMgr::shouldSkipSpawn
|
||||
0x0000007100d21a88,O,000436,_ZN4ksys3map16PlacementAreaMgr19insideInnerHideBaseERKN4sead7Vector3IfEERKfRKi
|
||||
0x0000007100d21c3c,O,000416,_ZN4ksys3map16PlacementAreaMgr17isPlayerInsideNpcERKN4sead7Vector3IfEE
|
||||
0x0000007100d21ddc,U,001820,PlacementAreaMgr::boundsChecking
|
||||
0x0000007100d224f8,O,000436,_ZN4ksys3map16PlacementAreaMgr19insideInnerHideCalcERKN4sead7Vector3IfEERKfRKi
|
||||
0x0000007100d226ac,O,000700,_ZN4ksys3map16PlacementAreaMgr15insideAlphaBaseERKN4sead7Vector3IfEERKf
|
||||
0x0000007100d22968,O,000724,_ZN4ksys3map16PlacementAreaMgr15insideOmegaBaseEv
|
||||
0x0000007100d22c3c,O,000700,_ZN4ksys3map16PlacementAreaMgr15insideOmegaBaseERKN4sead7Vector3IfEERKf
|
||||
0x0000007100d22ef8,O,000724,_ZN4ksys3map16PlacementAreaMgr15insideAlphaBaseEv
|
||||
0x0000007100d231cc,U,001728,PlacementAreaMgr::boundsChecking_1
|
||||
0x0000007100d2388c,U,002640,PlacementAreaMgr::weirdSetup
|
||||
0x0000007100d242dc,O,000292,_ZN4ksys3map16PlacementAreaMgr11isInsideNpcERKN4sead7Vector3IfEE
|
||||
0x0000007100d24400,U,000156,PlacementAreaMgr::pushFarModels
|
||||
0x0000007100d2449c,U,000412,PlacementAreaMgr::x_0
|
||||
0x0000007100d24638,U,000684,_GLOBAL__sub_I_mapPlacementAreaMgr.cpp
|
||||
0x0000007100d248e4,O,000044,_ZN4ksys3act2ai8BehaviorC1ERKNS2_7InitArgE
|
||||
0x0000007100d24910,U,000256,AI_BehaviorBase::init
|
||||
0x0000007100d24a10,U,000176,
|
||||
|
|
Can't render this file because it is too large.
|
|
@ -3,6 +3,7 @@
|
|||
#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"
|
||||
|
@ -156,10 +157,10 @@ LodState::LodState(sead::Heap* heap, sead::BitFlag32 flags, Actor* actor,
|
|||
}
|
||||
|
||||
auto* pm = map::PlacementMgr::instance();
|
||||
map::PlacementStruct1* ps1 = nullptr;
|
||||
map::PlacementAreaMgr* ps1 = nullptr;
|
||||
if (pm && pm->mPlacementActors && (ps1 = pm->mPlacementActors->mStruct1)) {
|
||||
if (!ps1->mIsOneHitChallengeActive) {
|
||||
if (ps1->mFlags.isOnBit(15)) {
|
||||
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") {
|
||||
|
|
|
@ -14,6 +14,8 @@ target_sources(uking PRIVATE
|
|||
mapObjectLink.h
|
||||
mapPlacementActors.cpp
|
||||
mapPlacementActors.h
|
||||
mapPlacementAreaMgr.cpp
|
||||
mapPlacementAreaMgr.h
|
||||
mapPlacementMap.cpp
|
||||
mapPlacementMap.h
|
||||
mapPlacementMapMgr.cpp
|
||||
|
|
|
@ -15,6 +15,8 @@ public:
|
|||
void updateFlags();
|
||||
bool wereFlagsUpdated();
|
||||
|
||||
bool empty() const { return !mHasEntries; }
|
||||
|
||||
private:
|
||||
struct Entry {
|
||||
sead::FixedSafeString<0x40> flag_name;
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace ksys::map {
|
|||
|
||||
class Object;
|
||||
class PlacementMap;
|
||||
class PlacementAreaMgr;
|
||||
|
||||
// TODO: rename
|
||||
enum class ActorFlag8 {
|
||||
|
@ -103,13 +104,6 @@ public:
|
|||
};
|
||||
KSYS_CHECK_SIZE_NX150(ActorData, 0x1A0);
|
||||
|
||||
// FIXME: incomplete
|
||||
class PlacementStruct1 {
|
||||
public:
|
||||
sead::BitFlag16 mFlags;
|
||||
bool mIsOneHitChallengeActive;
|
||||
};
|
||||
|
||||
class PlacementActors {
|
||||
public:
|
||||
u32 getNumStaticObjs() const;
|
||||
|
@ -124,7 +118,7 @@ public:
|
|||
|
||||
u8 _0[0x28 - 0x0];
|
||||
sead::ReadWriteLock mLock;
|
||||
PlacementStruct1* mStruct1;
|
||||
PlacementAreaMgr* mStruct1;
|
||||
u8 _e8[0x538 - 0xe8];
|
||||
sead::SafeArray<ActorData, 6000> mActorData;
|
||||
u8 _261b38[0x2a8058 - 0x261b38];
|
||||
|
|
|
@ -0,0 +1,640 @@
|
|||
#include "KingSystem/Map/mapPlacementAreaMgr.h"
|
||||
|
||||
#include "KingSystem/Map/mapLazyTraverseList.h"
|
||||
#include "KingSystem/Map/mapMubinIter.h"
|
||||
#include "KingSystem/Map/mapObject.h"
|
||||
#include "KingSystem/Map/mapObjectLink.h"
|
||||
#include "KingSystem/Utils/MathUtil.h"
|
||||
|
||||
#include <math/seadMatrix.h>
|
||||
|
||||
namespace ksys::map {
|
||||
|
||||
static s32 s_npc_count = 0;
|
||||
|
||||
enum class UnkFlag : u8 {
|
||||
_1 = 1 << 0,
|
||||
_2 = 1 << 1,
|
||||
_4 = 1 << 2,
|
||||
_20 = 1 << 5,
|
||||
_40 = 1 << 6,
|
||||
_80 = 1 << 7
|
||||
};
|
||||
static sead::TypedBitFlag<UnkFlag> s_unk_flag;
|
||||
|
||||
static sead::SafeArray<float, 26> s_npc_scales = {
|
||||
{0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.85f, 0.6f, 0.75f, 0.6f, 0.6f, 0.6f, 0.6f,
|
||||
0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.75f, 0.6f, 0.6f}};
|
||||
|
||||
// NON_MATCHING: weird memsets, hard to replicate
|
||||
PlacementAreaMgr::PlacementAreaMgr() {
|
||||
mInnerHideCount = 0;
|
||||
mPlayerPos = sead::Vector3f::zero;
|
||||
mActiveNpc = 0;
|
||||
|
||||
if (mObjects && !mObjects->empty()) {
|
||||
s_unk_flag.set(UnkFlag::_80);
|
||||
}
|
||||
|
||||
mJudgeAreaCount = 0;
|
||||
_2a468Count = 0;
|
||||
mGeneralAreasCount = 0;
|
||||
_2d5c4 = 0.0f;
|
||||
mOptAreasCount = 0;
|
||||
mFarModelsCount = 0;
|
||||
mIntroArea = nullptr;
|
||||
mFlags.set(Flag::_10);
|
||||
}
|
||||
|
||||
PlacementAreaMgr::~PlacementAreaMgr() {
|
||||
s_npc_count = 0;
|
||||
}
|
||||
|
||||
// NON_MATCHING: many various parts don't match but should be a template
|
||||
bool PlacementAreaMgr::parseAreas(const sead::SafeString& unit_config_name,
|
||||
const MubinIter& obj_iter) {
|
||||
if (unit_config_name == "AreaCulling_InnerHide") {
|
||||
auto& area = mInnerHide[mInnerHideCount++];
|
||||
SRT srt;
|
||||
obj_iter.getSRT(&srt);
|
||||
|
||||
bool hide = true;
|
||||
obj_iter.tryGetParamBoolByKey(&hide, "HideOutSide");
|
||||
area.params.hide_out_side = hide;
|
||||
|
||||
s32 culling = 0;
|
||||
obj_iter.tryGetIntByKey(&culling, "CullingOption");
|
||||
switch (static_cast<Unknown1::CullingOption>(culling)) {
|
||||
case Unknown1::CullingOption::_0:
|
||||
area.params.culling = Unknown1::CullingType::None;
|
||||
break;
|
||||
case Unknown1::CullingOption::_1:
|
||||
area.params.culling = Unknown1::CullingType::Culling_1;
|
||||
break;
|
||||
case Unknown1::CullingOption::_2:
|
||||
area.params.culling = Unknown1::CullingType::Culling_3;
|
||||
break;
|
||||
case Unknown1::CullingOption::_3:
|
||||
area.params.culling = Unknown1::CullingType::Culling_F;
|
||||
break;
|
||||
case Unknown1::CullingOption::_4:
|
||||
area.params.culling = Unknown1::CullingType::Culling_1F;
|
||||
break;
|
||||
case Unknown1::CullingOption::_5:
|
||||
area.params.culling = Unknown1::CullingType::Culling_33;
|
||||
break;
|
||||
case Unknown1::CullingOption::_6:
|
||||
area.params.culling = Unknown1::CullingType::Culling_3B;
|
||||
break;
|
||||
case Unknown1::CullingOption::_7:
|
||||
area.params.culling = Unknown1::CullingType::Culling_1B;
|
||||
break;
|
||||
case Unknown1::CullingOption::_8:
|
||||
area.params.culling = Unknown1::CullingType::Culling_18;
|
||||
break;
|
||||
case Unknown1::CullingOption::_9:
|
||||
area.params.culling = Unknown1::CullingType::Culling_10;
|
||||
break;
|
||||
case Unknown1::CullingOption::_A:
|
||||
area.params.culling = Unknown1::CullingType::Culling_13;
|
||||
break;
|
||||
case Unknown1::CullingOption::_B:
|
||||
area.params.culling = Unknown1::CullingType::Culling_43;
|
||||
break;
|
||||
case Unknown1::CullingOption::_C:
|
||||
area.params.culling = Unknown1::CullingType::Culling_9B;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool connect;
|
||||
obj_iter.tryGetBoolByKey(&connect, "IsConnectNeighborArea");
|
||||
area.params.is_connect_neighbor_area = connect;
|
||||
|
||||
area.hide_room_num = 0xFF;
|
||||
obj_iter.tryGetParamUInt8ByKey(&area.hide_room_num, "HideRoomNum");
|
||||
|
||||
bool weirdCheck = false;
|
||||
// is this some sort of hack?
|
||||
if (srt.translate.x > -440.0f && srt.translate.x < -436.0f && srt.translate.z > -1036.0f &&
|
||||
srt.translate.z < -1032.0f) {
|
||||
srt.scale.x = 27.863f;
|
||||
srt.translate.x = -439.24f;
|
||||
weirdCheck = true;
|
||||
srt.translate.z = -1033.4f;
|
||||
srt.scale.z = 40.908f;
|
||||
}
|
||||
|
||||
area.translate = srt.translate;
|
||||
|
||||
float scale = sead::Mathf::max3(srt.scale.x, srt.scale.y, srt.scale.z); // same logic
|
||||
|
||||
float calcMaxSize = sead::Mathf::max(scale * 0.5f, 4.0f);
|
||||
float calcXPlus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&calcXPlus, "CalcMarginXPlus");
|
||||
float calcXMinus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&calcXMinus, "CalcMarginXMinus");
|
||||
float calcYPlus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&calcYPlus, "CalcMarginYPlus");
|
||||
float calcYMinus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&calcYMinus, "CalcMarginYMinus");
|
||||
float calcZPlus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&calcZPlus, "CalcMarginZPlus");
|
||||
float calcZMinus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&calcZMinus, "CalcMarginZMinus");
|
||||
|
||||
if (weirdCheck) {
|
||||
calcXMinus = 3.0f;
|
||||
}
|
||||
|
||||
if (calcXPlus < 0.0f) {
|
||||
calcXPlus = calcMaxSize;
|
||||
}
|
||||
if (calcXMinus < 0.0f) {
|
||||
calcXMinus = calcMaxSize;
|
||||
}
|
||||
if (calcYPlus < 0.0f) {
|
||||
calcYPlus = calcMaxSize;
|
||||
}
|
||||
if (calcYMinus < 0.0f) {
|
||||
calcYMinus = calcMaxSize;
|
||||
}
|
||||
if (calcZPlus < 0.0f) {
|
||||
calcZPlus = calcMaxSize;
|
||||
}
|
||||
if (calcZMinus < 0.0f) {
|
||||
calcZMinus = calcMaxSize;
|
||||
}
|
||||
|
||||
float loadMaxSize = calcMaxSize * 1.75f;
|
||||
float loadXPlus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&loadXPlus, "LoadMarginXPlus");
|
||||
float loadXMinus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&loadXMinus, "LoadMarginXMinus");
|
||||
float loadYPlus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&loadYPlus, "LoadMarginYPlus");
|
||||
float loadYMinus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&loadYMinus, "LoadMarginYMinus");
|
||||
float loadZPlus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&loadZPlus, "LoadMarginZPlus");
|
||||
float loadZMinus = -1.0f;
|
||||
obj_iter.tryGetParamFloatByKey(&loadZMinus, "LoadMarginZMinus");
|
||||
|
||||
if (loadXPlus < 0.0f) {
|
||||
loadXPlus = loadMaxSize;
|
||||
}
|
||||
if (loadXMinus < 0.0f) {
|
||||
loadXMinus = loadMaxSize;
|
||||
}
|
||||
if (loadYPlus < 0.0f) {
|
||||
loadYPlus = loadMaxSize;
|
||||
}
|
||||
if (loadYMinus < 0.0f) {
|
||||
loadYMinus = loadMaxSize;
|
||||
}
|
||||
if (loadZPlus < 0.0f) {
|
||||
loadZPlus = loadMaxSize;
|
||||
}
|
||||
if (loadZMinus < 0.0f) {
|
||||
loadZMinus = loadMaxSize;
|
||||
}
|
||||
|
||||
// same code in AreaCulling_TwinsHide
|
||||
area.base = Axis{srt.scale};
|
||||
area.calc = Axis{srt.scale + sead::Vector3f{calcXPlus, calcYPlus, calcZPlus},
|
||||
srt.scale + sead::Vector3f{calcXMinus, calcYMinus, calcZMinus}};
|
||||
area.load = Axis{srt.scale + sead::Vector3f{loadXPlus, loadYPlus, loadZPlus},
|
||||
srt.scale + sead::Vector3f{loadXMinus, loadYMinus, loadZMinus}};
|
||||
area._d8 = Axis{-sead::Vector3f::ones};
|
||||
|
||||
sead::Matrix33f m;
|
||||
m.makeR(srt.rotate);
|
||||
|
||||
for (size_t i = 0; i < 6; ++i) {
|
||||
area.base[i] = srt.translate + (m * area.base[i]);
|
||||
area.calc[i] = srt.translate + (m * area.calc[i]);
|
||||
area.load[i] = srt.translate + (m * area.load[i]);
|
||||
area._d8[i] = m * area._d8[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (unit_config_name == "AreaCulling_OuterNPCMementary") {
|
||||
if (s_npc_count > 25) { // this if statement has ++ but this structure makes more sense
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& area = mNpc[s_npc_count++];
|
||||
SRT srt;
|
||||
|
||||
obj_iter.getSRT(&srt);
|
||||
area.translate = srt.translate;
|
||||
area.scale = srt.scale.x;
|
||||
return true;
|
||||
} else if (unit_config_name.include("AreaCulling_TwinsHide")) { // no objects
|
||||
Unknown1* area;
|
||||
if (unit_config_name.include("Alpha")) {
|
||||
area = &mAlpha; // 2980C
|
||||
} else if (unit_config_name.include("Omega")) {
|
||||
area = &mOmega; // 29958
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
SRT srt;
|
||||
obj_iter.getSRT(&srt);
|
||||
area->translate = srt.translate;
|
||||
|
||||
area->base = Axis{srt.scale};
|
||||
area->calc = Axis{srt.scale};
|
||||
area->load = Axis{-sead::Vector3f::ones};
|
||||
area->_d8 = Axis{-sead::Vector3f::ones};
|
||||
|
||||
sead::Matrix33f m;
|
||||
m.makeR(srt.rotate);
|
||||
|
||||
for (size_t i = 0; i < 6; ++i) {
|
||||
area->base[i] = srt.translate + (m * area->base[i]);
|
||||
area->calc[i] = srt.translate + (m * area->calc[i]);
|
||||
area->load[i] = srt.translate + (m * area->load[i]);
|
||||
area->_d8[i] = m * area->_d8[i];
|
||||
}
|
||||
|
||||
s_unk_flag.set(UnkFlag::_40);
|
||||
return true;
|
||||
} else if (unit_config_name == "AreaCulling_JudgeArea") { // no objects
|
||||
SRT srt;
|
||||
auto& area = mJudgeArea[mJudgeAreaCount++];
|
||||
|
||||
obj_iter.getSRT(&srt);
|
||||
area.bb.set(srt.translate - srt.scale, srt.translate + srt.scale);
|
||||
|
||||
MubinIter links;
|
||||
if (!obj_iter.tryGetParamIterByKey(&links, "LinksToObj")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < links.getSize(); ++i) {
|
||||
MubinIter iter;
|
||||
if (links.tryGetIterByIndex(&iter, i)) {
|
||||
u32 _id = 0;
|
||||
if (iter.tryGetParamUIntByKey(&_id, "DestUnitHashId")) {
|
||||
area.parent_ids[area.parent_count++] = _id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (unit_config_name.include("AreaCulling_")) { // only InnerOn?
|
||||
auto& area = mGeneralAreas[mGeneralAreasCount++];
|
||||
SRT srt;
|
||||
|
||||
obj_iter.getSRT(&srt);
|
||||
area.bb.set(srt.translate - srt.scale, srt.translate + srt.scale);
|
||||
obj_iter.tryGetParamUIntByKey(&area.id, "HashId");
|
||||
|
||||
area.type = GeneralArea::Type::None;
|
||||
|
||||
const char* param = nullptr;
|
||||
if (obj_iter.tryGetParamStringByKey(¶m, "UniqueName")) {
|
||||
if (sead::SafeString(param) == "LoadOpt") {
|
||||
area.type = GeneralArea::Type::LoadOpt;
|
||||
}
|
||||
}
|
||||
|
||||
if (area.type == GeneralArea::Type::LoadOpt) {
|
||||
auto& subArea = mOptAreas[mOptAreasCount++];
|
||||
subArea.parent_area = &area;
|
||||
subArea.id = "Demo102_0";
|
||||
} else {
|
||||
auto& subArea = mJudgeArea[mJudgeAreaCount++];
|
||||
sead::Vector3f offset{20.0f, 0.0f, 20.0f};
|
||||
subArea.bb.set(srt.translate - srt.scale - offset, srt.translate + srt.scale + offset);
|
||||
subArea.parent_ids[subArea.parent_count++] = 0;
|
||||
subArea.parent_areas[0] = &area;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (unit_config_name == "FarModelCullingArea") {
|
||||
auto& area = mFarModels[mFarModelsCount++];
|
||||
SRT srt;
|
||||
|
||||
obj_iter.getSRT(&srt);
|
||||
area.translate = srt.translate;
|
||||
area.rotate = srt.rotate;
|
||||
area.scale = srt.scale;
|
||||
area.id.format("Area_%04d", mFarModels.size() - 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PlacementAreaMgr::GeneralArea* PlacementAreaMgr::findGeneralArea(const u32& id) {
|
||||
for (int i = 0; i < mGeneralAreasCount; i++) {
|
||||
if (mGeneralAreas[i].id == id) {
|
||||
return &mGeneralAreas[i];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// NON_MATCHING: stack doesn't match, not sure if that's due to the first loop
|
||||
void PlacementAreaMgr::x() {
|
||||
s_unk_flag.set(UnkFlag::_20);
|
||||
s_unk_flag.set(UnkFlag::_4);
|
||||
s_unk_flag.set(UnkFlag::_2);
|
||||
s_unk_flag.set(UnkFlag::_1);
|
||||
|
||||
for (int i = 0; i < mInnerHideCount; i++) {
|
||||
auto& area = mInnerHide[i];
|
||||
|
||||
area._12c = isInsideNpcIdx(area.translate);
|
||||
area._130_count = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mInnerHideCount; i++) {
|
||||
auto& area = mInnerHide[i];
|
||||
|
||||
if (area.hide_room_num == 0xFF) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < mInnerHideCount; j++) {
|
||||
auto& subarea = mInnerHide[j];
|
||||
|
||||
if (i != j) {
|
||||
if (subarea.hide_room_num != 0xFF && area._12c == subarea._12c &&
|
||||
area.hide_room_num == subarea.hide_room_num) {
|
||||
area._130[area._130_count++] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mInnerHideCount; i++) {
|
||||
auto& area = mInnerHide[i];
|
||||
|
||||
if (area.params.is_connect_neighbor_area) {
|
||||
for (int j = 0; j < mInnerHideCount; j++) {
|
||||
auto& subarea = mInnerHide[j];
|
||||
|
||||
if (subarea.params.is_connect_neighbor_area && i != j) {
|
||||
if (area._12c == subarea._12c && (x_0(i, j) || x_0(j, i))) {
|
||||
addLinkPair(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mAlpha._12c = -1;
|
||||
mOmega._12c = -1;
|
||||
for (int i = 0; i < mJudgeAreaCount; i++) {
|
||||
auto& judgeArea = mJudgeArea[i];
|
||||
for (int j = 0; j < judgeArea.parent_count; j++) {
|
||||
auto& id = judgeArea.parent_ids[j];
|
||||
|
||||
if (id == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// doesn't necessarily exist, done to try and match
|
||||
judgeArea.parent_areas[j] = findGeneralArea(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlacementAreaMgr::Unknown1::addLink(const int& idx) {
|
||||
if (_130_count == 0) {
|
||||
_130[_130_count++] = idx;
|
||||
} else {
|
||||
// check to see if idx is in _130, add to end if not
|
||||
for (u8 i = 0; i < _130_count && _130[i] != idx; i++) {
|
||||
if (i == (_130_count - 1)) {
|
||||
_130[_130_count++] = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// weird logic because this would only trigger if _130_count was 6 in the loop
|
||||
if ((_130_count - 1) >= _130.size()) {
|
||||
--_130_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlacementAreaMgr::addLinkPair(const int& idx, const int& sub_idx) {
|
||||
mInnerHide[idx].addLink(sub_idx);
|
||||
mInnerHide[sub_idx].addLink(idx);
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::insideInnerHideTrans(const int& idx) {
|
||||
if (mActiveNpc != mInnerHide[idx]._12c) {
|
||||
return util::sqXZDistance(mPlayerPos, mInnerHide[idx].translate) <
|
||||
sead::Mathf::square(1000.0f);
|
||||
}
|
||||
|
||||
if (mActiveNpc == 5)
|
||||
return true;
|
||||
|
||||
if (mActiveNpc == 6) {
|
||||
return util::sqXZDistance(mPlayerPos, mInnerHide[idx].translate) <
|
||||
sead::Mathf::square(500.0f);
|
||||
}
|
||||
|
||||
if (mFlags.isOn(Flag::FinalTrial) || mFlags.isOn(Flag::_4000)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mFlags.isOff(Flag::Remains)) {
|
||||
if (mFlags.isOn(Flag::AocField)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mActiveNpc != 21 && mActiveNpc != 16 && mActiveNpc != 14 && mActiveNpc != 7 &&
|
||||
mActiveNpc != 2 && mActiveNpc != 0) {
|
||||
return util::sqXZDistance(mPlayerPos, mInnerHide[idx].translate) <
|
||||
sead::Mathf::square(200.0f);
|
||||
}
|
||||
}
|
||||
|
||||
return util::sqXZDistance(mPlayerPos, mInnerHide[idx].translate) < sead::Mathf::square(500.0f);
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::insideInnerHideBase(const int& idx) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((mPlayerPos - mInnerHide[idx].base[i]).dot(mInnerHide[idx]._d8[i]) < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::insideInnerHideCalc(const int& idx) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((mPlayerPos - mInnerHide[idx].calc[i]).dot(mInnerHide[idx]._d8[i]) < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::insideInnerHideLoad(const int& idx) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((mPlayerPos - mInnerHide[idx].load[i]).dot(mInnerHide[idx]._d8[i]) < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::insideInnerHideBase(const sead::Vector3f& pos, const float& dist_from_face,
|
||||
const int& idx) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((pos - mInnerHide[idx].base[i]).dot(mInnerHide[idx]._d8[i]) <= dist_from_face) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::insideInnerHideCalc(const sead::Vector3f& pos, const float& dist_from_face,
|
||||
const int& idx) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((pos - mInnerHide[idx].calc[i]).dot(mInnerHide[idx]._d8[i]) <= dist_from_face) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::insideAlphaBase() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((mPlayerPos - mAlpha.base[i]).dot(mAlpha._d8[i]) < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::insideAlphaBase(const sead::Vector3f& pos, const float& dist_from_face) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((pos - mAlpha.base[i]).dot(mAlpha._d8[i]) < dist_from_face) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::insideOmegaBase() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((mPlayerPos - mOmega.base[i]).dot(mOmega._d8[i]) < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::insideOmegaBase(const sead::Vector3f& pos, const float& dist_from_face) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((pos - mOmega.base[i]).dot(mOmega._d8[i]) < dist_from_face) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::isPlayerInsideNpc(const sead::Vector3f& pos) {
|
||||
// matches with 2 && but this looks cleaner
|
||||
if (mActiveNpc >= 0 && !isInsideNpc(pos)) {
|
||||
if (util::sqXZDistance(mPlayerPos, mNpc[mActiveNpc].translate) <
|
||||
(mNpc[mActiveNpc].scale * s_npc_scales[mActiveNpc])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// used to try and simplify PlacementAreaMgr::x and PlacementAreaMgr::isInsideNpc logic
|
||||
// doesn't seem to match so maybe remove after matching x?
|
||||
s8 PlacementAreaMgr::isInsideNpcIdx(const sead::Vector3f& pos) {
|
||||
for (int i = 0; i < mNpc.size(); i++) {
|
||||
if (!mNpc[i].isInside(pos)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == 5) {
|
||||
if (mNpc[6].isInside(pos)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool PlacementAreaMgr::isInsideNpc(const sead::Vector3f& pos) {
|
||||
if (s_unk_flag.isOff(UnkFlag::_4)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX: what the heck Nintendo
|
||||
int i = 0;
|
||||
while (i < mNpc.size()) {
|
||||
if (i == 5) {
|
||||
if (mNpc[i].isInside(pos) && !mNpc[i + 1].isInside(pos)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (mNpc[i].isInside(pos)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PlacementAreaMgr::loadDemoCulling(const sead::SafeString& demo_name) {
|
||||
mIntroArea = nullptr;
|
||||
|
||||
for (int i = 0; i < mOptAreasCount; ++i) {
|
||||
auto& area = mOptAreas[i];
|
||||
|
||||
bool loaded = false;
|
||||
if (area.id == demo_name) {
|
||||
loaded = true;
|
||||
mIntroArea = &area;
|
||||
}
|
||||
area.parent_area->loaded = loaded;
|
||||
}
|
||||
}
|
||||
|
||||
void PlacementAreaMgr::unloadDemoCulling() {
|
||||
mIntroArea = nullptr;
|
||||
|
||||
for (int i = 0; i < mOptAreasCount; ++i) {
|
||||
mOptAreas[i].parent_area->loaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ksys::map
|
|
@ -0,0 +1,244 @@
|
|||
#pragma once
|
||||
|
||||
#include <container/seadSafeArray.h>
|
||||
#include <math/seadBoundBox.h>
|
||||
#include <math/seadVector.h>
|
||||
#include <prim/seadSafeString.h>
|
||||
#include <prim/seadTypedBitFlag.h>
|
||||
|
||||
#include "KingSystem/Map/mapStagePreActorCache.h"
|
||||
#include "KingSystem/Map/mapTypes.h"
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
|
||||
namespace ksys::gdt {
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace ksys::map {
|
||||
|
||||
class LazyTraverseList;
|
||||
class MubinIter;
|
||||
class Object;
|
||||
|
||||
class PlacementAreaMgr {
|
||||
// not "Axis" and probably not in this class but I dunno what it does
|
||||
// contains + and - of each x, y, z as a vector
|
||||
class Axis {
|
||||
public:
|
||||
Axis() = default;
|
||||
explicit Axis(const sead::Vector3f& v) : Axis(v, v) {}
|
||||
|
||||
// parameter names only based on default values
|
||||
Axis(const sead::Vector3f& plus, const sead::Vector3f& minus) {
|
||||
data[0] = {0.0f - minus.x, 0.0f, 0.0f};
|
||||
data[1] = {0.0f + plus.x, 0.0f, 0.0f};
|
||||
data[2] = {0.0f, 0.0f, 0.0f - minus.z};
|
||||
data[3] = {0.0f, 0.0f, 0.0f + plus.z};
|
||||
data[4] = {0.0f, 0.0f - minus.y, 0.0f};
|
||||
data[5] = {0.0f, 0.0f + plus.y, 0.0f};
|
||||
}
|
||||
|
||||
// needs an assert
|
||||
sead::Vector3f& operator[](size_t idx) { return data[idx]; }
|
||||
|
||||
const sead::Vector3f& operator[](size_t idx) const { return data[idx]; }
|
||||
|
||||
private:
|
||||
sead::Vector3f data[6]{};
|
||||
};
|
||||
|
||||
struct Unknown1 { // only params appears in PlacementAreaMgr's ctor
|
||||
// unsure about these culling enums and the params bitfield
|
||||
enum class CullingOption : s32 { _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _A, _B, _C };
|
||||
|
||||
enum class CullingType : u8 {
|
||||
None,
|
||||
Culling_1 = 1 << 0,
|
||||
Culling_2 = 1 << 1,
|
||||
Culling_4 = 1 << 2,
|
||||
Culling_8 = 1 << 3,
|
||||
Culling_10 = 1 << 4,
|
||||
Culling_20 = 1 << 5,
|
||||
Culling_40 = 1 << 6,
|
||||
Culling_80 = 1 << 7,
|
||||
|
||||
Culling_3 = Culling_2 | Culling_1,
|
||||
Culling_B = Culling_8 | Culling_3,
|
||||
Culling_F = Culling_8 | Culling_4 | Culling_3,
|
||||
Culling_13 = Culling_10 | Culling_3,
|
||||
Culling_18 = Culling_10 | Culling_8,
|
||||
Culling_1B = Culling_10 | Culling_B,
|
||||
Culling_1F = Culling_10 | Culling_F,
|
||||
Culling_30 = Culling_20 | Culling_10,
|
||||
Culling_33 = Culling_30 | Culling_3,
|
||||
Culling_3B = Culling_30 | Culling_B,
|
||||
Culling_43 = Culling_40 | Culling_3,
|
||||
Culling_9B = Culling_80 | Culling_1B,
|
||||
};
|
||||
|
||||
Axis base{}, calc{}, load{}, _d8{};
|
||||
sead::Vector3f translate{};
|
||||
s8 _12c; // something to do with _29C54/mActiveNpc
|
||||
u8 hide_room_num;
|
||||
u8 _130_count;
|
||||
sead::SafeArray<int, 6> _130{}; // used to index mInnerHide, parent idx?
|
||||
struct Params { // _148 : u16
|
||||
bool hide_out_side : 1;
|
||||
bool is_connect_neighbor_area : 1;
|
||||
bool _4 : 1;
|
||||
bool _8 : 1;
|
||||
bool _10 : 1;
|
||||
bool _20 : 1;
|
||||
CullingType culling : 8;
|
||||
} params{};
|
||||
KSYS_CHECK_SIZE_NX150(Params, 0x2);
|
||||
|
||||
// helpers
|
||||
Unknown1() { memset(¶ms, 0, sizeof(params)); }
|
||||
|
||||
void addLink(const int& idx); // unsure about name
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(Unknown1, 0x14C);
|
||||
|
||||
struct OuterNPCMementary {
|
||||
sead::Vector3f translate;
|
||||
f32 scale;
|
||||
|
||||
// should probably remove
|
||||
bool isInside(const sead::Vector3f& pos) const {
|
||||
return (pos - translate).squaredLength() < sead::Mathf::square(scale);
|
||||
}
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(OuterNPCMementary, 0x10);
|
||||
|
||||
struct GeneralArea { // InnerOn?
|
||||
enum class Type : u8 { None = 0, LoadOpt = 2 };
|
||||
|
||||
sead::BoundBox3f bb{};
|
||||
u32 id;
|
||||
Type type;
|
||||
bool loaded;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(GeneralArea, 0x20);
|
||||
|
||||
struct JudgeArea {
|
||||
sead::BoundBox3f bb{};
|
||||
sead::SafeArray<GeneralArea*, 8> parent_areas{};
|
||||
sead::SafeArray<u32, 8> parent_ids{};
|
||||
s32 parent_count = 0;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(JudgeArea, 0x80);
|
||||
|
||||
struct OptArea {
|
||||
GeneralArea* parent_area;
|
||||
sead::FixedSafeString<16> id{};
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(OptArea, 0x30);
|
||||
|
||||
struct FarModel {
|
||||
sead::Vector3f translate;
|
||||
sead::Vector3f rotate;
|
||||
sead::Vector3f scale;
|
||||
sead::FixedSafeString<16> id{};
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(FarModel, 0x50);
|
||||
|
||||
public:
|
||||
enum class Flag : u16 {
|
||||
Remains = 1 << 0,
|
||||
AocField = 1 << 1,
|
||||
FireOrWindRemains = 1 << 2,
|
||||
_8 = 1 << 3,
|
||||
_10 = 1 << 4,
|
||||
WindRelicFlag = 1 << 5,
|
||||
FirstInCastleBossRoom = 1 << 6,
|
||||
LastBoss = 1 << 7,
|
||||
_100 = 1 << 8,
|
||||
_200 = 1 << 9,
|
||||
_400 = 1 << 10,
|
||||
_800 = 1 << 11,
|
||||
_1000 = 1 << 12,
|
||||
_2000 = 1 << 13,
|
||||
_4000 = 1 << 14,
|
||||
FinalTrial = 1 << 15
|
||||
};
|
||||
|
||||
// d1f4d8
|
||||
static bool getIsPlayedDemo145AndFirstInCastleBossRoom(ksys::gdt::Manager& gdm,
|
||||
bool* first_in_ganon_boss_room,
|
||||
bool* played_demo_145);
|
||||
|
||||
// d1c8c0
|
||||
PlacementAreaMgr();
|
||||
~PlacementAreaMgr();
|
||||
|
||||
// d1cecc
|
||||
bool parseAreas(const sead::SafeString& unit_config_name, const MubinIter& obj_iter);
|
||||
// d1e578
|
||||
void x();
|
||||
void addLinkPair(const int& idx, const int& sub_idx);
|
||||
// d1eb24
|
||||
void postPlaceActorsUpdateFlagsAndLazyTraverse();
|
||||
bool insideInnerHideTrans(const int& idx);
|
||||
bool insideInnerHideBase(const int& idx);
|
||||
bool insideInnerHideCalc(const int& idx);
|
||||
bool insideInnerHideLoad(const int& idx);
|
||||
void loadDemoCulling(const sead::SafeString& demo_name);
|
||||
void unloadDemoCulling();
|
||||
// d1fe78
|
||||
bool shouldSkipSpawnOneHitChallengeActor(const Object& obj);
|
||||
// d20bcc
|
||||
bool shouldSkipSpawn(const Object& obj, bool a3);
|
||||
bool insideInnerHideBase(const sead::Vector3f& pos, const float& dist_from_face,
|
||||
const int& idx);
|
||||
bool isPlayerInsideNpc(const sead::Vector3f& pos);
|
||||
// d21ddc
|
||||
void boundsChecking();
|
||||
bool insideInnerHideCalc(const sead::Vector3f& pos, const float& dist_from_face,
|
||||
const int& idx);
|
||||
bool insideAlphaBase(const sead::Vector3f& pos, const float& dist_from_face);
|
||||
bool insideOmegaBase();
|
||||
bool insideOmegaBase(const sead::Vector3f& pos, const float& dist_from_face);
|
||||
bool insideAlphaBase();
|
||||
// d231cc
|
||||
void boundsChecking_1(); // looks eerily similar to boundsChecking
|
||||
// d2388c
|
||||
void weirdSetup(); // perhaps used with teleport feature?
|
||||
bool isInsideNpc(const sead::Vector3f& pos);
|
||||
// d24400
|
||||
void pushFarModels();
|
||||
// d2449c
|
||||
bool x_0(const int& idx, const int& sub_idx);
|
||||
|
||||
s8 isInsideNpcIdx(const sead::Vector3f& pos);
|
||||
GeneralArea* findGeneralArea(const u32& id);
|
||||
|
||||
sead::TypedBitFlag<Flag> mFlags;
|
||||
bool mIsOneHitChallengeActive = false;
|
||||
bool mNotAocField = false;
|
||||
bool _4 = false;
|
||||
sead::SafeArray<Unknown1, 512> mInnerHide{}; // parseObj
|
||||
s32 mInnerHideCount;
|
||||
Unknown1 mAlpha{}, mOmega{}; // parseObj
|
||||
sead::SafeArray<OuterNPCMementary, 26> mNpc{};
|
||||
sead::Vector3f mPlayerPos;
|
||||
f32 mCameraAngleMaybe = 50.0f; // fov?
|
||||
s32 mActiveNpc; // 0 - 25
|
||||
LazyTraverseList* mObjects = StagePreActorCache::instance()->getObjects();
|
||||
sead::SafeArray<JudgeArea, 16> mJudgeArea{};
|
||||
s32 mJudgeAreaCount;
|
||||
sead::SafeArray<char, 128> _2a468{}; // probably not char
|
||||
s32 _2a468Count;
|
||||
sead::SafeArray<GeneralArea, 64> mGeneralAreas{};
|
||||
s32 mGeneralAreasCount;
|
||||
sead::SafeArray<OptArea, 4> mOptAreas{};
|
||||
s32 mOptAreasCount;
|
||||
OptArea* mIntroArea;
|
||||
sead::SafeArray<FarModel, 128> mFarModels{};
|
||||
s32 mFarModelsCount;
|
||||
f32 _2d5c4; // distance?
|
||||
u8 _2d5c8 = 0; // enum potentially
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(PlacementAreaMgr, 0x2D5D0);
|
||||
|
||||
} // namespace ksys::map
|
|
@ -9,15 +9,20 @@ class ForestRenderer;
|
|||
|
||||
namespace ksys::map {
|
||||
|
||||
class LazyTraverseList;
|
||||
|
||||
// TODO
|
||||
class StagePreActorCache {
|
||||
SEAD_SINGLETON_DISPOSER(StagePreActorCache)
|
||||
StagePreActorCache();
|
||||
|
||||
public:
|
||||
LazyTraverseList* getObjects() const { return mObjects; }
|
||||
auto* getForestRenderer() { return mForestRenderer; }
|
||||
|
||||
private:
|
||||
char _0[0x20];
|
||||
LazyTraverseList* mObjects;
|
||||
gfx::ForestRenderer* mForestRenderer;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <math/seadVector.h>
|
||||
|
||||
namespace ksys::util {
|
||||
|
||||
// too specific for sead
|
||||
inline float sqXZDistance(const sead::Vector3f& a, const sead::Vector3f& b) {
|
||||
return sead::Mathf::square(a.x - b.x) + sead::Mathf::square(a.z - b.z);
|
||||
}
|
||||
|
||||
} // namespace ksys::util
|
Loading…
Reference in New Issue