OdysseyDecomp/lib/al/Library/Area/AreaObjDirector.cpp

162 lines
5.2 KiB
C++

#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