#include "CWorldTransManager.hpp" #include "GuiSys/CGuiTextSupport.hpp" #include "CSimplePool.hpp" #include "GameGlobalObjects.hpp" #include "CGameState.hpp" #include "Character/CAnimPlaybackParms.hpp" #include "Character/CAssetFactory.hpp" #include "Character/CCharacterFactory.hpp" #include "Character/IAnimReader.hpp" #include "Character/CSkinRules.hpp" #include "Graphics/CModel.hpp" namespace urde { int CWorldTransManager::GetSuitCharSet() { CPlayerState& state = *g_GameState->GetPlayerState(); if (state.GetFusion()) { switch (state.x20_currentSuit) { case CPlayerState::EPlayerSuit::Power: return 4; case CPlayerState::EPlayerSuit::Gravity: return 6; case CPlayerState::EPlayerSuit::Varia: return 7; case CPlayerState::EPlayerSuit::Phazon: return 8; default: break; } } return int(state.x20_currentSuit); } CWorldTransManager::SModelDatas::SModelDatas(const CAnimRes& samusRes) : x0_samusRes(samusRes) { x1a0_lights.reserve(8); } void CWorldTransManager::UpdateLights(float dt) { if (!x4_modelData) return; x4_modelData->x1a0_lights.clear(); zeus::CVector3f lightPos(0.f, 10.f, 0.f); CLight spot = CLight::BuildSpot(lightPos, zeus::kBackVec, zeus::CColor::skWhite, 90.f); spot.SetAttenuation(1.f, 0.f, 0.f); CLight s1 = spot; s1.SetPosition(lightPos + zeus::CVector3f{0.f, 0.f, 2.f * x18_bgOffset - x1c_bgHeight}); float z = 1.f; float delta = x1c_bgHeight - x18_bgOffset; if (!x44_26_goingUp && delta < 2.f) z = delta * 0.5f; else if (x44_26_goingUp && x18_bgOffset < 2.f) z = x18_bgOffset * 0.5f; if (z < 1.f) { CLight s2 = spot; float pos = x44_26_goingUp ? x1c_bgHeight : -x1c_bgHeight; s2.SetPosition(lightPos + zeus::CVector3f{0.f, 0.f, pos}); s2.SetColor(zeus::CColor::lerp(zeus::CColor::skBlack, zeus::CColor::skWhite, 1.f - z)); x4_modelData->x1a0_lights.push_back(std::move(s2)); s1.SetColor(zeus::CColor::lerp(zeus::CColor::skBlack, zeus::CColor::skWhite, z)); } x4_modelData->x1a0_lights.push_back(std::move(s1)); } void CWorldTransManager::UpdateDisabled(float) { if (x0_curTime <= 2.f) return; x44_24_dissolveComplete = true; } void CWorldTransManager::UpdateEnabled(float dt) { if (x4_modelData && !x4_modelData->x1c_samusModelData.IsNull()) { if (x44_25_stopSoon && !x4_modelData->x1dc_dissolveStarted && x0_curTime > 2.f) { x4_modelData->x1dc_dissolveStarted = true; x4_modelData->x1d0_dissolveStartTime = x0_curTime; x4_modelData->x1d4_relativeDissolveStartTime = 4.f + x0_curTime - 2.f; x4_modelData->x1d8_relativeDissolveEndTime = 5.f + x0_curTime - 2.f; } if (x0_curTime > x4_modelData->x1d8_relativeDissolveEndTime && x4_modelData->x1dc_dissolveStarted) x44_24_dissolveComplete = true; x4_modelData->x1c_samusModelData.AdvanceAnimationIgnoreParticles(dt, x20_random, true); x4_modelData->x170_gunXf = x4_modelData->x1c_samusModelData.GetScaledLocatorTransform("GUN_LCTR"); x4_modelData->x1c4_randTimeout -= dt; if (x4_modelData->x1c4_randTimeout <= 0.f) { x4_modelData->x1c4_randTimeout = x20_random.Range(0.016666668f, 0.1f); zeus::CVector2f randVec(x20_random.Range(-0.025f, 0.025f), x20_random.Range(-0.075f, 0.075f)); x4_modelData->x1bc_shakeDelta = (randVec - x4_modelData->x1b4_shakeResult) / x4_modelData->x1c4_randTimeout; x4_modelData->x1cc_blurDelta = (x20_random.Range(-2.f, 4.f) - x4_modelData->x1c8_blurResult) / x4_modelData->x1c4_randTimeout; } x4_modelData->x1b4_shakeResult += x4_modelData->x1bc_shakeDelta * dt; x4_modelData->x1c8_blurResult += dt * x4_modelData->x1cc_blurDelta; } float delta = dt * 50.f; if (x44_26_goingUp) delta = -delta; x18_bgOffset += delta; if (x18_bgOffset > x1c_bgHeight) x18_bgOffset -= x1c_bgHeight; if (x18_bgOffset < 0.f) x18_bgOffset += x1c_bgHeight; UpdateLights(dt); } void CWorldTransManager::UpdateText(float) { } void CWorldTransManager::Update(float dt) { x0_curTime += dt; switch (x30_type) { case ETransType::Disabled: UpdateDisabled(dt); break; case ETransType::Enabled: UpdateEnabled(dt); break; case ETransType::Text: UpdateText(dt); break; } } void CWorldTransManager::DrawEnabled() { } void CWorldTransManager::DrawDisabled() { m_fadeToBlack.draw(zeus::CColor{0.f, 0.f, 0.f, 0.01f}); } void CWorldTransManager::DrawText() { } void CWorldTransManager::Draw() { if (x30_type == ETransType::Disabled) DrawDisabled(); else if (x30_type == ETransType::Enabled) DrawEnabled(); else if (x30_type == ETransType::Text) DrawText(); } void CWorldTransManager::TouchModels() { if (!x4_modelData) return; if (x4_modelData->x14c_beamModel.IsLoaded() && x4_modelData->x14c_beamModel.GetObj()) { x4_modelData->x68_beamModelData = CStaticRes(x4_modelData->x14c_beamModel.GetObjectTag()->id, x4_modelData->x0_samusRes.GetScale()); } if (x4_modelData->x158_suitModel.IsLoaded() && x4_modelData->x158_suitModel.GetObj() && x4_modelData->x164_suitSkin.IsLoaded() && x4_modelData->x164_suitSkin.GetObj()) { CAnimRes animRes(x4_modelData->x0_samusRes.GetId(), GetSuitCharSet(), x4_modelData->x0_samusRes.GetScale(), x4_modelData->x0_samusRes.GetDefaultAnim(), true); x4_modelData->x1c_samusModelData = animRes; CAnimPlaybackParms aData(animRes.GetDefaultAnim(), -1, 1.f, true); x4_modelData->x1c_samusModelData.AnimationData()->SetAnimation(aData, false); } if (x4_modelData->x1c_samusModelData.IsNull()) x4_modelData->x1c_samusModelData.Touch(CModelData::EWhichModel::Normal, 0); if (x4_modelData->xb4_platformModelData.IsNull()) x4_modelData->xb4_platformModelData.Touch(CModelData::EWhichModel::Normal, 0); if (x4_modelData->x100_bgModelData.IsNull()) x4_modelData->x100_bgModelData.Touch(CModelData::EWhichModel::Normal, 0); if (x4_modelData->x68_beamModelData.IsNull()) x4_modelData->x68_beamModelData.Touch(CModelData::EWhichModel::Normal, 0); } void CWorldTransManager::EnableTransition(const CAnimRes& samusRes, ResId platRes, const zeus::CVector3f& platScale, ResId bgRes, const zeus::CVector3f& bgScale, bool goingUp) { x44_25_stopSoon = false; x44_26_goingUp = goingUp; x30_type = ETransType::Enabled; x4_modelData.reset(new SModelDatas(samusRes)); x8_textData.reset(); x20_random.SetSeed(99); x4_modelData->x1c_samusModelData = CModelData(samusRes); CAnimPlaybackParms aData(samusRes.GetDefaultAnim(), -1, 1.f, true); x4_modelData->x1c_samusModelData.AnimationData()->SetAnimation(aData, false); const std::string& modelName = g_tweakPlayerRes->GetBeamCineModel( DataSpec::ITweakPlayerRes::EBeamId(g_GameState->GetPlayerState()->GetCurrentBeam())); x4_modelData->x14c_beamModel = g_SimplePool->GetObj(modelName.c_str()); TToken fac = g_CharFactoryBuilder->GetFactory(samusRes); const CCharacterInfo& info = fac.GetObj()->GetCharInfo(GetSuitCharSet()); x4_modelData->x158_suitModel = g_SimplePool->GetObj(SObjectTag{FOURCC('CMDL'), info.GetModelId()}); x4_modelData->x164_suitSkin = g_SimplePool->GetObj(SObjectTag{FOURCC('CSKR'), info.GetSkinRulesId()}); if (platRes != -1) { x4_modelData->xb4_platformModelData = CStaticRes(platRes, platScale); x4_modelData->xb4_platformModelData.Touch(CModelData::EWhichModel::Normal, 0); } if (bgRes != -1) { x4_modelData->x100_bgModelData = CStaticRes(bgRes, bgScale); x4_modelData->x100_bgModelData.Touch(CModelData::EWhichModel::Normal, 0); zeus::CAABox bounds = x4_modelData->x100_bgModelData.GetBounds(); x1c_bgHeight = (bounds.max.z - bounds.min.z) * bgScale.z; } else x1c_bgHeight = 0.f; StartTransition(); TouchModels(); } void CWorldTransManager::EnableTransition(ResId fontId, ResId stringId, bool b1, bool b2, float chFadeTime, float chFadeRate, float f3) { x40_ = b1; x38_ = f3; x44_25_stopSoon = false; x30_type = ETransType::Text; x4_modelData.reset(); x44_27_ = b2; CGuiTextProperties props(false, true, EJustification::Center, EVerticalJustification::Center, ETextDirection::Horizontal); x8_textData.reset(new CGuiTextSupport(fontId, props, zeus::CColor::skWhite, zeus::CColor::skBlack, zeus::CColor::skWhite, 640, 448, g_SimplePool)); x8_textData->SetTypeWriteEffectOptions(true, chFadeTime, chFadeRate); xc_strTable = g_SimplePool->GetObj(SObjectTag{FOURCC('STRG'), stringId}); x8_textData->SetText(L""); StartTransition(); } void CWorldTransManager::DisableTransition() { x4_modelData.reset(); x8_textData.reset(); x44_26_goingUp = false; } void CWorldTransManager::StartTransition() { x0_curTime = 0.f; x18_bgOffset = 0.f; x44_24_dissolveComplete = false; x44_28_ = true; } void CWorldTransManager::EndTransition() { DisableTransition(); } }