diff options
| author | theo3 <arisstephenson2@gmail.com> | 2021-06-28 10:05:07 -0700 |
|---|---|---|
| committer | theo3 <arisstephenson2@gmail.com> | 2021-07-01 21:02:46 -0700 |
| commit | 4cba2eb093fbc452db88e33643b3ca293ff02213 (patch) | |
| tree | 581b36877d8b17b986c12a20a351b229dfd56bdf /src/KingSystem/Map/mapObject.cpp | |
| parent | 112c1f987d3831df97f46c0f9e4ae977fba59484 (diff) | |
ksys::map placement classes
Diffstat (limited to 'src/KingSystem/Map/mapObject.cpp')
| -rw-r--r-- | src/KingSystem/Map/mapObject.cpp | 295 |
1 files changed, 244 insertions, 51 deletions
diff --git a/src/KingSystem/Map/mapObject.cpp b/src/KingSystem/Map/mapObject.cpp index 6d62d9c2..d198ab44 100644 --- a/src/KingSystem/Map/mapObject.cpp +++ b/src/KingSystem/Map/mapObject.cpp @@ -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; + 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; } -const char* Object::getHashIdStringDebug_0() const { - act::ActorDebug::HashUnused t; +void Object::unlinkProc(bool force) { + bool set = false; + auto flag = Flag0::ResetOnUnlinkFailed; - const char* terminator; + if (!tera::checkTeraSystemStatus()) { + auto* thread = sead::ThreadMgr::instance()->getCurrentThread(); + thread->getPriority(); + } + static_cast<void>(mFlags0.isZero()); - if (mMubinIter.tryGetParamUIntByKey(&t.hash, "HashId")) - terminator = act::ActorDebug::instance()->getNullStr(&t); + 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 - terminator = ""; + s = getUnitConfigNameFromByaml(); + id->getInvalidLifeConditions(s, info); - return terminator; + sead::Vector3f temp = mTranslate; + return !id->sub_7100D30DF8(info, temp); } -void* Object::getRails() const { - if (!mLinkData) - return nullptr; +// NON_MATCHING +bool Object::setupTargetLinks(Object* src, ObjectLink* link, sead::Heap* heap) { + if (mNumLinksPointingToMe == 0) + return false; - return mLinkData->mRails; + 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); } |
