#include "Library/Area/AreaObjDirector.h" #include "Library/Area/AreaInitInfo.h" #include "Library/Area/AreaObj.h" #include "Library/Area/AreaObjFactory.h" #include "Library/Area/AreaObjGroup.h" #include "Library/Area/AreaObjMtxConnecter.h" #include "Library/Placement/PlacementFunction.h" #include "Library/Placement/PlacementInfo.h" namespace al { AreaObjDirector::AreaObjDirector() = default; void AreaObjDirector::init(const AreaObjFactory* factory) { mFactory = factory; mMtxConnecterHolder = new AreaObjMtxConnecterHolder(0x100); s32 nFactoryEntries = mFactory->getNumFactoryEntries(); mAreaGroups = new AreaObjGroup*[nFactoryEntries]; for (s32 i = 0; i < nFactoryEntries; i++) mAreaGroups[i] = nullptr; } void AreaObjDirector::endInit() {} void AreaObjDirector::update() { if (mMtxConnecterHolder) mMtxConnecterHolder->update(); } void AreaObjDirector::placement(const AreaInitInfo& initInfo) { createAreaObjGroup(initInfo); createAreaObjGroupBuffer(); placementAreaObj(initInfo); } void AreaObjDirector::placement(const AreaInitInfo* initInfoArray, s32 initInfoCount) { for (s32 i = 0; i < initInfoCount; i++) createAreaObjGroup(initInfoArray[i]); createAreaObjGroupBuffer(); for (s32 i = 0; i < initInfoCount; i++) placementAreaObj(initInfoArray[i]); } void AreaObjDirector::createAreaObjGroup(const AreaInitInfo& initInfo) { PlacementInfo placementInfo(initInfo); s32 pInfoCount = getCountPlacementInfo(placementInfo); for (s32 i = 0; i < pInfoCount; i++) { PlacementInfo placementInfo2; tryGetPlacementInfoByIndex(&placementInfo2, placementInfo, i); const char* pInfoName = nullptr; tryGetObjectName(&pInfoName, placementInfo2); AreaCreatorFunction creatorFunc = nullptr; s32 entryIndex = mFactory->getEntryIndex(&creatorFunc, pInfoName); if (!creatorFunc) continue; if (!mAreaGroups[entryIndex]) { s32 size = mFactory->tryFindAddBufferSize(pInfoName); mAreaGroups[entryIndex] = new AreaObjGroup(pInfoName, size); } mAreaGroups[entryIndex]->incrementCount(); } } void AreaObjDirector::createAreaObjGroupBuffer() { for (s32 i = 0; i < mFactory->getAreaGroupCount(); i++) { const AreaGroupInfo& addBuffer = mFactory->getAreaGroupInfo()[i]; AreaCreatorFunction creatorFunc = nullptr; s32 entryIndex = mFactory->getEntryIndex(&creatorFunc, addBuffer.name); if (!mAreaGroups[entryIndex]) mAreaGroups[entryIndex] = new AreaObjGroup(addBuffer.name, addBuffer.size); } s32 areaGroupCount = 0; s32 nEntries = mFactory->getNumFactoryEntries(); for (s32 i = 0; i < nEntries; i++) { if (!mAreaGroups[i]) continue; mAreaGroups[i]->createBuffer(); areaGroupCount++; for (s32 areaGroupIndex = i; areaGroupIndex > 0; areaGroupIndex--) { AreaObjGroup* prevAreaObjGroup = mAreaGroups[areaGroupIndex - 1]; if (prevAreaObjGroup) { if (strcmp(mAreaGroups[areaGroupIndex]->getName(), prevAreaObjGroup->getName()) > -1) break; } mAreaGroups[areaGroupIndex - 1] = mAreaGroups[areaGroupIndex]; mAreaGroups[areaGroupIndex] = prevAreaObjGroup; } } mAreaGroupCount = areaGroupCount; } void AreaObjDirector::placementAreaObj(const AreaInitInfo& initInfo) { PlacementInfo pInfo(initInfo); s32 pInfoCount = getCountPlacementInfo(pInfo); for (s32 j = 0; j < pInfoCount; j++) { PlacementInfo pInfo2; tryGetPlacementInfoByIndex(&pInfo2, pInfo, j); const char* pInfoName = nullptr; tryGetObjectName(&pInfoName, pInfo2); AreaCreatorFunction creatorFunc = nullptr; mFactory->getEntryIndex(&creatorFunc, pInfoName); if (!creatorFunc) continue; const char* displayName; getDisplayName(&displayName, pInfo2); AreaObj* areaObj = creatorFunc(displayName); AreaInitInfo initInfo2(pInfo2, initInfo); areaObj->init(initInfo2); AreaObjGroup* areaGroup = getAreaObjGroup(pInfoName); areaGroup->registerAreaObj(areaObj); mMtxConnecterHolder->tryAddArea(areaObj, pInfo2); } } AreaObjGroup* AreaObjDirector::getAreaObjGroup(const char* name) const { s32 lower = 0; s32 upper = mAreaGroupCount; while (lower < upper) { s32 i = (lower + upper) / 2; s32 equalString = strcmp(name, mAreaGroups[i]->getName()); if (equalString == 0) return mAreaGroups[i]; else if (equalString > 0) lower = i + 1; else upper = i; } return nullptr; } bool AreaObjDirector::isExistAreaGroup(const char* name) const { return getAreaObjGroup(name) != nullptr; } AreaObj* AreaObjDirector::getInVolumeAreaObj(const char* name, const sead::Vector3f& position) { AreaObjGroup* areaGroup = getAreaObjGroup(name); if (!areaGroup) return nullptr; return areaGroup->getInVolumeAreaObj(position); } AreaObjMtxConnecterHolder* AreaObjDirector::getMtxConnecterHolder() const { return mMtxConnecterHolder; } } // namespace al