diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 231330bf..54760f09 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -2478,7 +2478,7 @@ Address,Quality,Size,Name 0x0000007100082c5c,O,000020,_ZN5uking6action23AddAutoPlacementCreatorD1Ev 0x0000007100082c70,O,000052,_ZN5uking6action23AddAutoPlacementCreatorD0Ev 0x0000007100082ca4,O,000008,_ZN5uking6action23AddAutoPlacementCreator5init_EPN4sead4HeapE -0x0000007100082cac,m,000620,_ZN5uking6action23AddAutoPlacementCreator6enter_EPN4ksys3act2ai15InlineParamPackE +0x0000007100082cac,O,000620,_ZN5uking6action23AddAutoPlacementCreator6enter_EPN4ksys3act2ai15InlineParamPackE 0x0000007100082f18,O,000004,_ZN5uking6action23AddAutoPlacementCreator5calc_Ev 0x0000007100082f1c,O,000064,_ZN5uking6action23AddAutoPlacementCreator6leave_Ev 0x0000007100082f5c,O,000128,_ZN5uking6action23AddAutoPlacementCreator11loadParams_Ev @@ -39660,42 +39660,42 @@ Address,Quality,Size,Name 0x000000710064c3ac,U,000420, 0x000000710064c550,U,000516,sinitAmiiboMgrDates 0x000000710064c754,U,000004,nullsub_2156 -0x000000710064c758,U,000772, +0x000000710064c758,M,000772,_ZN4ksys3map13AutoPlacementC1Ev 0x000000710064ca5c,U,000416, -0x000000710064cbfc,U,000388, -0x000000710064cd80,U,000052, -0x000000710064cdb4,U,000428, +0x000000710064cbfc,O,000388,_ZN4ksys3map13AutoPlacement14sub_710064CBFCEPN4sead4HeapEhii +0x000000710064cd80,O,000052,_ZN4ksys3map13AutoPlacement14sub_710064CD80Ejj +0x000000710064cdb4,O,000428,_ZN4ksys3map14ActorSpawnInfo18calcSpawnLocationsEv 0x000000710064cf60,U,000832, 0x000000710064d2a0,U,001072, 0x000000710064d6d0,U,000716, -0x000000710064d99c,U,000184, -0x000000710064da54,U,000044, +0x000000710064d99c,O,000184,_ZN4ksys3map13AutoPlacement12setSpawnInfoERKN4sead14SafeStringBaseIcEEi +0x000000710064da54,O,000044,_ZN4ksys3map13AutoPlacement14sub_710064DA54Ev 0x000000710064da80,U,000948, 0x000000710064de34,U,000836, -0x000000710064e178,U,000460, +0x000000710064e178,m,000460,_ZN4ksys3map13AutoPlacement14sub_710064E178ERKN4sead14SafeStringBaseIcEEjRKNS2_7Vector3IfEE 0x000000710064e344,U,001564, -0x000000710064e960,U,000340, +0x000000710064e960,m,000340,_ZN4ksys3map14PlacementThing6invokeEv 0x000000710064eab4,U,000684, 0x000000710064ed60,U,000452, -0x000000710064ef24,U,000264, +0x000000710064ef24,m,000264,_ZN4ksys3map13AutoPlacement14sub_710064EF24EPNS0_14ActorSpawnInfoERKN4sead7Vector3IfEE 0x000000710064f02c,U,000536, 0x000000710064f244,U,000776, 0x000000710064f54c,U,000504, -0x000000710064f744,U,000072, -0x000000710064f78c,U,000020, +0x000000710064f744,O,000072,_ZN4ksys3map13AutoPlacement14sub_710064F744Ehh +0x000000710064f78c,O,000020,_ZN4ksys3map13AutoPlacement14incrementGroupEv 0x000000710064f7a0,U,001804, 0x000000710064feac,U,000664,checkActorInvalidTimeWeatherStuffMaybe -0x0000007100650144,U,000172, +0x0000007100650144,O,000172,_ZN4ksys3map13AutoPlacement14sub_7100650144EPNS0_14PlacementGroupEb 0x00000071006501f0,U,000560, -0x0000007100650420,U,000220, +0x0000007100650420,m,000220,_ZN4ksys3map13AutoPlacement10placeGroupEPNS0_20AutoPlacementFlowResE 0x00000071006504fc,U,001036, -0x0000007100650908,U,000044, +0x0000007100650908,O,000044,_ZN4ksys3map13AutoPlacement14sub_7100650908Ev 0x0000007100650934,U,000488,autoplacement::getActorToSpawn -0x0000007100650b1c,U,000060, -0x0000007100650b58,U,000208, -0x0000007100650c28,U,000360, -0x0000007100650d90,U,000024,getCurrentGroundMat -0x0000007100650da8,U,000024,getCurrentWaterSubMat +0x0000007100650b1c,O,000060,_ZN4ksys3map13AutoPlacement15stepAllRaycastsEv +0x0000007100650b58,O,000208,_ZN4ksys3map14PlacementThing11stepRaycastEv +0x0000007100650c28,m,000360,_ZN4ksys3map13AutoPlacement14sub_7100650C28EPNS_4phys9RigidBodyE +0x0000007100650d90,O,000024,_ZNK4ksys3map14PlacementThing19getCurrentGroundMatEv +0x0000007100650da8,O,000024,_ZNK4ksys3map14PlacementThing21getCurrentWaterSubMatEv 0x0000007100650dc0,U,000228, 0x0000007100650ea4,U,000244, 0x0000007100650f98,U,000228, @@ -39716,12 +39716,12 @@ Address,Quality,Size,Name 0x0000007100652014,U,000824,AutoPlacementFlowMgr::ctor 0x000000710065234c,U,000360,AutoPlacementFlowMgr::dtor 0x00000071006524b4,U,000100,AutoPlacementFlowMgr::init -0x0000007100652518,U,000616,AutoPlacementFlowMgr::loadEventFlows +0x0000007100652518,M,000616,_ZN4ksys3map20AutoPlacementFlowMgr14loadEventFlowsEv 0x0000007100652780,U,000428,AutoPlacementFlowMgr::resAreReady 0x000000710065292c,U,000004,AutoPlacementFlowMgr::nullsub_2157 0x0000007100652930,U,000044,AutoPlacementFlowMgr::getResource1 0x000000710065295c,U,000048,AutoPlacementFlowMgr::getResource2 -0x000000710065298c,U,000344,AutoPlacementFlowMgr::a +0x000000710065298c,U,000344,AutoPlacementFlowMgr::getFlow 0x0000007100652ae4,O,000364,_ZN3ore5ArrayIN4evfl12FlowchartObjEE16DestructElementsEv 0x0000007100652c50,U,000096,StringWithLen::cmp 0x0000007100652cb0,U,000652, @@ -39751,9 +39751,9 @@ Address,Quality,Size,Name 0x0000007100654298,U,000916,sinitSomeBfevflStrings 0x000000710065462c,U,000100,_ZN4sead15DebugFontMgrNvn18SingletonDisposer_D1Ev 0x0000007100654690,U,000108, -0x00000071006546fc,U,000140,AutoPlacementMgr::createInstance -0x0000007100654788,U,000088,AutoPlacementMgr::destroyInstance -0x00000071006547e0,U,001636,AutoPlacementMgr::ctor +0x00000071006546fc,U,000140,_ZN4ksys3map16AutoPlacementMgr14createInstanceEPN4sead4HeapE +0x0000007100654788,O,000088,_ZN4ksys3map16AutoPlacementMgr14deleteInstanceEv +0x00000071006547e0,U,001636,_ZN4ksys3map16AutoPlacementMgrC1Ev 0x0000007100654e44,U,000572,AutoPlacementMgr::threadFn 0x0000007100655080,U,000152,AutoPlacementMgr::actorCreateCallback 0x0000007100655118,U,000172,AutoPlacementMgr::invoked3 diff --git a/src/Game/AI/Action/actionAddAutoPlacementCreator.cpp b/src/Game/AI/Action/actionAddAutoPlacementCreator.cpp index 7457b131..068f96b9 100644 --- a/src/Game/AI/Action/actionAddAutoPlacementCreator.cpp +++ b/src/Game/AI/Action/actionAddAutoPlacementCreator.cpp @@ -14,7 +14,6 @@ bool AddAutoPlacementCreator::init_(sead::Heap* heap) { return ksys::act::ai::Action::init_(heap); } -// NON_MATCHING: dot float regalloc void AddAutoPlacementCreator::enter_(ksys::act::ai::InlineParamPack* params) { ksys::act::ai::Action::enter_(params); diff --git a/src/KingSystem/ActorSystem/actActor.h b/src/KingSystem/ActorSystem/actActor.h index da3e060e..97350562 100644 --- a/src/KingSystem/ActorSystem/actActor.h +++ b/src/KingSystem/ActorSystem/actActor.h @@ -140,7 +140,9 @@ public: const sead::Vector3f& getVelocity() const { return mVelocity; } const sead::Vector3f& getAngVelocity() const { return mAngVelocity; } const sead::Vector3f& getScale() const { return mScale; } - f32 getDeleteDistance() const { return sead::Mathf::sqrt(sead::Mathf::clampMin(mDeleteDistanceSq, 0.0f)); } + f32 getDeleteDistance() const { + return sead::Mathf::sqrt(sead::Mathf::clampMin(mDeleteDistanceSq, 0.0f)); + } void setDeleteDistance(f32 distance) { mDeleteDistanceSq = sead::Mathf::square(distance); } diff --git a/src/KingSystem/ActorSystem/actPhysicsUserTag.h b/src/KingSystem/ActorSystem/actPhysicsUserTag.h index 641cd0f2..82360113 100644 --- a/src/KingSystem/ActorSystem/actPhysicsUserTag.h +++ b/src/KingSystem/ActorSystem/actPhysicsUserTag.h @@ -18,6 +18,8 @@ public: Actor* getActor(ActorLinkConstDataAccess* accessor, Actor* other_actor) const; bool acquireActor(ActorLinkConstDataAccess* accessor) const; + Actor* getActor() const { return mActor; } + void onMaxPositionExceeded(phys::RigidBody* body) override; void m3(void* a, void* b, float c) override; void onBodyShapeChanged(phys::RigidBody* body) override; diff --git a/src/KingSystem/Map/CMakeLists.txt b/src/KingSystem/Map/CMakeLists.txt index b201b701..87d13eee 100644 --- a/src/KingSystem/Map/CMakeLists.txt +++ b/src/KingSystem/Map/CMakeLists.txt @@ -1,5 +1,11 @@ target_sources(uking PRIVATE mapTypes.h + mapAutoPlacement.cpp + mapAutoPlacement.h + mapAutoPlacementFlowMgr.cpp + mapAutoPlacementFlowMgr.h + mapAutoPlacementMgr.cpp + mapAutoPlacementMgr.h mapDebug.cpp mapDebug.h mapLazyTraverseList.cpp diff --git a/src/KingSystem/Map/mapAutoPlacement.cpp b/src/KingSystem/Map/mapAutoPlacement.cpp new file mode 100644 index 00000000..886a65da --- /dev/null +++ b/src/KingSystem/Map/mapAutoPlacement.cpp @@ -0,0 +1,335 @@ +#include "KingSystem/Map/mapAutoPlacement.h" +#include "KingSystem/ActorSystem/actActor.h" +#include "KingSystem/ActorSystem/actActorUtil.h" +#include "KingSystem/ActorSystem/actInfoData.h" +#include "KingSystem/ActorSystem/actPhysicsUserTag.h" +#include "KingSystem/Ecosystem/ecoSystem.h" +#include "KingSystem/Map/mapAutoPlacementFlowMgr.h" +#include "KingSystem/Map/mapAutoPlacementMgr.h" +#include "KingSystem/Physics/RigidBody/physRigidBody.h" +#include "KingSystem/Utils/Byaml/Byaml.h" +#include "KingSystem/World/worldWeatherMgr.h" + +namespace ksys::map { + +AutoPlacement::AutoPlacement() = default; +AutoPlacement::~AutoPlacement() = default; + +bool AutoPlacement::sub_710064CBFC(sead::Heap* heap, u8 flag, s32 num_spawn, s32 num_obj) { + mNearFlag = flag; + + if (!mSpawnInfo.tryAllocBuffer(num_spawn, heap)) + return false; + + if (num_obj > 0 && !mObjectRefs.tryAllocBuffer(num_obj, heap)) + return false; + return true; +} + +u32 AutoPlacement::sub_710064CD80(u32 a, u32 b) { + auto calc = [](u32 x, u32 y, u32 a, u32 b) { return (1 - a + x < 3) & (1 - b + y < 3); }; + return calc(_4, _5, a, b); +} + +void ActorSpawnInfo::calcSpawnLocations() { + auto* mgr = act::InfoData::instance(); + al::ByamlIter iter; + + using namespace act::tags; + + spawn_location.makeAllZero(); + if (mgr == nullptr || !mgr->getActorIter(&iter, name.cstr())) + return; + + if (mgr->hasTag(iter, CheckBirdSafetyArea)) + spawn_location.set(SpawnLocation::CheckBirdSafetyArea); + if (mgr->hasTag(iter, IsSnowBall)) + spawn_location.set(SpawnLocation::IsSnowBall); + + if (mgr->hasTag(iter, CreateFromTrunkOrGlowStoneLocator)) + spawn_location.set(SpawnLocation::TrunkOrGlowStoneLocator); + else if (mgr->hasTag(iter, 0x923A4962)) + spawn_location.set(SpawnLocation::_4); + else if (mgr->hasTag(iter, CreateFromTrunkLocatorRandom)) + spawn_location.set(SpawnLocation::TrunkLocatorRandom); + else if (mgr->hasTag(iter, 0x7881F260)) + spawn_location.set(SpawnLocation::_10); + else if (mgr->hasTag(iter, CreateFromBranchLocatorRandom)) + spawn_location.set(SpawnLocation::BranchLocatorRandom); + else if (mgr->hasTag(iter, CreateFromOnTreeLocator)) + spawn_location.set(SpawnLocation::OnTreeLocator); + else if (mgr->hasTag(iter, CreateFromOnTreeLocatorRandom)) + spawn_location.set(SpawnLocation::OnTreeLocatorRandom); +} + +void AutoPlacement::setSpawnInfo(const sead::SafeString& name, s32 count) { + sub_710064CF60(false); + ActorSpawnInfo* info = &mSpawnInfo[0]; + auto* flow = AutoPlacementFlowMgr::instance()->getFlow(name, mNearFlag == 0xff); + if (flow != nullptr) { + info->name = name; + info->flow = flow; + info->_19 = 0; + s32 value = std::min(count, 255); + info->_18 = value; + info->_1c = value * 30; + info->_1e = 0; + info->calcSpawnLocations(); + _d = true; + _8 = 0; + } else { + _d = false; + } +} + +void AutoPlacement::sub_710064DA54() { + sub_710064CF60(false); + _8 = 2; +} + +eco::AreaItemType sPlacementItemTypesData[] = { + eco::AreaItemType::Enemy, eco::AreaItemType::Animal, eco::AreaItemType::Insect, + eco::AreaItemType::Fish, eco::AreaItemType::Bird, eco::AreaItemType::AutoPlacementMaterial, +}; +sead::Buffer sPlacementItemTypes{sPlacementItemTypesData}; + +// NON_MATCHING: stack +bool AutoPlacement::sub_710064E178(const sead::SafeString& name, u32 placement_type, + const sead::Vector3f& pos) { + if (mNearFlag == 0xFE) + return true; + + auto* eco = eco::Ecosystem::instance(); + if (eco == nullptr) + return false; + + s32 area = eco->getFieldMapArea(pos.x, pos.z); + if (area < 0) + return false; + + eco::AreaItemSet item_set; + eco->getAreaItems(area, sPlacementItemTypes[placement_type], &item_set); + + for (int i = 0; i < item_set.count; ++i) { + const auto& item = item_set.items[i]; + if (item.num > 0.0f && name == item.name) + return true; + } + return false; +} + +// NON_MATCHING: blocked by raycast +bool PlacementThing::invoke() { + auto lock = sead::makeScopedLock(mCS); + + if (AutoPlacementMgr::instance()->auto9()) + return true; + + if (mRaycast == nullptr || mState != State::Initialized) + return false; + + mRaycast->addContactLayer(phys::ContactLayer::EntityGround); + mRaycast->addContactLayer(phys::ContactLayer::EntityGroundRough); + mRaycast->addContactLayer(phys::ContactLayer::EntityGroundSmooth); + mRaycast->addContactLayer(phys::ContactLayer::EntityAirWall); + mRaycast->addContactLayer(phys::ContactLayer::EntityGroundObject); + mRaycast->addContactLayer(phys::ContactLayer::EntityTree); + + if (_8944) { + sead::Vector3f v1 = mVec1 + sead::Vector3f{0, 4, 30}; + sead::Vector3f v2 = mVec1 - sead::Vector3f{0, 4, 30}; + mRaycast->sub_7100FC38A0(v1, v2); + } else { + sead::Vector3f v1{mVec1.x, 2000.0f, mVec1.z}; + sead::Vector3f v2{mVec1.x, -100.0f, mVec1.z}; + mRaycast->sub_7100FC38A0(v1, v2); + // void** p = &mRaycast->mGroups[0]._68; + // *p = &mDelegate; + } + + mState = State::LayersDone; + return true; +} + +bool AutoPlacement::sub_7100650144(PlacementGroup* grp, bool check_exposure) { + if (grp->_1d == 0xFF) + return false; + if (grp->_20 == -1) + return false; + + auto* object = mObjectRefs[grp->_20].obj; + if (object == nullptr) + return false; + + if (object->shouldSkipSpawn()) { + return true; + } + + if (object->getProc() == nullptr && object->getFlags0().isOn(Object::Flag0::_80)) + return true; + + if (grp->_1d != 2) + return false; + + if (check_exposure && !world::WeatherMgr::isExposureZero()) + return true; + return false; +} + +bool AutoPlacement::sub_710064EF24(ActorSpawnInfo* info, const sead::Vector3f& pos) { + auto* mgr = AutoPlacementMgr::instance(); + u32 placement_type = info->flow->placement_type; + if (mgr->auto0(pos, placement_type)) { + if (mNearFlag != 0xFF) { + return false; + } + if (info->name.findIndex("Enemy_Dragon") == -1) { + return false; + } + } + + if ((mNearFlag != 0xFF && mgr->auto11(pos)) || + (!sub_710064E178(info->name, placement_type, pos))) { + return false; + } + + if (mNearFlag != 0xFE && mNearFlag != 0xFF) { + if (AutoPlacementMgr::instance()->auto2(info->name, pos)) + return false; + } + return true; +} + +void AutoPlacement::sub_710064F744(u8 a1, u8 a2) { + if (mNearFlag != 0xFF) + return; + if (mGroupIdx < 0) + return; + + auto& grp = mGroups[mGroupIdx]; + if (!grp._80) { + grp._1a = a1; + grp._1b = a2; + } +} + +void AutoPlacement::incrementGroup() { + if (mGroupIdx < 0) + return; + mGroupIdx++; +} + +s32 AutoPlacement::placeGroup(AutoPlacementFlowRes* res) { + if (mGroupIdx < 0) { + return -1; + } + + mThing2.mRaycast = mThing1.mRaycast; + _6 = 0; + _b = 0xFF; + + auto& grp = mGroups[mGroupIdx]; + if (grp.b.isEmpty()) { + return -1; + } + + _8868 = sead::SafeString::cEmptyString; + int tmp = 0; + res->start(this, grp.a, &tmp); + if (!_9) + return -1; + _9 = 0; + + return mGroupIdx; +} + +s32 AutoPlacement::sub_7100650908() { + if (mGroupIdx < 0) { + return -1; + } + return mGroups[mGroupIdx]._1c; +} + +void AutoPlacement::stepAllRaycasts() { + mThing1.stepRaycast(); + mThing2.stepRaycast(); + mThing3.stepRaycast(); +} + +void PlacementThing::stepRaycast() { + auto lock = sead::makeScopedLock(mCS); + + if (AutoPlacementMgr::instance()->auto9()) { + if (mRaycast != nullptr) { + mRaycast->release(); + mRaycast = nullptr; + } + mState = State::Invalid; + _8880 = _8944; + return; + } + + State next; + + switch (mState) { + case State::Uninitialized: + mRaycast = Raycast::create(nullptr, 1); + next = mRaycast != nullptr ? State::Initialized : State::Invalid; + break; + case State::LayersDone: + mRaycast->sub_7100FC55AC(0); + next = State::RaycastDone; + break; + case State::PlacementDone: + if (mRaycast != nullptr) { + mRaycast->release(); + next = State::Invalid; + mRaycast = nullptr; + } else { + next = State::Invalid; + } + break; + default: + return; + } + mState = next; +} + +void AutoPlacement::sub_7100650C28(phys::RigidBody* rb) { + if (rb == nullptr) + return; + + if (rb->getContactLayer() == phys::ContactLayer::EntityTree) + mNearFlag.setDirect(1); + + auto* tag = sead::DynamicCast(rb->getUserTag()); + if (tag == nullptr) + return; + + auto* actor = tag->getActor(); + if (actor == nullptr) + return; + + mNearFlag.set(act::hasTag(actor, act::tags::Tree) || + act::hasTag(actor, act::tags::AutoPlacementForbidCreate)); + + _b.set(actor->getName() == "AirWallHorse"); +} + +const char* PlacementThing::getCurrentGroundMat() const { + if (mWaterQuery > 0.0f) { + return mMask2.getMaterialName(); + } else { + return mMask1.getMaterialName(); + } +} + +const char* PlacementThing::getCurrentWaterSubMat() const { + if (mWaterQuery > 0.0f) { + return mMask2.getSubMaterialName(); + } else { + return mMask1.getSubMaterialName(); + } +} + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapAutoPlacement.h b/src/KingSystem/Map/mapAutoPlacement.h new file mode 100644 index 00000000..ecdb3a36 --- /dev/null +++ b/src/KingSystem/Map/mapAutoPlacement.h @@ -0,0 +1,190 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "KingSystem/Map/mapObject.h" +#include "KingSystem/Map/mapObjectLink.h" +#include "KingSystem/Physics/physMaterialMask.h" +#include "KingSystem/Utils/Types.h" + +namespace ksys::phys { +class RigidBody; +} // namespace ksys::phys + +namespace ksys::map { + +class AutoPlacement; +struct AutoPlacementFlowRes; +class PlacementThing; + +// TODO: move this +struct Raycast { + Raycast(); + virtual ~Raycast(); + + static Raycast* create(void*, u32); + + void addContactLayer(phys::ContactLayer layer); + void sub_7100FC55AC(u32); + void release(); + void sub_7100FC38A0(const sead::Vector3f&, const sead::Vector3f&); +}; + +struct PlacementGroup { + sead::SafeString a; + u32 _10; + u32 _14; + u8 _18; + u8 _19; + u8 _1a; + u8 _1b; + u8 _1c; + u8 _1d; + u8 _1e; + u8 _1f{}; + s16 _20; + u16 _22{}; + u8 _24; + u8 _25{}; + void* _28; + void* _30; + void* _38; + void* _40; + void* _48; + void* _50; + void* _58; + void* _60; + void* _68; + sead::SafeString b; + u32 _80{}; +}; +KSYS_CHECK_SIZE_NX150(PlacementGroup, 0x88); + +class PlacementThing { +public: + enum class State : u32 { + Invalid, + Uninitialized, + Initialized, + LayersDone, + RaycastDone, + PlacementDone, + }; + + explicit PlacementThing(bool set) + : mDelegate{this, &PlacementThing::sub_7100650C28}, _8944(set) {} + + bool invoke(); + void stepRaycast(); + void sub_7100650C28(phys::RigidBody*); + const char* getCurrentGroundMat() const; + const char* getCurrentWaterSubMat() const; + +private: + friend class AutoPlacement; + + Raycast* mRaycast{}; + u8 _8880{}; + u8 mUnderwater{}; + sead::Vector3f mVec1{}; + sead::Vector3f mQueryVec{}; + u32 _889c{}; + f32 _88a0 = 1.0f; + phys::MaterialMask mMask1; + phys::MaterialMask mMask2; + f32 mWaterQuery = -1.0f; + sead::Delegate1 mDelegate; + sead::CriticalSection mCS{}; + State mState; + u8 _8944{}; + u8 _8945{}; +}; + +struct ActorSpawnInfo { + enum class SpawnLocation : u16 { + CheckBirdSafetyArea = 1, + + // exclusive + TrunkOrGlowStoneLocator = 2, + _4 = 4, + TrunkLocatorRandom = 8, + _10 = 0x10, + BranchLocatorRandom = 0x20, + OnTreeLocator = 0x40, + OnTreeLocatorRandom = 0x80, + + IsSnowBall = 0x100, + }; + + void calcSpawnLocations(); + + sead::SafeString name{}; + AutoPlacementFlowRes* flow; + u8 _18; + u8 _19; + sead::TypedBitFlag spawn_location{}; + u16 _1c; + u16 _1e; +}; + +class AutoPlacement { +public: + AutoPlacement(); + ~AutoPlacement(); + + bool sub_710064CBFC(sead::Heap* heap, u8 flag, s32 num_spawn, s32 num_obj); + u32 sub_710064CD80(u32, u32); + void sub_710064CF60(bool force); + + bool sub_710064ED60(const sead::SafeString& name, const sead::Vector3f& distance); + + void setSpawnInfo(const sead::SafeString& name, s32 count); + void sub_710064DA54(); + + bool sub_710064E178(const sead::SafeString& name, u32 placement_type, + const sead::Vector3f& pos); + bool sub_710064EF24(ActorSpawnInfo* info, const sead::Vector3f& pos); + void sub_710064F744(u8 a1, u8 a2); + void incrementGroup(); + bool sub_7100650144(PlacementGroup* grp, bool check_exposure); + s32 placeGroup(AutoPlacementFlowRes* res); + s32 sub_7100650908(); + void stepAllRaycasts(); + void sub_7100650C28(phys::RigidBody* rb); + +private: + struct ObjectRef { + Object* obj; + void* _8; + }; + + s16 _0 = 0; + s16 mGroupIdx = -1; + u8 _4 = 0xFF; + u8 _5 = 0xFF; + s16 _6 = 0; + u8 _8 = 0; + u8 _9 = 2; + sead::BitFlag mNearFlag{}; + sead::BitFlag _b{}; + u8 _c = 0; + u8 _d = 0; + u8 _e = 0; + u8 _f = 0; + u8 _10 = 0; + s32 _14 = 0; + sead::Buffer mSpawnInfo; + sead::CriticalSection mCS{}; + sead::SafeArray mGroups{}; + sead::SafeString _8868{}; + PlacementThing mThing1{false}; + PlacementThing mThing2{false}; + PlacementThing mThing3{true}; + void* mX; + sead::Buffer mObjectRefs; +}; + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapAutoPlacementFlowMgr.cpp b/src/KingSystem/Map/mapAutoPlacementFlowMgr.cpp new file mode 100644 index 00000000..3bef06c4 --- /dev/null +++ b/src/KingSystem/Map/mapAutoPlacementFlowMgr.cpp @@ -0,0 +1,61 @@ +#include "KingSystem/Map/mapAutoPlacementFlowMgr.h" +#include +#include +#include "KingSystem/Resource/resLoadRequest.h" + +namespace ksys::map { + +const char* sFlowResNamesData[] = { + "AutoPlacement_Animal.bfevfl", + "AutoPlacement_Bird.bfevfl", + "AutoPlacement_Enemy_Golem_Little.bfevfl", + "AutoPlacement_Enemy_Keese.bfevfl", + "AutoPlacement_Enemy_Lizalfos.bfevfl", + "AutoPlacement_Enemy_Octarock.bfevfl", + "AutoPlacement_Enemy_Wizzrobe.bfevfl", + "AutoPlacement_Enemy_Fish.bfevfl", + "AutoPlacement_Enemy_Insect.bfevfl", + "AutoPlacement_Enemy_Material.bfevfl", +}; +sead::Buffer sFlowResNames{sFlowResNamesData}; + +const char* sFlowNearResNamesData[] = { + "AutoPlacementNear_Enemy_Assassin_Middle.bfevfl", + "AutoPlacementNear_Enemy_Assassin_Shooter_Junior.bfevfl", + "AutoPlacementNear_Enemy_Chuchu.bfevfl", + "AutoPlacementNear_Enemy_Dragon.bfevfl", + "AutoPlacementNear_Enemy_Lizalfos.bfevfl", + "AutoPlacementNear_Enemy_Octarock.bfevfl", + "AutoPlacementNear_Enemy_Stal.bfevfl", +}; +sead::Buffer sFlowNearResNames{sFlowNearResNamesData}; + +void AutoPlacementFlowMgr::loadEventFlows() { + for (int i = 0; i < mFlowArray.size(); i++) { + auto& flow = mFlowArray[i]; + flow.evfl_name = sFlowResNames[i]; + flow.idx = 0xFF; + + sead::FixedSafeString<128> path; + path.format("EventFlow/%s", flow.evfl_name.cstr()); + res::LoadRequest req; + req.mRequester = "AutoPlacementFlow"; + + flow.handle.requestLoad(path, &req); + } + + for (int i = 0; i < mFlowNearArray.size(); i++) { + auto& flow = mFlowNearArray[i]; + flow.evfl_name = sFlowResNames[i]; + flow.idx = 0xFF; + + sead::FixedSafeString<128> path; + path.format("EventFlow/%s", flow.evfl_name.cstr()); + res::LoadRequest req; + req.mRequester = "AutoPlacementFlow"; + + flow.handle.requestLoad(path, &req); + } +} + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapAutoPlacementFlowMgr.h b/src/KingSystem/Map/mapAutoPlacementFlowMgr.h new file mode 100644 index 00000000..df3b6648 --- /dev/null +++ b/src/KingSystem/Map/mapAutoPlacementFlowMgr.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include +#include "KingSystem/Resource/resHandle.h" + +namespace ksys::map { + +class AutoPlacement; + +struct AutoPlacementFlowRes { + void start(AutoPlacement* placement, const sead::SafeString& unit_name, int*); + + res::Handle handle; + sead::SafeString evfl_name; + evfl::FlowchartContext flowchart_ctx; + AutoPlacement* placement; + sead::SafeString unit_name; + u8 idx; + s8 placement_type; +}; + +class AutoPlacementFlowMgr { + SEAD_SINGLETON_DISPOSER(AutoPlacementFlowMgr) +public: + AutoPlacementFlowMgr(); + virtual ~AutoPlacementFlowMgr(); + + void loadEventFlows(); + + AutoPlacementFlowRes* getFlow(const sead::SafeString& actor_name, bool near_flow); + +private: + sead::Heap* mHeap; + sead::SafeArray mFlowArray; + sead::SafeArray mFlowNearArray; +}; + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapAutoPlacementMgr.cpp b/src/KingSystem/Map/mapAutoPlacementMgr.cpp new file mode 100644 index 00000000..8a3c4983 --- /dev/null +++ b/src/KingSystem/Map/mapAutoPlacementMgr.cpp @@ -0,0 +1,7 @@ +#include "KingSystem/Map/mapAutoPlacementMgr.h" + +namespace ksys::map { + +SEAD_SINGLETON_DISPOSER_IMPL(AutoPlacementMgr) + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapAutoPlacementMgr.h b/src/KingSystem/Map/mapAutoPlacementMgr.h index 0fb8e722..dc918b32 100644 --- a/src/KingSystem/Map/mapAutoPlacementMgr.h +++ b/src/KingSystem/Map/mapAutoPlacementMgr.h @@ -1,22 +1,41 @@ #pragma once #include +#include +#include #include +#include "KingSystem/Utils/Types.h" + namespace ksys::act { class Actor; -} // namespace ksys::act +} // namespace ksys::act namespace ksys::map { class AutoPlacementMgr { -SEAD_SINGLETON_DISPOSER(AutoPlacementMgr) + SEAD_SINGLETON_DISPOSER(AutoPlacementMgr) public: AutoPlacementMgr(); virtual ~AutoPlacementMgr(); - bool sub_7100659E40(ksys::act::Actor* actor, const sead::SafeString& actor_name, int count, bool is_box); - void sub_7100659F94(ksys::act::Actor* actor); + bool sub_7100659E40(act::Actor* actor, const sead::SafeString& actor_name, int count, + bool is_box); + void sub_7100659F94(act::Actor* actor); + + // 0x0000007100654e44 + bool threadFn(); + // 0x0000007100656030 + bool auto9(); + // 0x0000007100656d24 + bool auto2(const sead::SafeString& name, const sead::Vector3f& pos); + // 0x0000007100659188 + bool auto0(const sead::Vector3f& pos, u32 placement_type); + // 0x0000007100659350 + bool auto11(const sead::Vector3f& pos); + + sead::DelegateR mDelegate; }; +// KSYS_CHECK_SIZE_NX150(AutoPlacementMgr, 0x189E38); } // namespace ksys::map diff --git a/src/KingSystem/Utils/MathUtil.h b/src/KingSystem/Utils/MathUtil.h index d7158213..7450440e 100644 --- a/src/KingSystem/Utils/MathUtil.h +++ b/src/KingSystem/Utils/MathUtil.h @@ -21,9 +21,8 @@ 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); } -// NON_MATCHING: float regalloc -inline float dot(const sead::Vector3f& u, const sead::Matrix34f& mtx, int row) { - return u.x * mtx(row, 0) + u.y * mtx(row, 1) + mtx(row, 2) * u.z; +inline float dot(sead::Vector3f u, const sead::Matrix34f& mtx, int row) { + return u.x * mtx(row, 0) + u.y * mtx(row, 1) + u.z * mtx(row, 2); } } // namespace ksys::util diff --git a/src/KingSystem/World/worldWeatherMgr.h b/src/KingSystem/World/worldWeatherMgr.h index 23242d28..0a6b8df9 100644 --- a/src/KingSystem/World/worldWeatherMgr.h +++ b/src/KingSystem/World/worldWeatherMgr.h @@ -16,6 +16,8 @@ public: void onUnload(); void rerollClimateWindPowers(); + static bool isExposureZero(); + u8 _20[0x398 - 0x20]; }; KSYS_CHECK_SIZE_NX150(WeatherMgr, 0x398);