mirror of
https://github.com/zeldaret/botw
synced 2026-06-06 11:37:27 -04:00
ksys::map placement classes
This commit is contained in:
@@ -1,11 +1,24 @@
|
||||
#include "KingSystem/Map/mapObject.h"
|
||||
#include "KingSystem/ActorSystem/actBaseProcMgr.h"
|
||||
#include "KingSystem/ActorSystem/actInfoData.h"
|
||||
#include "KingSystem/GameData/gdtManager.h"
|
||||
#include "KingSystem/Map/mapObjectLink.h"
|
||||
#include "KingSystem/Map/mapPlacementMgr.h"
|
||||
#include "KingSystem/Map/mapStagePreActorCache.h"
|
||||
#include "KingSystem/Terrain/teraSystem.h"
|
||||
#include "KingSystem/Utils/Debug.h"
|
||||
|
||||
namespace ksys::map {
|
||||
|
||||
Object::Object() = default;
|
||||
// NON_MATCHING
|
||||
Object::Object() {
|
||||
mHardModeFlags.makeAllZero();
|
||||
_b = 0xFF;
|
||||
_18 = nullptr;
|
||||
_20 = nullptr;
|
||||
mProc = nullptr;
|
||||
mLinkData = nullptr;
|
||||
}
|
||||
|
||||
Object::~Object() {
|
||||
if (mLinkData != nullptr) {
|
||||
@@ -23,9 +36,7 @@ void Object::free() {
|
||||
if (mProc)
|
||||
mProc = nullptr;
|
||||
|
||||
// TODO: figure out what this is
|
||||
mFlags0.reset(Flag0::Freed);
|
||||
|
||||
mFlags0.reset(Flag0::ResetOnFreed);
|
||||
mHardModeFlags.reset(HardModeFlag::ActorCreated);
|
||||
|
||||
if (mFlags0.isOn(Flag0::_80000))
|
||||
@@ -37,25 +48,99 @@ void Object::free() {
|
||||
mLinkData->field_57 = 0;
|
||||
}
|
||||
|
||||
// NON_MATCHING: functionally equivalent; CSEL instruction flipped
|
||||
bool Object::getActorWithAccessor(act::ActorLinkConstDataAccess& accessor) const {
|
||||
// NON_MATCHING
|
||||
void Object::initData(MubinIter* iter, u8 idx, u32 actor_data_idx, ActorData* data) {
|
||||
mActorDataIdx = 0xFFFF;
|
||||
mFlags0.makeAllZero();
|
||||
mRevivalGameDataFlagHash = gdt::InvalidHandle;
|
||||
mId = 0;
|
||||
mActorFlags8.makeAllZero();
|
||||
mFlags.makeAllZero();
|
||||
mIdx = 0;
|
||||
mNumLinksPointingToMe = 0;
|
||||
mStaticCompoundId = 0xFFFF;
|
||||
_18 = nullptr;
|
||||
_20 = nullptr;
|
||||
_10 = nullptr;
|
||||
_50 = nullptr;
|
||||
mTraverseDist = 0.0f;
|
||||
mTraverseDistInt = 0;
|
||||
mHashId = 0;
|
||||
mHardModeFlags.makeAllZero();
|
||||
_b = 0xFF;
|
||||
mProc = nullptr;
|
||||
mLinkData = nullptr;
|
||||
iter->tryGetFloatArrayByKey(&mTranslate.x, "Translate");
|
||||
mMubinIter = *iter;
|
||||
|
||||
u32 hash = 0;
|
||||
iter->tryGetParamUIntByKey(&hash, "HashId");
|
||||
if (hash == 0)
|
||||
hash = 0xFFFFFFFF;
|
||||
mHashId = hash;
|
||||
|
||||
mIdx = idx;
|
||||
mFlags0.setDirect(Flag0::_8);
|
||||
mNumLinksPointingToMe = 0;
|
||||
_10 = nullptr;
|
||||
_18 = nullptr;
|
||||
_20 = nullptr;
|
||||
mStaticCompoundId = 0xFFFF;
|
||||
mActorDataIdx = actor_data_idx;
|
||||
mProc = nullptr;
|
||||
mLinkData = nullptr;
|
||||
mActorFlags8 = data->mActorFlags8;
|
||||
|
||||
auto* fr = StagePreActorCache::instance()->getForestRenderer();
|
||||
if (fr != nullptr) {
|
||||
if (fr->x_7(mTranslate) != -1) {
|
||||
mFlags0.set(Flag0::_10);
|
||||
}
|
||||
}
|
||||
initRevivalGameDataFlagAndMiscFlags(data, false);
|
||||
}
|
||||
|
||||
act::BaseProc* Object::tryGetProc(bool force) {
|
||||
auto* bpm = act::BaseProcMgr::instance();
|
||||
if (bpm == nullptr || !bpm->isHighPriorityThread())
|
||||
return nullptr;
|
||||
if (mProc == nullptr)
|
||||
return nullptr;
|
||||
|
||||
act::BaseProc* result = nullptr;
|
||||
if (!mProc->isDeleteOrInvalid())
|
||||
result = mProc;
|
||||
if (mProc->isDeleteOrInvalid() || force)
|
||||
return result;
|
||||
|
||||
if (!mProc->isInit())
|
||||
bpm->isAccessingProcSafe(mProc, nullptr);
|
||||
return mProc;
|
||||
}
|
||||
|
||||
act::Actor* Object::tryGetActor(bool force) {
|
||||
auto* proc = tryGetProc(force);
|
||||
return sead::DynamicCast<act::Actor>(proc);
|
||||
}
|
||||
|
||||
bool Object::getActorWithAccessor(act::ActorLinkConstDataAccess& accessor) {
|
||||
act::BaseProcMgr* instance = act::BaseProcMgr::instance();
|
||||
|
||||
if (instance == nullptr || !instance->isHighPriorityThread() || mProc == nullptr)
|
||||
return accessor.acquire(nullptr);
|
||||
|
||||
if (mProc->isInit() || mProc->isCalc())
|
||||
if (!mProc->isDeleteOrInvalid())
|
||||
return accessor.acquire(mProc);
|
||||
|
||||
return accessor.acquire(nullptr);
|
||||
}
|
||||
|
||||
act::Actor* Object::getActor() const {
|
||||
act::Actor* Object::getActor() {
|
||||
return sead::DynamicCast<act::Actor>(mProc);
|
||||
}
|
||||
|
||||
void Object::registerBaseProc(act::BaseProc* proc) {
|
||||
const char* sActorStateStrings[4] = {"Init", "Calc", "Sleep", "Delete"};
|
||||
static const char* sActorStateStrings[4] = {"Init", "Calc", "Sleep", "Delete"};
|
||||
|
||||
if (mProc != nullptr && mProc != proc) {
|
||||
sead::FixedSafeString<1000> message;
|
||||
@@ -65,7 +150,7 @@ void Object::registerBaseProc(act::BaseProc* proc) {
|
||||
sActorStateStrings[static_cast<s32>(proc->getState())]);
|
||||
util::PrintDebug(message);
|
||||
}
|
||||
mProc = proc;
|
||||
setBaseProcDirect(proc);
|
||||
|
||||
mFlags0.set(Flag0::_80);
|
||||
mFlags0.reset(Flag0::_80000000);
|
||||
@@ -93,7 +178,7 @@ bool Object::isEnemyOrNpcOrActiveOrMapPassive() const {
|
||||
|
||||
bool Object::isNpcOrActiveOrMapPassiveOrFlag1() const {
|
||||
auto actFlags = mActorFlags8;
|
||||
if (actFlags.isZero())
|
||||
if (isFlags8Cleared())
|
||||
return true;
|
||||
|
||||
auto pa = PlacementMgr::instance()->mPlacementActors;
|
||||
@@ -108,13 +193,13 @@ bool Object::isNpcOrActiveOrMapPassiveOrFlag1() const {
|
||||
}
|
||||
|
||||
bool Object::isMapPassive(const PlacementActors* pa) const {
|
||||
if (mActorFlags8.isZero())
|
||||
if (isFlags8Cleared())
|
||||
return true;
|
||||
|
||||
if (pa == nullptr)
|
||||
return false;
|
||||
|
||||
if (pa->mActorData[mActorDataIdx].mFlags.isOnBit(ActorData::Flag::_16) ||
|
||||
if (checkActorDataFlag(pa, ActorData::Flag::_16) ||
|
||||
mActorFlags8.isOn(ActorFlag8::EnemyOrNpcOrActiveOrAreaOrAirWall))
|
||||
return false;
|
||||
|
||||
@@ -146,20 +231,17 @@ f32 Object::getDispDistance(const ActorData* data, bool get_diameter, u32 unused
|
||||
f32 Object::getDispDistance(const PlacementActors* pa, bool get_diameter,
|
||||
bool ignore_radius) const {
|
||||
auto* dat = &pa->mActorData[mActorDataIdx];
|
||||
|
||||
return getDispDistance(dat, get_diameter, 0, ignore_radius);
|
||||
}
|
||||
|
||||
f32 Object::getDispDistance(bool get_diameter, bool ignore_radius) const {
|
||||
auto pa = PlacementMgr::instance()->mPlacementActors;
|
||||
|
||||
return getDispDistance(pa, get_diameter, ignore_radius);
|
||||
}
|
||||
|
||||
[[gnu::noinline]] f32 Object::getTraverseDist(const ActorData* data, bool get_diameter, u32,
|
||||
bool ignore_radius) const {
|
||||
using DFlag = ActorData::Flag;
|
||||
|
||||
f32 dist = 0.0;
|
||||
|
||||
if (mFlags.isOn(Flag::HasTraversePos) && !ignore_radius) {
|
||||
@@ -186,22 +268,18 @@ f32 Object::getDispDistance(bool get_diameter, bool ignore_radius) const {
|
||||
|
||||
f32 Object::getTraverseDistForLOD() const {
|
||||
using DFlag = ActorData::Flag;
|
||||
|
||||
auto* data = &PlacementMgr::instance()->mPlacementActors->mActorData[mActorDataIdx];
|
||||
f32 dist = 0.0;
|
||||
|
||||
if (data->mFlags.isOnBit(ActorData::Flag::TraverseDistReset))
|
||||
return 0.0;
|
||||
|
||||
if (data->mFlags.isOnBit(ActorData::Flag::TraverseDistReset))
|
||||
dist = 0.0;
|
||||
|
||||
else if (data->mFlags.isOnBit(DFlag::TraverseDist400) ||
|
||||
data->mFlags.isOnBit(DFlag::TraverseDist200) ||
|
||||
data->mFlags.isOnBit(DFlag::TraverseDist4000) ||
|
||||
data->mFlags.isOnBit(DFlag::TraverseDist800))
|
||||
dist = mTraverseDist + 0.0;
|
||||
|
||||
else if (data->mFlags.isOffBit(DFlag::TraverseDist2000))
|
||||
dist = mTraverseDist + 0.0;
|
||||
else
|
||||
@@ -217,7 +295,6 @@ f32 Object::getTraverseDistForLOD() const {
|
||||
|
||||
sead::Vector3f Object::getScale() const {
|
||||
sead::Vector3f vec;
|
||||
|
||||
mMubinIter.getScale(&vec);
|
||||
return vec;
|
||||
}
|
||||
@@ -235,7 +312,6 @@ const char* Object::getUnitConfigNameFromByaml() const {
|
||||
const char* result;
|
||||
if (!mMubinIter.tryGetParamStringByKey(&result, "UnitConfigName"))
|
||||
result = "";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -246,7 +322,6 @@ Object* Object::findPlacementLODLinkObject(const PlacementActors*) const {
|
||||
ObjectLink* result = mLinkData->mLinksToSelf.findLinkWithType(MapLinkDefType::PlacementLOD);
|
||||
if (result)
|
||||
return result->other_obj;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -254,75 +329,196 @@ Object* Object::findPlacementLODLinkObject() const {
|
||||
if (!mLinkData)
|
||||
return nullptr;
|
||||
|
||||
ObjectLink* result = mLinkData->mLinksToSelf.findLinkWithType(MapLinkDefType::PlacementLOD);
|
||||
ObjectLink* result = mLinkData->mLinksToSelf.findLinkWithType_0(MapLinkDefType::PlacementLOD);
|
||||
if (result)
|
||||
return result->other_obj;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* Object::getHashIdStringDebug() const {
|
||||
act::ActorDebug::HashUnused t;
|
||||
|
||||
const char* terminator;
|
||||
|
||||
if (mMubinIter.tryGetParamUIntByKey(&t.hash, "HashId"))
|
||||
terminator = act::ActorDebug::instance()->getNullStr(&t);
|
||||
else
|
||||
terminator = "";
|
||||
|
||||
return terminator;
|
||||
return getHashIdStringDebug_0();
|
||||
}
|
||||
|
||||
const char* Object::getHashIdStringDebug_0() const {
|
||||
act::ActorDebug::HashUnused t;
|
||||
|
||||
const char* terminator;
|
||||
|
||||
if (mMubinIter.tryGetParamUIntByKey(&t.hash, "HashId"))
|
||||
terminator = act::ActorDebug::instance()->getNullStr(&t);
|
||||
else
|
||||
terminator = "";
|
||||
|
||||
return terminator;
|
||||
}
|
||||
|
||||
void* Object::getRails() const {
|
||||
if (!mLinkData)
|
||||
return nullptr;
|
||||
void Object::unlinkProc(bool force) {
|
||||
bool set = false;
|
||||
auto flag = Flag0::ResetOnUnlinkFailed;
|
||||
|
||||
return mLinkData->mRails;
|
||||
if (!tera::checkTeraSystemStatus()) {
|
||||
auto* thread = sead::ThreadMgr::instance()->getCurrentThread();
|
||||
thread->getPriority();
|
||||
}
|
||||
static_cast<void>(mFlags0.isZero());
|
||||
|
||||
if (force || mFlags0.isOn(Flag0::ActorCreated))
|
||||
set = true;
|
||||
else if (checkActorDataFlag(PlacementMgr::instance()->mPlacementActors,
|
||||
ActorData::Flag::RevivalEnable))
|
||||
set = isRevivalGameDataFlagOn();
|
||||
|
||||
if (set)
|
||||
flag = Flag0::ResetOnUnlink;
|
||||
|
||||
mFlags0.reset(flag);
|
||||
mProc = nullptr;
|
||||
}
|
||||
|
||||
bool Object::checkRevivalFlag(ActorData::Flag bit) const {
|
||||
if (bit == ActorData::Flag::RevivalEnable || bit == ActorData::Flag::RevivalForUsed ||
|
||||
bit == ActorData::Flag::RevivalForDrop) {
|
||||
if (getActorData().mFlags.isOffBit(bit))
|
||||
return false;
|
||||
return isRevivalGameDataFlagOn();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Object::isRevivalGameDataFlagOn() const {
|
||||
bool x = false;
|
||||
gdt::Manager::instance()->getBool(mRevivalGameDataFlagHash, &x, true);
|
||||
return x;
|
||||
}
|
||||
|
||||
void Object::setRevivalFlagValueIf(ActorData::Flag bit, bool value) {
|
||||
if (bit == ActorData::Flag::RevivalEnable || bit == ActorData::Flag::RevivalForUsed ||
|
||||
bit == ActorData::Flag::RevivalForDrop) {
|
||||
if (getActorData().mFlags.isOnBit(bit)) {
|
||||
setRevivalFlagValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Object::setRevivalFlagValue(bool value) {
|
||||
gdt::Manager::instance()->setBool(value, mRevivalGameDataFlagHash);
|
||||
}
|
||||
|
||||
// NON_MATCHING
|
||||
bool Object::x_18() const {
|
||||
act::InfoData::InvalidLifeConditions info;
|
||||
const char* s;
|
||||
auto* id = act::InfoData::instance();
|
||||
|
||||
if (PlacementMgr::instance() != nullptr &&
|
||||
PlacementMgr::instance()->mPlacementActors != nullptr)
|
||||
s = PlacementMgr::instance()->mPlacementActors->mActorData[mActorDataIdx].mActorName.cstr();
|
||||
else
|
||||
s = getUnitConfigNameFromByaml();
|
||||
id->getInvalidLifeConditions(s, info);
|
||||
|
||||
sead::Vector3f temp = mTranslate;
|
||||
return !id->sub_7100D30DF8(info, temp);
|
||||
}
|
||||
|
||||
// NON_MATCHING
|
||||
bool Object::setupTargetLinks(Object* src, ObjectLink* link, sead::Heap* heap) {
|
||||
if (mNumLinksPointingToMe == 0)
|
||||
return false;
|
||||
|
||||
if (mLinkData == nullptr) {
|
||||
mLinkData = new (heap) ObjectLinkData();
|
||||
if (mLinkData == nullptr)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mLinkData->mLinksToSelf.links != nullptr)
|
||||
return mLinkData->sub_7100D4EC40(src, link, this);
|
||||
|
||||
if (!mLinkData->allocLinksToSelf(mNumLinksPointingToMe, heap))
|
||||
return false;
|
||||
|
||||
return mLinkData->sub_7100D4EC40(src, link, this);
|
||||
}
|
||||
|
||||
bool Object::checkCreateOrDeleteLinkObjRevival() const {
|
||||
if (mLinkData != nullptr)
|
||||
return mLinkData->checkCreateOrDeleteLinkObjRevival();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Object::shouldSkipSpawn() const {
|
||||
if (checkTraverseFlags() || shouldSkipSpawn_(false))
|
||||
return true;
|
||||
return checkCreateOrDeleteLinkObjRevival();
|
||||
}
|
||||
|
||||
bool Object::checkTraverseFlags() const {
|
||||
return mFlags0.isOn(Flag0::_500400);
|
||||
}
|
||||
|
||||
// NON_MATCHING
|
||||
bool Object::x_20() const {
|
||||
if (getActorData().mFlags.isOffBit(ActorData::Flag::RevivalEnable))
|
||||
return false;
|
||||
|
||||
if (mFlags0.isOff(Flag0::_400400))
|
||||
return false;
|
||||
|
||||
if (!shouldSkipSpawn_(false)) {
|
||||
return checkCreateOrDeleteLinkObjRevival();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Object::onBaseProcCreated(act::BaseProc* actor) {
|
||||
if (actor != nullptr) {
|
||||
registerBaseProc(actor);
|
||||
mFlags0.set(Flag0::ActorCreated);
|
||||
} else {
|
||||
mFlags0.reset(Flag0::_80002106);
|
||||
}
|
||||
}
|
||||
|
||||
void Object::spawnGenGroupActorsIfNeeded(Object* obj) {
|
||||
if (mLinkData != nullptr)
|
||||
mLinkData->sub_7100D4FB78(obj);
|
||||
}
|
||||
|
||||
void Object::setFieldATrue() {
|
||||
if (mActorFlags8.isOn(ActorFlag8::MapPassive) || mActorFlags8.isOn(ActorFlag8::_8)) {
|
||||
mActorFlags8.reset(ActorFlag8::MapPassive);
|
||||
mActorFlags8.reset(ActorFlag8::_8);
|
||||
mActorFlags8.set(ActorFlag8::EnemyOrNpcOrActiveOrAreaOrAirWall);
|
||||
}
|
||||
}
|
||||
|
||||
void* Object::getRails() const {
|
||||
return getRails_0();
|
||||
}
|
||||
|
||||
void* Object::getRails_0() const {
|
||||
if (!mLinkData)
|
||||
if (mLinkData == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return mLinkData->mRails;
|
||||
}
|
||||
|
||||
bool Object::allocLinkData(sead::Heap* heap) {
|
||||
mLinkData = new (heap) ObjectLinkData;
|
||||
|
||||
return mLinkData != nullptr;
|
||||
}
|
||||
|
||||
bool Object::hasGenGroup() const {
|
||||
if (!mLinkData)
|
||||
return false;
|
||||
|
||||
return mLinkData->mGenGroup != nullptr;
|
||||
}
|
||||
|
||||
void Object::incrementLinkNum() {
|
||||
if (mNumLinksPointingToMe != 0xFF) {
|
||||
mNumLinksPointingToMe += 1;
|
||||
mNumLinksPointingToMe++;
|
||||
return;
|
||||
}
|
||||
|
||||
auto name = sead::SafeString(getUnitConfigName());
|
||||
|
||||
if (name == "LinkTagNone") {
|
||||
if (sead::SafeString(getUnitConfigName()) == "LinkTagNone") {
|
||||
// More than 255 actors are specified in one generation group.
|
||||
// If it is not a test, consult the programmer.
|
||||
printDebugMsg(this,
|
||||
@@ -345,18 +541,15 @@ void Object::decrementLinkNum() {
|
||||
sead::Vector3f Object::getRotate() const {
|
||||
sead::Vector3f result;
|
||||
mMubinIter.getRotate(&result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// NON_MATCHING: Vec3f copy incorrect
|
||||
void Object::getTraversePosAndLoadDistance(sead::Vector3f* traverse_pos, f32* load_dist) const {
|
||||
if (mFlags.isOn(Flag::HasTraversePos)) {
|
||||
if (mFlags.isOn(Flag::HasTraversePos))
|
||||
mMubinIter.tryGetFloatArrayByKey(&traverse_pos->x, "TraversePos");
|
||||
} else {
|
||||
else
|
||||
*traverse_pos = mTranslate;
|
||||
}
|
||||
|
||||
*load_dist = getLoadDistance(false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user