CAutoMapper work

This commit is contained in:
Jack Andersen 2017-04-15 19:52:43 -10:00
parent 6056857cab
commit c3f04bcbaa
14 changed files with 662 additions and 75 deletions

View File

@ -7,6 +7,7 @@ namespace DataSpec
{
struct ITweakAutoMapper : public ITweak
{
virtual bool GetShowOneMiniMapArea() const=0;
virtual bool GetScaleMoveSpeedWithCamDist() const=0;
virtual float GetCamDist() const=0;
virtual float GetMinCamDist() const=0;
@ -19,6 +20,7 @@ struct ITweakAutoMapper : public ITweak
virtual float GetMiniCamAngle() const=0;
virtual float GetOpenMapScreenTime() const=0;
virtual float GetCloseMapScreenTime() const=0;
virtual float GetHintPanTime() const=0;
virtual float GetCamZoomUnitsPerFrame() const=0;
virtual float GetCamRotateDegreesPerFrame() const=0;
virtual float GetBaseMapScreenCameraMoveSpeed() const=0;
@ -33,6 +35,7 @@ struct ITweakAutoMapper : public ITweak
virtual const zeus::CVector3f& GetDoorCenter() const=0;
virtual float GetMiniMapViewportWidth() const=0;
virtual float GetMiniMapViewportHeight() const=0;
virtual float GetMiniMapCamDistScale() const=0;
virtual float GetUniverseCamDist() const=0;
virtual float GetMinUniverseCamDist() const=0;
virtual float GetMaxUniverseCamDist() const=0;

View File

@ -11,7 +11,7 @@ namespace DNAMP1
struct CTweakAutoMapper : public ITweakAutoMapper
{
DECL_YAML
Value<bool> x4_24_ : 1;
Value<bool> x4_24_showOneMiniMapArea : 1;
Value<bool> x4_25_ : 1;
Value<bool> x4_26_scaleMoveSpeedWithCamDist : 1;
Value<float> x8_camDist;
@ -39,7 +39,7 @@ struct CTweakAutoMapper : public ITweakAutoMapper
float x60_ = 0.4f;
Value<float> x64_openMapScreenTime;
Value<float> x68_closeMapScreenTime;
Value<float> x6c_;
Value<float> x6c_hintPanTime;
Value<float> x70_zoomUnitsPerFrame;
Value<float> x74_rotateDegPerFrame;
Value<float> x78_baseMapScreenCameraMoveSpeed;
@ -59,7 +59,7 @@ struct CTweakAutoMapper : public ITweakAutoMapper
Value<float> xb4_;
Value<float> xb8_miniMapViewportWidth;
Value<float> xbc_miniMapViewportHeight;
Value<float> xc0_;
Value<float> xc0_miniMapCamDistScale;
Value<float> xc4_;
Value<float> xc8_;
Value<bool> xcc_;
@ -82,6 +82,7 @@ struct CTweakAutoMapper : public ITweakAutoMapper
CTweakAutoMapper() = default;
CTweakAutoMapper(athena::io::IStreamReader& r) { this->read(r); }
bool GetShowOneMiniMapArea() const { return x4_24_showOneMiniMapArea; }
bool GetScaleMoveSpeedWithCamDist() const { return x4_26_scaleMoveSpeedWithCamDist; }
float GetCamDist() const { return x8_camDist; }
float GetMinCamDist() const { return xc_minCamDist; }
@ -94,6 +95,7 @@ struct CTweakAutoMapper : public ITweakAutoMapper
float GetMiniCamAngle() const { return x30_miniCamAngle; }
float GetOpenMapScreenTime() const { return x64_openMapScreenTime; }
float GetCloseMapScreenTime() const { return x68_closeMapScreenTime; }
float GetHintPanTime() const { return x6c_hintPanTime; }
float GetCamZoomUnitsPerFrame() const { return x70_zoomUnitsPerFrame; }
float GetCamRotateDegreesPerFrame() const { return x74_rotateDegPerFrame; }
float GetBaseMapScreenCameraMoveSpeed() const { return x78_baseMapScreenCameraMoveSpeed; }
@ -108,6 +110,7 @@ struct CTweakAutoMapper : public ITweakAutoMapper
const zeus::CVector3f& GetDoorCenter() const { return xa4_doorCenter; }
float GetMiniMapViewportWidth() const { return xb8_miniMapViewportWidth; }
float GetMiniMapViewportHeight() const { return xbc_miniMapViewportHeight; }
float GetMiniMapCamDistScale() const { return xc0_miniMapCamDistScale; }
float GetUniverseCamDist() const { return xd0_universeCamDist; }
float GetMinUniverseCamDist() const { return xd4_minUniverseCamDist; }
float GetMaxUniverseCamDist() const { return xd8_maxUniverseCamDist; }

View File

@ -9,6 +9,8 @@
#include "Particle/CGenDescription.hpp"
#include "MP1/MP1.hpp"
#include "Input/ControlMapper.hpp"
#include "GuiSys/CGuiFrame.hpp"
#include "GuiSys/CGuiTextPane.hpp"
namespace urde
{
@ -161,6 +163,39 @@ bool CAutoMapper::CanLeaveMapScreenInternal(const CStateManager& mgr) const
return false;
}
void CAutoMapper::LeaveMapScreen(const CStateManager& mgr)
{
if (x1c0_nextState == EAutoMapperState::MapScreenUniverse)
{
xa8_renderStates[1].x2c_drawDepth1 = GetMapAreaMiniMapDrawDepth();
xa8_renderStates[1].x30_drawDepth2 = GetMapAreaMiniMapDrawDepth();
xa8_renderStates[0].x2c_drawDepth1 = GetMapAreaMiniMapDrawDepth();
xa8_renderStates[0].x30_drawDepth2 = GetMapAreaMiniMapDrawDepth();
SetupMiniMapWorld(mgr);
}
else
{
x328_ = 2;
xa8_renderStates[1] = xa8_renderStates[0];
xa8_renderStates[2] = xa8_renderStates[1];
xa0_curAreaId = x24_world->IGetCurrentAreaId();
xa8_renderStates[1].x20_areaPoint = GetAreaPointOfInterest(mgr, xa0_curAreaId);
xa8_renderStates[1].x4c_pointEase = SAutoMapperRenderState::Ease::Linear;
xa8_renderStates[1].x2c_drawDepth1 = GetMapAreaMiniMapDrawDepth();
xa8_renderStates[1].x30_drawDepth2 = GetMapAreaMiniMapDrawDepth();
xa8_renderStates[1].x50_depth1Ease = SAutoMapperRenderState::Ease::Linear;
xa8_renderStates[1].x54_depth2Ease = SAutoMapperRenderState::Ease::Linear;
ResetInterpolationTimer(0.25f);
}
}
void CAutoMapper::SetupMiniMapWorld(const CStateManager& mgr)
{
const CWorld& wld = *mgr.GetWorld();
const_cast<CMapWorld*>(wld.GetMapWorld())->SetWhichMapAreasLoaded(wld, wld.GetCurrentAreaId(), 3);
x328_ = 3;
}
bool CAutoMapper::HasCurrentMapUniverseWorld() const
{
ResId mlvlId = x24_world->IGetWorldAssetId();
@ -201,6 +236,104 @@ bool CAutoMapper::CheckDummyWorldLoad(const CStateManager& mgr)
return true;
}
void CAutoMapper::UpdateHintNavigation(float dt, const CStateManager& mgr)
{
SAutoMapperHintStep& nextStep = x1e0_hintSteps.front();
bool oldProcessing = nextStep.x8_processing;
nextStep.x8_processing = true;
switch (nextStep.x0_type)
{
case SAutoMapperHintStep::Type::PanToArea:
{
if (x24_world->IGetMapWorld()->GetMapArea(nextStep.x4_areaId))
{
xa8_renderStates[2] = xa8_renderStates[0];
xa8_renderStates[1].x20_areaPoint = GetAreaPointOfInterest(mgr, nextStep.x4_areaId);
xa8_renderStates[1].ResetInterpolation();
ResetInterpolationTimer(2.f * g_tweakAutoMapper->GetHintPanTime());
x1e0_hintSteps.pop_front();
}
break;
}
case SAutoMapperHintStep::Type::PanToWorld:
{
const CMapUniverse::CMapWorldData& mwData = x8_mapu->GetMapWorldDataByWorldId(nextStep.x4_worldId);
xa8_renderStates[2] = xa8_renderStates[0];
xa8_renderStates[1].x20_areaPoint = mwData.GetWorldCenterPoint();
xa8_renderStates[1].ResetInterpolation();
ResetInterpolationTimer(2.f * g_tweakAutoMapper->GetHintPanTime());
x1e0_hintSteps.pop_front();
break;
}
case SAutoMapperHintStep::Type::SwitchToUniverse:
{
if (HasCurrentMapUniverseWorld())
{
BeginMapperStateTransition(EAutoMapperState::MapScreenUniverse, mgr);
x1e0_hintSteps.pop_front();
}
else
{
x1e0_hintSteps.clear();
}
break;
}
case SAutoMapperHintStep::Type::SwitchToWorld:
{
x1e0_hintSteps.pop_front();
x32c_loadingDummyWorld = true;
if (CheckDummyWorldLoad(mgr))
break;
x1e0_hintSteps.clear();
break;
}
case SAutoMapperHintStep::Type::ShowBeacon:
{
if (!oldProcessing)
{
if (xa0_curAreaId == mgr.GetNextAreaId() && x24_world == mgr.GetWorld())
CSfxManager::SfxStart(1386, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
else
CSfxManager::SfxStart(1387, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
}
nextStep.x4_float = std::max(0.f, nextStep.x4_float - dt);
for (SAutoMapperHintLocation& loc : x1f8_hintLocations)
{
if (x24_world->IGetWorldAssetId() == loc.x8_worldId && xa0_curAreaId == loc.xc_areaId)
{
nextStep.x4_float = 1.f - std::min(nextStep.x4_float / 0.5f, 1.f);
break;
}
}
if (nextStep.x4_float != 0.f)
break;
x1e0_hintSteps.pop_front();
break;
}
case SAutoMapperHintStep::Type::ZoomOut:
{
xa8_renderStates[2] = xa8_renderStates[0];
xa8_renderStates[1].x18_camDist = g_tweakAutoMapper->GetMaxCamDist();
xa8_renderStates[1].ResetInterpolation();
xa8_renderStates[1].x48_camEase = SAutoMapperRenderState::Ease::Linear;
ResetInterpolationTimer(0.5f);
x1e0_hintSteps.pop_front();
break;
}
case SAutoMapperHintStep::Type::ZoomIn:
{
xa8_renderStates[2] = xa8_renderStates[0];
xa8_renderStates[1].x18_camDist = g_tweakAutoMapper->GetCamDist();
xa8_renderStates[1].ResetInterpolation();
xa8_renderStates[1].x48_camEase = SAutoMapperRenderState::Ease::Linear;
ResetInterpolationTimer(0.5f);
x1e0_hintSteps.pop_front();
break;
}
default: break;
}
}
bool CAutoMapper::CanLeaveMapScreen(const CStateManager& mgr) const
{
return x328_ == 3 && CanLeaveMapScreenInternal(mgr);
@ -283,10 +416,15 @@ void CAutoMapper::BeginMapperStateTransition(EAutoMapperState state, const CStat
}
}
void CAutoMapper::CompleteMapperStateTransition(const CStateManager&)
{
}
void CAutoMapper::ResetInterpolationTimer(float t)
{
x1c4_ = t;
x1c8_ = 0.f;
x1c4_interpDur = t;
x1c8_interpTime = 0.f;
}
CAutoMapper::SAutoMapperRenderState
@ -525,14 +663,14 @@ void CAutoMapper::ProcessMapZoomInput(const CFinalInput& input, const CStateMana
{
xa8_renderStates[0].x18_camDist =
GetClampedMapScreenCameraDistance(xa8_renderStates[0].x18_camDist - delta);
x2f0_ = 1;
x2f0_rTriggerPos = 1;
x324_zoomState = EZoomState::In;
}
else if (x324_zoomState == EZoomState::Out)
{
xa8_renderStates[0].x18_camDist =
GetClampedMapScreenCameraDistance(xa8_renderStates[0].x18_camDist + delta);
x2ec_ = 1;
x2ec_lTriggerPos = 1;
x324_zoomState = EZoomState::Out;
}
@ -629,7 +767,7 @@ void CAutoMapper::ProcessMapPanInput(const CFinalInput& input, const CStateManag
}
else
{
std::pair<TAreaId, int> areas = FindClosestVisibleWorld(xa8_renderStates[0].x20_areaPoint, camRot.basis[1], mgr);
std::pair<int, int> areas = FindClosestVisibleWorld(xa8_renderStates[0].x20_areaPoint, camRot.basis[1], mgr);
const zeus::CTransform& hex = x8_mapu->GetMapWorldData(areas.first).GetMapAreaData(areas.second);
zeus::CVector3f areaToHex = hex.origin - xa8_renderStates[0].x20_areaPoint;
if (areaToHex.magnitude() < speed)
@ -708,16 +846,16 @@ void CAutoMapper::ProcessMapScreenInput(const CFinalInput& input, const CStateMa
}
}
x2f4_ = 0;
x2f4_aButtonPos = 0;
if (input.PA())
x2f4_ = 1;
x2f4_aButtonPos = 1;
if (IsInMapperState(EAutoMapperState::MapScreen) || IsInMapperState(EAutoMapperState::MapScreenUniverse))
{
x2e4_lStickPos = 0;
x2e8_rStickPos = 0;
x2ec_ = 0;
x2f0_ = 0;
x2ec_lTriggerPos = 0;
x2f0_rTriggerPos = 0;
ProcessMapRotateInput(input, mgr);
ProcessMapZoomInput(input, mgr);
ProcessMapPanInput(input, mgr);
@ -744,16 +882,62 @@ zeus::CVector3f CAutoMapper::GetAreaPointOfInterest(const CStateManager&, TAreaI
return mapa->GetAreaPostTransform(*x24_world, aid) * mapa->GetAreaCenterPoint();
}
TAreaId CAutoMapper::FindClosestVisibleArea(const zeus::CVector3f&, const zeus::CUnitVector3f&, const CStateManager&,
const IWorld&, const CMapWorldInfo&) const
TAreaId CAutoMapper::FindClosestVisibleArea(const zeus::CVector3f& point,
const zeus::CUnitVector3f& camDir, const CStateManager& mgr,
const IWorld& wld, const CMapWorldInfo& mwInfo) const
{
return 0;
float minDist = 9999.f;
TAreaId closestArea = xa0_curAreaId;
const CMapWorld* mw = wld.IGetMapWorld();
std::vector<TAreaId> areas = mw->GetVisibleAreas(wld, mwInfo);
for (TAreaId areaId : areas)
{
const CMapArea* mapa = mw->GetMapArea(areaId);
zeus::CVector3f xfPoint = mapa->GetAreaPostTransform(wld, areaId) * mapa->GetAreaCenterPoint();
zeus::CVector3f pointToArea = xfPoint - point;
pointToArea = pointToArea.canBeNormalized() ?
point + (pointToArea.normalized().dot(camDir) * pointToArea.magnitude()) * camDir : point;
pointToArea -= xfPoint;
float dist = pointToArea.magnitude();
if (dist < minDist)
{
minDist = dist;
closestArea = areaId;
}
}
return closestArea;
}
std::pair<TAreaId, int>
CAutoMapper::FindClosestVisibleWorld(const zeus::CVector3f&, const zeus::CUnitVector3f&, const CStateManager&) const
std::pair<int, int>
CAutoMapper::FindClosestVisibleWorld(const zeus::CVector3f& point,
const zeus::CUnitVector3f& camDir,
const CStateManager& mgr) const
{
return {};
float minDist = 29999.f;
std::pair<int, int> closestWorld = {xa0_curAreaId, xa0_curAreaId};
for (int w=0 ; w<x8_mapu->GetNumMapWorldDatas() ; ++w)
{
const CMapUniverse::CMapWorldData& mwData = x8_mapu->GetMapWorldData(w);
const CMapWorldInfo& mwInfo = *g_GameState->StateForWorld(mwData.GetWorldAssetId()).MapWorldInfo();
if (!mwInfo.IsAnythingSet())
continue;
for (int i=0 ; i<mwData.GetNumMapAreaDatas() ; ++i)
{
const zeus::CVector3f& mwOrigin = mwData.GetMapAreaData(i).origin;
zeus::CVector3f pointToArea = mwOrigin - point;
pointToArea = pointToArea.canBeNormalized() ?
point + (pointToArea.normalized().dot(camDir) * pointToArea.magnitude()) * camDir : point;
pointToArea -= mwOrigin;
float dist = pointToArea.magnitude();
if (dist < minDist)
{
minDist = dist;
closestWorld.first = w;
closestWorld.second = i;
}
}
}
return closestWorld;
}
zeus::CVector2i CAutoMapper::GetMiniMapViewportSize()
@ -802,6 +986,39 @@ float CAutoMapper::GetMapAreaMiniMapDrawAlphaOutlineUnvisited(const CStateManage
stateMgr.Player()->GetMapAlpha() + mapAlphaInterp;
}
float CAutoMapper::GetDesiredMiniMapCameraDistance(const CStateManager& mgr) const
{
const CMapWorldInfo& mwInfo = *g_GameState->StateForWorld(x24_world->IGetWorldAssetId()).MapWorldInfo();
const CMapWorld* mw = x24_world->IGetMapWorld();
zeus::CAABox aabb;
const IGameArea* area = x24_world->IGetAreaAlways(xa0_curAreaId);
const CMapArea* mapa = mw->GetMapArea(xa0_curAreaId);
bool oneMiniMapArea = g_tweakAutoMapper->GetShowOneMiniMapArea();
for (int i = -1 ; i < oneMiniMapArea ? 0 : area->IGetNumAttachedAreas() ; ++i)
{
TAreaId aid = i == -1 ? xa0_curAreaId : area->IGetAttachedAreaId(i);
const CMapArea* attMapa = mw->GetMapArea(aid);
if (attMapa->GetIsVisibleToAutoMapper(mwInfo.IsWorldVisible(aid), mwInfo.IsAreaVisible(aid)))
{
zeus::CAABox areaAABB =
attMapa->GetBoundingBox().getTransformedAABox(attMapa->GetAreaPostTransform(*x24_world, aid));
aabb.accumulateBounds(areaAABB.min);
aabb.accumulateBounds(areaAABB.max);
}
}
zeus::CVector3f xfPoint = mapa->GetAreaPostTransform(*x24_world, xa0_curAreaId) * mapa->GetAreaCenterPoint();
zeus::CVector3f maxMargin;
maxMargin.x = std::max(xfPoint.x - aabb.min.x, aabb.max.x - xfPoint.x);
maxMargin.y = std::max(xfPoint.y - aabb.min.y, aabb.max.y - xfPoint.y);
maxMargin.z = std::max(xfPoint.z - aabb.min.z, aabb.max.z - xfPoint.z);
zeus::CVector3f extent = mapa->GetBoundingBox().max - mapa->GetBoundingBox().min;
return (0.5f * (0.5f * extent.magnitude()) + 0.5f * maxMargin.magnitude()) *
g_tweakAutoMapper->GetMiniMapCamDistScale() *
std::tan(M_PIF / 2.f - 0.5f * 2.f * M_PIF * (xa8_renderStates[0].x1c_camAngle / 360.f));
}
float CAutoMapper::GetClampedMapScreenCameraDistance(float v)
{
if (x1bc_state == EAutoMapperState::MapScreenUniverse)
@ -825,10 +1042,310 @@ void CAutoMapper::ProcessControllerInput(const CFinalInput& input, CStateManager
if (IsInMapperState(EAutoMapperState::MapScreen) || IsInMapperState(EAutoMapperState::MapScreenUniverse))
{
if (x32c_loadingDummyWorld)
CheckDummyWorldLoad(mgr);
else if (x1e0_hintSteps.size())
UpdateHintNavigation(input.DeltaTime(), mgr);
else if (!x328_)
ProcessMapScreenInput(input, mgr);
}
}
zeus::CMatrix3f camRot = xa8_renderStates[0].x8_camOrientation.toTransform().buildMatrix3f();
if (IsInMapperState(EAutoMapperState::MapScreen))
{
CMapWorldInfo& mwInfo = *g_GameState->StateForWorld(x24_world->IGetWorldAssetId()).MapWorldInfo();
TAreaId aid = FindClosestVisibleArea(xa8_renderStates[0].x20_areaPoint, camRot[1], mgr, *x24_world, mwInfo);
if (aid != xa0_curAreaId)
{
xa0_curAreaId = aid;
xa8_renderStates[0].x2c_drawDepth1 = GetMapAreaMaxDrawDepth(mgr, xa0_curAreaId);
xa8_renderStates[0].x30_drawDepth2 = GetMapAreaMaxDrawDepth(mgr, xa0_curAreaId);
}
}
else if (IsInMapperState(EAutoMapperState::MapScreenUniverse))
{
int oldWldIdx = x9c_worldIdx;
if (x1e0_hintSteps.size())
{
SAutoMapperHintStep& nextStep = x1e0_hintSteps.front();
if (nextStep.x0_type == SAutoMapperHintStep::Type::PanToWorld ||
nextStep.x0_type == SAutoMapperHintStep::Type::SwitchToWorld)
{
SetCurWorldAssetId(nextStep.x4_worldId);
}
else
{
std::pair<int, int> wld = FindClosestVisibleWorld(xa8_renderStates[0].x20_areaPoint,
camRot[1], mgr);
x9c_worldIdx = wld.first;
}
}
else
{
std::pair<int, int> wld = FindClosestVisibleWorld(xa8_renderStates[0].x20_areaPoint,
camRot[1], mgr);
x9c_worldIdx = wld.first;
}
if (x9c_worldIdx != oldWldIdx)
{
ResId curMlvl = g_GameState->CurrentWorldAssetId();
for (int i=0 ; i<x14_dummyWorlds.size() ; ++i)
{
auto& wld = x14_dummyWorlds[i];
const CMapUniverse::CMapWorldData& mwData = x8_mapu->GetMapWorldData(i);
if (i == x9c_worldIdx && curMlvl != mwData.GetWorldAssetId())
{
if (g_ResFactory->CanBuild(SObjectTag{FOURCC('MLVL'), mwData.GetWorldAssetId()}))
wld = std::make_unique<CDummyWorld>(mwData.GetWorldAssetId(), true);
}
else
{
wld.reset();
}
}
x24_world = (curMlvl == x8_mapu->GetMapWorldData(x9c_worldIdx).GetWorldAssetId()) ? mgr.GetWorld() : nullptr;
}
}
if (x300_textpane_instructions)
{
if (x84_)
{
if (x78_areaHintDesc.IsLoaded())
{
x2fc_textpane_hint->TextSupport()->SetText(x78_areaHintDesc->GetString(0));
x304_textpane_instructions1->TextSupport()->SetText(u"");
x300_textpane_instructions->TextSupport()->SetText(u"");
x308_textpane_instructions2->TextSupport()->SetText(u"");
}
else
{
x2fc_textpane_hint->TextSupport()->SetText(u"");
std::u16string str = hecl::UTF8ToChar16(
hecl::Format("&image=SI,0.6,1.0,%8.8X;", u32(g_tweakPlayerRes->x24_lStick[x2e4_lStickPos])));
str += g_MainStringTable->GetString(46); // Rotate
x300_textpane_instructions->TextSupport()->SetText(str);
str = hecl::UTF8ToChar16(
hecl::Format("&image=SI,0.6,1.0,%8.8X;", u32(g_tweakPlayerRes->x4c_cStick[x2e8_rStickPos])));
str += g_MainStringTable->GetString(47); // Move
x304_textpane_instructions1->TextSupport()->SetText(str);
str = hecl::UTF8ToChar16(
hecl::Format("&image=%8.8X;", u32(g_tweakPlayerRes->x74_lTrigger[x2ec_lTriggerPos])));
str += g_MainStringTable->GetString(48); // Zoom
str += hecl::UTF8ToChar16(
hecl::Format("&image=%8.8X;", u32(g_tweakPlayerRes->x80_rTrigger[x2f0_rTriggerPos])));
x308_textpane_instructions2->TextSupport()->SetText(str);
}
}
}
if (input.PY())
{
CPersistentOptions& sysOpts = g_GameState->SystemOptions();
switch (sysOpts.GetAutoMapperKeyState())
{
case 0:
sysOpts.SetAutoMapperKeyState(1);
CSfxManager::SfxStart(1452, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
break;
case 1:
sysOpts.SetAutoMapperKeyState(2);
CSfxManager::SfxStart(1446, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
break;
case 2:
sysOpts.SetAutoMapperKeyState(0);
CSfxManager::SfxStart(1453, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
break;
default: break;
}
}
if (input.PZ() || input.PB())
{
if (!x328_)
{
if (CanLeaveMapScreenInternal(mgr))
LeaveMapScreen(mgr);
if (NotHintNavigating())
{
BeginMapperStateTransition(EAutoMapperState::MapScreenUniverse, mgr);
x328_ = 1;
}
}
}
}
void CAutoMapper::Update(float dt, const CStateManager& mgr)
{
if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap)
{
x1d8_ = std::fmod(x1d8_ + dt, 0.75f);
x1dc_ = x1d8_ < 0.375f ? x1d8_ / 0.375f : (0.75f - x1d8_) / 0.375f;
}
if (!m_frmeInitialized && x28_frmeMapScreen.IsLoaded())
{
m_frmeInitialized = true;
static_cast<CGuiTextPane*>(x28_frmeMapScreen->FindWidget("textpane_left"))->TextSupport()->
SetText(g_MainStringTable->GetString(42));
static_cast<CGuiTextPane*>(x28_frmeMapScreen->FindWidget("textpane_yicon"))->TextSupport()->
SetText(g_MainStringTable->GetString(43));
x2fc_textpane_hint = static_cast<CGuiTextPane*>(x28_frmeMapScreen->FindWidget("textpane_hint"));
x300_textpane_instructions = static_cast<CGuiTextPane*>(x28_frmeMapScreen->FindWidget("textpane_instructions"));
x304_textpane_instructions1 = static_cast<CGuiTextPane*>(x28_frmeMapScreen->FindWidget("textpane_instructions1"));
x308_textpane_instructions2 = static_cast<CGuiTextPane*>(x28_frmeMapScreen->FindWidget("textpane_instructions2"));
CGuiTextPane* mapLegend = static_cast<CGuiTextPane*>(x28_frmeMapScreen->FindWidget("textpane_mapLegend"));
mapLegend->TextSupport()->ClearRenderBuffer();
mapLegend->TextSupport()->SetImageBaseline(true);
mapLegend->TextSupport()->SetText(g_MainStringTable->GetString(49));
x30c_basewidget_leftPane = x28_frmeMapScreen->FindWidget("basewidget_leftPane");
x310_basewidget_yButtonPane = x28_frmeMapScreen->FindWidget("basewidget_yButtonPane");
x314_basewidget_bottomPane = x28_frmeMapScreen->FindWidget("basewidget_bottomPane");
x2f8_textpane_areaname = static_cast<CGuiTextPane*>(x28_frmeMapScreen->FindWidget("textpane_areaname"));
x2f8_textpane_areaname->SetDepthTest(false);
}
if (m_frmeInitialized)
{
x28_frmeMapScreen->Update(dt);
CGuiTextPane* right1 = static_cast<CGuiTextPane*>(x28_frmeMapScreen->FindWidget("textpane_right1"));
std::u16string string;
if (x1bc_state == EAutoMapperState::MapScreenUniverse ||
(x1bc_state == EAutoMapperState::MapScreen && HasCurrentMapUniverseWorld()))
string = hecl::UTF8ToChar16(hecl::Format("image=%8.8X", u32(g_tweakPlayerRes->x98_aButton[x2f4_aButtonPos])));
right1->TextSupport()->SetText(string);
CGuiTextPane* right = static_cast<CGuiTextPane*>(x28_frmeMapScreen->FindWidget("textpane_right"));
if (x1bc_state == EAutoMapperState::MapScreenUniverse)
string = g_MainStringTable->GetString(45);
else if (x1bc_state == EAutoMapperState::MapScreen)
string = g_MainStringTable->GetString(44);
right->TextSupport()->SetText(string);
}
float dt2 = 2.f * dt;
switch (g_GameState->SystemOptions().GetAutoMapperKeyState())
{
case 0: // All shown
x318_leftPanePos -= dt2;
x31c_yButtonPanePos -= dt2;
x320_bottomPanePos -= dt2;
break;
case 1: // Left shown
x318_leftPanePos += dt2;
x31c_yButtonPanePos -= dt2;
x320_bottomPanePos -= dt2;
break;
case 2: // All hidden
x318_leftPanePos += dt2;
x31c_yButtonPanePos += dt2;
x320_bottomPanePos += dt2;
break;
default: break;
}
x318_leftPanePos = std::max(0.f, std::min(x318_leftPanePos, 1.f));
x31c_yButtonPanePos = std::max(0.f, std::min(x31c_yButtonPanePos, 1.f));
x320_bottomPanePos = std::max(0.f, std::min(x320_bottomPanePos, 1.f));
if (x30c_basewidget_leftPane)
{
x30c_basewidget_leftPane->SetLocalTransform(
zeus::CTransform::Translate(x318_leftPanePos * -15.f, 0.f, 0.f) *
x30c_basewidget_leftPane->GetTransform());
}
if (x310_basewidget_yButtonPane)
{
x310_basewidget_yButtonPane->SetLocalTransform(
zeus::CTransform::Translate(0.f, 0.f, x31c_yButtonPanePos * -3.5f) *
x310_basewidget_yButtonPane->GetTransform());
}
if (x314_basewidget_bottomPane)
{
x314_basewidget_bottomPane->SetLocalTransform(
zeus::CTransform::Translate(0.f, 0.f, x320_bottomPanePos * -7.f) *
x314_basewidget_bottomPane->GetTransform());
}
if (IsInMapperState(EAutoMapperState::MiniMap))
{
xa8_renderStates[0].x8_camOrientation = GetMiniMapCameraOrientation(mgr);
float desiredDist = GetDesiredMiniMapCameraDistance(mgr);
if (std::fabs(xa8_renderStates[0].x18_camDist - desiredDist) < 3.f)
xa8_renderStates[0].x18_camDist = desiredDist;
else if (xa8_renderStates[0].x18_camDist < desiredDist)
xa8_renderStates[0].x18_camDist += 3.f;
else
xa8_renderStates[0].x18_camDist -= 3.f;
TAreaId curAid = x24_world->IGetCurrentAreaId();
if (curAid != xa0_curAreaId)
{
xa8_renderStates[2] = xa8_renderStates[0];
xa8_renderStates[1] = xa8_renderStates[0];
xa4_otherAreaId = xa0_curAreaId;
xa0_curAreaId = curAid;
xa8_renderStates[1].x20_areaPoint = GetAreaPointOfInterest(mgr, xa0_curAreaId);
xa8_renderStates[1].x44_viewportEase = SAutoMapperRenderState::Ease::None;
xa8_renderStates[1].x48_camEase = SAutoMapperRenderState::Ease::None;
xa8_renderStates[1].x4c_pointEase = SAutoMapperRenderState::Ease::InOut;
xa8_renderStates[1].x50_depth1Ease = SAutoMapperRenderState::Ease::Linear;
xa8_renderStates[1].x54_depth2Ease = SAutoMapperRenderState::Ease::Linear;
xa8_renderStates[1].x58_alphaEase = SAutoMapperRenderState::Ease::None;
xa8_renderStates[1].x2c_drawDepth1 = GetMapAreaMiniMapDrawDepth();
xa8_renderStates[1].x30_drawDepth2 = GetMapAreaMiniMapDrawDepth();
xa8_renderStates[2].x2c_drawDepth1 = GetMapAreaMiniMapDrawDepth() - 1.f;
xa8_renderStates[2].x30_drawDepth2 = GetMapAreaMiniMapDrawDepth() - 1.f;
ResetInterpolationTimer(g_tweakAutoMapper->GetHintPanTime());
}
xa8_renderStates[1].x34_alphaSurfaceVisited = GetMapAreaMiniMapDrawAlphaSurfaceVisited(mgr);
xa8_renderStates[1].x38_alphaOutlineVisited = GetMapAreaMiniMapDrawAlphaOutlineVisited(mgr);
xa8_renderStates[1].x3c_alphaSurfaceUnvisited = GetMapAreaMiniMapDrawAlphaSurfaceUnvisited(mgr);
xa8_renderStates[1].x40_alphaOutlineUnvisited = GetMapAreaMiniMapDrawAlphaOutlineUnvisited(mgr);
}
else
{
if (x1c0_nextState == EAutoMapperState::MiniMap)
{
float desiredDist = GetDesiredMiniMapCameraDistance(mgr);
if (std::fabs(xa8_renderStates[1].x18_camDist - desiredDist) < 3.f)
xa8_renderStates[0].x18_camDist = desiredDist;
else if (xa8_renderStates[1].x18_camDist < desiredDist)
xa8_renderStates[1].x18_camDist += 3.f;
else
xa8_renderStates[1].x18_camDist -= 3.f;
}
else if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap && x24_world)
{
x24_world->IGetMapWorld()->RecalculateWorldSphere(
*g_GameState->StateForWorld(x24_world->IGetWorldAssetId()).MapWorldInfo(), *x24_world);
}
}
if (IsRenderStateInterpolating())
{
x1c8_interpTime = std::min(x1c8_interpTime + dt, x1c4_interpDur);
SAutoMapperRenderState::InterpolateWithClamp(xa8_renderStates[2], xa8_renderStates[0], xa8_renderStates[1],
x1c8_interpTime / x1c4_interpDur);
if (x1c8_interpTime == x1c4_interpDur && x328_ == 2)
SetupMiniMapWorld(mgr);
}
else if (IsInMapperStateTransition())
{
CompleteMapperStateTransition(mgr);
}
if (IsInMapperState(EAutoMapperState::MapScreenUniverse))
{
if (IWorld* wld = x14_dummyWorlds[x9c_worldIdx].get())
{
/* TODO: Finish */
}
}
else
{
}
}
@ -888,10 +1405,10 @@ void CAutoMapper::SetupHintNavigation()
}
else
{
x1e0_hintSteps.push_back({SAutoMapperHintStep::PulseCurrentArea{}});
x1e0_hintSteps.push_back({SAutoMapperHintStep::ZoomOut{}});
}
x1e0_hintSteps.push_back({SAutoMapperHintStep::PanToArea{}, loc.x8_areaId});
x1e0_hintSteps.push_back({SAutoMapperHintStep::PulseTargetArea{}});
x1e0_hintSteps.push_back({SAutoMapperHintStep::ZoomIn{}});
x1e0_hintSteps.push_back({SAutoMapperHintStep::ShowBeacon{}, 1.f});
x1f8_hintLocations.push_back({0, 0.f, loc.x0_mlvlId, loc.x8_areaId});
}

View File

@ -94,16 +94,16 @@ public:
SwitchToUniverse,
SwitchToWorld,
ShowBeacon,
PulseTargetArea,
PulseCurrentArea
ZoomIn,
ZoomOut
};
struct PanToArea {};
struct PanToWorld {};
struct SwitchToUniverse {};
struct SwitchToWorld {};
struct ShowBeacon {};
struct PulseTargetArea {};
struct PulseCurrentArea {};
struct ZoomIn {};
struct ZoomOut {};
Type x0_type;
union
@ -112,15 +112,15 @@ public:
TAreaId x4_areaId;
float x4_float;
};
bool x8_ = false;
bool x8_processing = false;
SAutoMapperHintStep(PanToArea, TAreaId areaId) : x0_type(Type::PanToArea), x4_areaId(areaId) {}
SAutoMapperHintStep(PanToWorld, ResId worldId) : x0_type(Type::PanToWorld), x4_worldId(worldId) {}
SAutoMapperHintStep(SwitchToUniverse) : x0_type(Type::SwitchToUniverse), x4_worldId(0) {}
SAutoMapperHintStep(SwitchToWorld, ResId worldId) : x0_type(Type::SwitchToWorld), x4_worldId(worldId) {}
SAutoMapperHintStep(ShowBeacon, float val) : x0_type(Type::ShowBeacon), x4_float(val) {}
SAutoMapperHintStep(PulseTargetArea) : x0_type(Type::PulseTargetArea), x4_worldId(0) {}
SAutoMapperHintStep(PulseCurrentArea) : x0_type(Type::PulseCurrentArea), x4_worldId(0) {}
SAutoMapperHintStep(ZoomIn) : x0_type(Type::ZoomIn), x4_worldId(0) {}
SAutoMapperHintStep(ZoomOut) : x0_type(Type::ZoomOut), x4_worldId(0) {}
};
struct SAutoMapperHintLocation
@ -168,23 +168,24 @@ private:
TLockedToken<CMapUniverse> x8_mapu;
std::vector<std::unique_ptr<IWorld>> x14_dummyWorlds;
const CWorld* x24_world;
TLockedToken<CModel> x28_frmeMapScreen; // Used to be ptr
u32 x2c_ = 0;
TLockedToken<CGuiFrame> x28_frmeMapScreen; // Used to be ptr
bool m_frmeInitialized = false;
TLockedToken<CModel> x30_miniMapSamus;
TLockedToken<CTexture> x3c_hintBeacon;
rstl::reserved_vector<TLockedToken<CTexture>, 5> x48_mapIcons;
ResId x74_ = -1;
ResId x74_areaHintDescId = -1;
TLockedToken<CStringTable> x78_areaHintDesc;
u32 x84_ = 0;
ResId x88_ = -1;
u32 x98_ = 0;
u32 x9c_worldIdx = 0;
TAreaId xa0_curAreaId;
TAreaId xa4_otherAreaId;
SAutoMapperRenderState xa8_renderStates[3]; // xa8, x104, x160; current, prev, next
SAutoMapperRenderState xa8_renderStates[3]; // xa8, x104, x160; current, next, prev
EAutoMapperState x1bc_state = EAutoMapperState::MiniMap;
EAutoMapperState x1c0_nextState = EAutoMapperState::MiniMap;
float x1c4_ = 0.f;
float x1c8_ = 0.f;
float x1c4_interpDur = 0.f;
float x1c8_interpTime = 0.f;
CSfxHandle x1cc_panningSfx;
CSfxHandle x1d0_rotatingSfx;
CSfxHandle x1d4_zoomingSfx;
@ -199,20 +200,20 @@ private:
rstl::reserved_vector<TLockedToken<CTexture>, 2> x2d0_abutton;
u32 x2e4_lStickPos = 0;
u32 x2e8_rStickPos = 0;
u32 x2ec_ = 0;
u32 x2f0_ = 0;
u32 x2f4_ = 0;
u32 x2f8_ = 0;
u32 x2fc_ = 0;
u32 x300_ = 0;
u32 x304_ = 0;
u32 x308_ = 0;
u32 x30c_ = 0;
u32 x310_ = 0;
u32 x314_ = 0;
float x318_ = 0.f;
float x31c_ = 0.f;
float x320_ = 0.f;
u32 x2ec_lTriggerPos = 0;
u32 x2f0_rTriggerPos = 0;
u32 x2f4_aButtonPos = 0;
CGuiTextPane* x2f8_textpane_areaname = nullptr;
CGuiTextPane* x2fc_textpane_hint = nullptr;
CGuiTextPane* x300_textpane_instructions = nullptr;
CGuiTextPane* x304_textpane_instructions1 = nullptr;
CGuiTextPane* x308_textpane_instructions2 = nullptr;
CGuiWidget* x30c_basewidget_leftPane = nullptr;
CGuiWidget* x310_basewidget_yButtonPane = nullptr;
CGuiWidget* x314_basewidget_bottomPane = nullptr;
float x318_leftPanePos = 0.f;
float x31c_yButtonPanePos = 0.f;
float x320_bottomPanePos = 0.f;
EZoomState x324_zoomState = EZoomState::None;
u32 x328_ = 0;
bool x32c_loadingDummyWorld = false;
@ -228,6 +229,8 @@ private:
}
bool NotHintNavigating() const;
bool CanLeaveMapScreenInternal(const CStateManager& mgr) const;
void LeaveMapScreen(const CStateManager& mgr);
void SetupMiniMapWorld(const CStateManager& mgr);
bool HasCurrentMapUniverseWorld() const;
bool CheckDummyWorldLoad(const CStateManager& mgr);
void UpdateHintNavigation(float dt, const CStateManager& mgr);
@ -239,7 +242,7 @@ private:
static float GetMapAreaMiniMapDrawAlphaOutlineVisited(const CStateManager&);
static float GetMapAreaMiniMapDrawAlphaSurfaceUnvisited(const CStateManager&);
static float GetMapAreaMiniMapDrawAlphaOutlineUnvisited(const CStateManager&);
static void GetDesiredMiniMapCameraDistance(const CStateManager&);
float GetDesiredMiniMapCameraDistance(const CStateManager&) const;
static float GetBaseMapScreenCameraMoveSpeed();
float GetClampedMapScreenCameraDistance(float);
float GetFinalMapScreenCameraMoveSpeed() const;
@ -267,12 +270,13 @@ public:
void UnmuteAllLoopedSounds();
void ProcessControllerInput(const CFinalInput&, CStateManager&);
bool IsInPlayerControlState() const;
void Update(float dt, const CStateManager& mgr);
void Draw(const CStateManager&, const zeus::CTransform&, float) const;
bool IsInOrTransitioningToMapScreenState() const;
float GetTimeIntoInterpolation() const;
bool IsFullyInMapScreenState() const;
void BeginMapperStateTransition(EAutoMapperState, const CStateManager&);
void CompleteMapperStateTransition();
void CompleteMapperStateTransition(const CStateManager&);
void ResetInterpolationTimer(float);
SAutoMapperRenderState BuildMiniMapWorldRenderState(const CStateManager&, const zeus::CQuaternion&, TAreaId) const;
SAutoMapperRenderState BuildMapScreenWorldRenderState(const CStateManager&, const zeus::CQuaternion&, TAreaId, bool) const;
@ -283,7 +287,7 @@ public:
zeus::CVector3f GetAreaPointOfInterest(const CStateManager&, TAreaId) const;
TAreaId FindClosestVisibleArea(const zeus::CVector3f&, const zeus::CUnitVector3f&, const CStateManager&,
const IWorld&, const CMapWorldInfo&) const;
std::pair<TAreaId, int>
std::pair<int, int>
FindClosestVisibleWorld(const zeus::CVector3f&, const zeus::CUnitVector3f&, const CStateManager&) const;
bool IsInMapperState(EAutoMapperState state) const
@ -296,7 +300,7 @@ public:
}
bool IsRenderStateInterpolating() const
{
return x1c8_ < x1c4_;
return x1c8_interpTime < x1c4_interpDur;
}
void UpdateOptionsMenu(const CTweakValue::Audio&);
void UpdateAudioMusicMenu();

View File

@ -47,6 +47,23 @@ void CMapArea::PostConstruct()
(reinterpret_cast<CMapAreaSurface*>(x40_surfaceStart + j))->PostConstruct(x44_buf.get());
}
bool CMapArea::GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const
{
switch (xc_)
{
case 0:
return true;
case 1:
return worldVis || areaVis;
case 2:
return areaVis;
case 3:
return false;
default:
return true;
}
}
static const zeus::CVector3f MinesPostTransforms[3] =
{
{0.f, 0.f, 200.f},
@ -99,7 +116,7 @@ static const u8 MinesPostTransformIndices[] =
2, // 41 Fungal Hall A
};
zeus::CTransform CMapArea::GetAreaPostTransform(const CWorld& world, TAreaId aid) const
zeus::CTransform CMapArea::GetAreaPostTransform(const IWorld& world, TAreaId aid) const
{
if (world.IGetWorldAssetId() == g_ResFactory->TranslateOriginalToNew(0xB1AC4D65)) // Phazon Mines
{

View File

@ -8,7 +8,7 @@
namespace urde
{
class CWorld;
class IWorld;
class CMapArea
{
public:
@ -40,13 +40,13 @@ public:
void PostConstruct();
bool GetIsVisibleToAutoMapper(bool, bool) const;
zeus::CVector3f GetAreaCenterPoint() const { return x10_box.center(); }
zeus::CAABox GetBoundingBox() const;
const zeus::CAABox& GetBoundingBox() const { return x10_box; }
const zeus::CVector3f& GetVertices() const;
void GetMappableObject(s32) const;
void GetSurface(s32) const;
u32 GetNumMappableObjects() const;
u32 GetNumSurfaces() const;
zeus::CTransform GetAreaPostTransform(const CWorld& world, TAreaId aid) const;
zeus::CTransform GetAreaPostTransform(const IWorld& world, TAreaId aid) const;
};
CFactoryFnReturn FMapAreaFactory(const SObjectTag& objTag, CInputStream& in, const CVParamTransfer&,

View File

@ -56,11 +56,11 @@ public:
const std::string& GetWorldLabel() const { return x0_label; }
const zeus::CTransform& GetWorldTransform() const { return x14_transform; }
const zeus::CTransform& GetMapAreaData(s32 idx) const { return x44_hexagonXfs[idx]; }
u32 GetNumMapAreaDatas() const { return x44_hexagonXfs.size(); }
zeus::CColor GetOutlineColorUnselected() const;
zeus::CColor GetOutlineColorSelected() const;
zeus::CColor GetSurfaceColorUnselected() const;
zeus::CColor GetSurfaceColorSelected() const;
u32 GetNumMapAreaDatas() const;
};
private:
@ -72,6 +72,13 @@ private:
public:
CMapUniverse(CInputStream&, u32);
const CMapWorldData& GetMapWorldData(s32 idx) const { return x10_worldDatas[idx]; }
const CMapWorldData& GetMapWorldDataByWorldId(ResId id) const
{
for (const CMapWorldData& data : x10_worldDatas)
if (data.GetWorldAssetId() == id)
return data;
return x10_worldDatas.front();
}
u32 GetNumMapWorldDatas() const { return x10_worldDatas.size(); }
float GetMapUniverseRadius() const { return x2c_universeRadius; }
const zeus::CVector3f& GetMapUniverseCenterPoint() const { return x20_universeCenter; }

View File

@ -1,4 +1,5 @@
#include "CMapWorld.hpp"
#include "CMapWorldInfo.hpp"
namespace urde
{
@ -38,9 +39,21 @@ s32 CMapWorld::GetCurrentMapAreaDepth(const IWorld& wld, TAreaId aid) const
return info.back().GetDepth();
}
void CMapWorld::GetVisibleAreas(const IWorld&, const CMapWorldInfo&) const
std::vector<TAreaId> CMapWorld::GetVisibleAreas(const IWorld& wld, const CMapWorldInfo& mwInfo) const
{
std::vector<TAreaId> ret;
ret.reserve(x0_areas.size());
for (int i=0 ; i<x0_areas.size() ; ++i)
{
if (!IsMapAreaValid(wld, i, true))
continue;
const CMapArea* area = GetMapArea(i);
bool areaVis = mwInfo.IsAreaVisible(i);
bool worldVis = mwInfo.IsWorldVisible(i);
if (area->GetIsVisibleToAutoMapper(worldVis, areaVis))
ret.push_back(i);
}
return ret;
}
void CMapWorld::Draw(const CMapWorld::CMapWorldDrawParms&, int, int, float, float, bool) const

View File

@ -99,7 +99,7 @@ public:
bool IsMapAreasStreaming() const;
void MoveMapAreaToList(CMapAreaData*, EMapAreaList);
s32 GetCurrentMapAreaDepth(const IWorld&, TAreaId) const;
void GetVisibleAreas(const IWorld&, const CMapWorldInfo&) const;
std::vector<TAreaId> GetVisibleAreas(const IWorld&, const CMapWorldInfo&) const;
void Draw(const CMapWorldDrawParms&, int, int, float, float, bool) const;
void DoBFS(const IWorld&, TAreaId, int, float, float, bool, std::vector<CMapAreaBFSInfo>&) const;
bool IsMapAreaValid(const IWorld&, int, bool) const;

View File

@ -36,7 +36,7 @@ void CMapWorldInfo::PutTo(CBitStreamWriter& writer, const CSaveWorld& savw, ResI
for (int i=0 ; i<worldMem.GetAreaCount() ; ++i)
{
if (i < x0_visitedAreasAllocated)
writer.WriteEncoded(const_cast<CMapWorldInfo&>(*this).IsAreaVisted(i), 1);
writer.WriteEncoded(IsAreaVisted(i), 1);
else
writer.WriteEncoded(0, 1);
}
@ -44,7 +44,7 @@ void CMapWorldInfo::PutTo(CBitStreamWriter& writer, const CSaveWorld& savw, ResI
for (int i=0 ; i<worldMem.GetAreaCount() ; ++i)
{
if (i < x14_mappedAreasAllocated)
writer.WriteEncoded(const_cast<CMapWorldInfo&>(*this).IsMapped(i), 1);
writer.WriteEncoded(IsMapped(i), 1);
else
writer.WriteEncoded(0, 1);
}
@ -65,12 +65,12 @@ bool CMapWorldInfo::IsDoorVisited(TEditorId eid) const
return x28_visitedDoors.find(eid) != x28_visitedDoors.end();
}
bool CMapWorldInfo::IsAreaVisted(TAreaId aid)
bool CMapWorldInfo::IsAreaVisted(TAreaId aid) const
{
if (aid + 1 > x0_visitedAreasAllocated)
{
x4_visitedAreas.resize((aid + 32) / 32);
x0_visitedAreasAllocated = aid + 1;
const_cast<CMapWorldInfo&>(*this).x4_visitedAreas.resize((aid + 32) / 32);
const_cast<CMapWorldInfo&>(*this).x0_visitedAreasAllocated = aid + 1;
}
return (x4_visitedAreas[aid / 32] >> (aid % 32)) & 0x1;
}
@ -88,12 +88,12 @@ void CMapWorldInfo::SetAreaVisited(TAreaId aid, bool visited)
x4_visitedAreas[aid / 32] &= ~(1 << (aid % 32));
}
bool CMapWorldInfo::IsMapped(TAreaId aid)
bool CMapWorldInfo::IsMapped(TAreaId aid) const
{
if (aid + 1 > x14_mappedAreasAllocated)
{
x18_mappedAreas.resize((aid + 32) / 32);
x14_mappedAreasAllocated = aid + 1;
const_cast<CMapWorldInfo&>(*this).x18_mappedAreas.resize((aid + 32) / 32);
const_cast<CMapWorldInfo&>(*this).x14_mappedAreasAllocated = aid + 1;
}
return (x18_mappedAreas[aid / 32] >> (aid % 32)) & 0x1;
}
@ -111,9 +111,27 @@ void CMapWorldInfo::SetIsMapped(TAreaId aid, bool mapped)
x18_mappedAreas[aid / 32] &= ~(1 << (aid % 32));
}
bool CMapWorldInfo::IsWorldVisible(TAreaId aid)
bool CMapWorldInfo::IsWorldVisible(TAreaId aid) const
{
return x38_worldVisited || IsMapped(aid);
}
bool CMapWorldInfo::IsAreaVisible(TAreaId aid) const
{
if (IsAreaVisted(aid) || IsMapped(aid))
return true;
return false;
}
bool CMapWorldInfo::IsAnythingSet() const
{
for (int i=0 ; i<x0_visitedAreasAllocated ; ++i)
if (x4_visitedAreas[i / 32] & (1 << (i % 32)))
return true;
for (int i=0 ; i<x14_mappedAreasAllocated ; ++i)
if (x18_mappedAreas[i / 32] & (1 << (i % 32)))
return true;
return x38_worldVisited;
}
}

View File

@ -19,13 +19,15 @@ public:
CMapWorldInfo()=default;
CMapWorldInfo(CBitStreamReader&, const CSaveWorld& saveWorld, ResId mlvlId);
void PutTo(CBitStreamWriter& writer, const CSaveWorld& savw, ResId mlvlId) const;
bool IsMapped(TAreaId);
bool IsMapped(TAreaId) const;
void SetIsMapped(TAreaId, bool);
void SetDoorVisited(TEditorId eid, bool val);
bool IsDoorVisited(TEditorId eid) const;
bool IsAreaVisted(TAreaId);
bool IsAreaVisted(TAreaId) const;
void SetAreaVisited(TAreaId, bool);
bool IsWorldVisible(TAreaId);
bool IsWorldVisible(TAreaId) const;
bool IsAreaVisible(TAreaId) const;
bool IsAnythingSet() const;
};
}

View File

@ -75,7 +75,7 @@ CPersistentOptions::CPersistentOptions(CBitStreamReader& stream)
xd0_27_fusionBeat = stream.ReadEncoded(1);
xd0_28_fusionSuitActive = stream.ReadEncoded(1);
xd0_29_allItemsCollected = stream.ReadEncoded(1);
xbc_ = stream.ReadEncoded(2);
xbc_autoMapperKeyState = stream.ReadEncoded(2);
auto& memWorlds = g_MemoryCardSys->GetMemoryWorlds();
size_t cinematicCount = 0;
@ -121,7 +121,7 @@ void CPersistentOptions::PutTo(CBitStreamWriter& w) const
w.WriteEncoded(xd0_27_fusionBeat, 1);
w.WriteEncoded(xd0_28_fusionSuitActive, 1);
w.WriteEncoded(xd0_29_allItemsCollected, 1);
w.WriteEncoded(xbc_, 2);
w.WriteEncoded(xbc_autoMapperKeyState, 2);
auto& memWorlds = g_MemoryCardSys->GetMemoryWorlds();
for (const auto& world : memWorlds)

View File

@ -58,7 +58,7 @@ class CPersistentOptions
u8 x0_[98] = {};
bool x68_[64] = {};
std::vector<std::pair<ResId, TEditorId>> xac_cinematicStates; /* (MLVL, Cinematic) */
u32 xbc_ = 0;
u32 xbc_autoMapperKeyState = 0;
u32 xc0_ = 0;
u32 xc4_freezeBreakCount = 0;
u32 xc8_ = 0;
@ -84,6 +84,8 @@ public:
bool GetCinematicState(ResId mlvlId, TEditorId cineId) const;
void SetCinematicState(ResId mlvlId, TEditorId cineId, bool state);
u32 GetAutoMapperKeyState() const { return xbc_autoMapperKeyState; }
void SetAutoMapperKeyState(u32 s) { xbc_autoMapperKeyState = s; }
bool GetPlayerLinkedFusion() const { return xd0_24_fusionLinked; }
void SetPlayerLinkedFusion(bool v) { xd0_24_fusionLinked = v; }
bool GetPlayerBeatNormalMode() const { return xd0_25_normalModeBeat; }

View File

@ -183,6 +183,7 @@ public:
s32 GetNumAreas() const { return x18_areas.size(); }
const IGameArea* IGetAreaAlways(TAreaId id) const;
TAreaId IGetCurrentAreaId() const;
TAreaId GetCurrentAreaId() const { return x68_curAreaId; }
TAreaId IGetAreaId(ResId id) const;
bool ICheckWorldComplete();
std::string IGetDefaultAudioTrack() const;