diff --git a/DataSpec/DNAMP1/CMDLMaterials.cpp b/DataSpec/DNAMP1/CMDLMaterials.cpp index 15a96ad92..7d03df265 100644 --- a/DataSpec/DNAMP1/CMDLMaterials.cpp +++ b/DataSpec/DNAMP1/CMDLMaterials.cpp @@ -867,6 +867,18 @@ void _ConstructMaterial(Stream& out, } } + /* Indirect texture node */ + if (material.flags.samusReflectionIndirectTexture()) + { + Material::AddTexture(out, GX::TexGenSrc::TG_POS, -1, material.indTexSlot[0]); + out << "# Indirect Texture\n" + "ind_out = new_nodetree.nodes.new('ShaderNodeOutput')\n" + "gridder.place_node(ind_out, 3)\n" + "ind_out.name = 'IndirectOutput'\n" + "ind_out.label = 'Indirect'\n" + "new_nodetree.links.new(tex_node.outputs['Color'], ind_out.inputs['Color'])\n"; + } + /* TEV-emulation combiner-node index context */ unsigned c_combiner_idx = 0; unsigned a_combiner_idx = 0; diff --git a/Runtime/CGameOptions.cpp b/Runtime/CGameOptions.cpp index a1d92a77a..97e440f52 100644 --- a/Runtime/CGameOptions.cpp +++ b/Runtime/CGameOptions.cpp @@ -642,7 +642,14 @@ void CHintOptions::ActivateContinueDelayHintTimer(const char* name) void CHintOptions::DismissDisplayedHint() { - + if (x10_nextHintIdx == -1) + return; + const CGameHintInfo::CGameHint& hint = g_MemoryCardSys->GetHints()[x10_nextHintIdx]; + SHintState& hintState = x0_hintStates[x10_nextHintIdx]; + if (hintState.x4_time >= hint.GetTextTime()) + return; + hintState.x4_time = hint.GetNormalTime(); + hintState.x8_dismissed = true; } u32 CHintOptions::GetNextHintIdx() const diff --git a/Runtime/CObjectList.cpp b/Runtime/CObjectList.cpp index 211301036..395389f97 100644 --- a/Runtime/CObjectList.cpp +++ b/Runtime/CObjectList.cpp @@ -83,6 +83,30 @@ CEntity* CObjectList::GetObjectById(TUniqueId uid) return ent.entity; } +const CEntity* CObjectList::GetValidObjectById(TUniqueId uid) const +{ + if (uid == kInvalidUniqueId) + return nullptr; + const SObjectListEntry& ent = x0_list[uid & 0x3ff]; + if (!ent.entity) + return nullptr; + if (ent.entity->GetUniqueId() != uid) + return nullptr; + return ent.entity; +} + +CEntity* CObjectList::GetValidObjectById(TUniqueId uid) +{ + if (uid == kInvalidUniqueId) + return nullptr; + SObjectListEntry& ent = x0_list[uid & 0x3ff]; + if (!ent.entity) + return nullptr; + if (ent.entity->GetUniqueId() != uid) + return nullptr; + return ent.entity; +} + bool CObjectList::IsQualified(const CEntity&) {return true;} } diff --git a/Runtime/CObjectList.hpp b/Runtime/CObjectList.hpp index 3a5747f7f..8678469bb 100644 --- a/Runtime/CObjectList.hpp +++ b/Runtime/CObjectList.hpp @@ -58,6 +58,8 @@ public: const CEntity* GetObjectById(TUniqueId uid) const; const CEntity* GetObjectByIndex(s32 index) const { return x0_list[index].entity; } CEntity* GetObjectById(TUniqueId uid); + const CEntity* GetValidObjectById(TUniqueId uid) const; + CEntity* GetValidObjectById(TUniqueId uid); TUniqueId GetFirstObjectIndex() const { return x2008_firstId; } TUniqueId GetNextObjectIndex(TUniqueId prev) const { return x0_list[prev & 0x3ff].next; } virtual bool IsQualified(const CEntity&); diff --git a/Runtime/CPlayerState.hpp b/Runtime/CPlayerState.hpp index a9e859cd8..23c116f6f 100644 --- a/Runtime/CPlayerState.hpp +++ b/Runtime/CPlayerState.hpp @@ -170,6 +170,7 @@ public: u32 GetLogScans() const { return x180_logScans; } u32 GetTotalLogScans() const { return x184_totalLogScans; } bool IsPlayerAlive() const { return x0_24_alive; } + void SetPlayerAlive(bool alive) { x0_24_alive = alive; } void InitializeScanTimes(); const rstl::reserved_vector, 846>& GetScanTimes() const { return x170_scanTimes; } CPlayerState(); diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 0e4bfbf06..dc0c102d9 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -37,6 +37,8 @@ #include "World/CScriptEffect.hpp" #include "MP1/CSamusHud.hpp" #include "Collision/CGameCollision.hpp" +#include "World/CScriptPlatform.hpp" +#include "World/CScriptRoomAcoustics.hpp" #include @@ -344,21 +346,64 @@ TAreaId CStateManager::GetVisAreaId() const return curArea; } -void CStateManager::GetWeaponIdCount(TUniqueId, EWeaponType) {} +s32 CStateManager::GetWeaponIdCount(TUniqueId uid, EWeaponType type) +{ + return x878_weaponManager->GetNumActive(uid, type); +} -void CStateManager::RemoveWeaponId(TUniqueId, EWeaponType) {} +void CStateManager::RemoveWeaponId(TUniqueId uid, EWeaponType type) +{ + x878_weaponManager->DecrCount(uid, type); +} -void CStateManager::AddWeaponId(TUniqueId, EWeaponType) {} +void CStateManager::AddWeaponId(TUniqueId uid, EWeaponType type) +{ + x878_weaponManager->IncrCount(uid, type); +} -void CStateManager::UpdateEscapeSequenceTimer(float) {} +void CStateManager::UpdateEscapeSequenceTimer(float dt) +{ + if (xf0c_escapeTimer <= 0.f) + return; + xf0c_escapeTimer = std::max(FLT_EPSILON, xf0c_escapeTimer - dt); + if (xf0c_escapeTimer <= FLT_EPSILON) + x8b8_playerState->SetPlayerAlive(false); -float CStateManager::GetEscapeSequenceTimer() const { return 0.f; } + if (!g_EscapeShakeCountdownInit) + { + g_EscapeShakeCountdown = 0.f; + g_EscapeShakeCountdownInit = true; + } -void CStateManager::ResetEscapeSequenceTimer(float) {} + g_EscapeShakeCountdown -= dt; + if (g_EscapeShakeCountdown < 0.f) + { + float factor = 1.f - xf0c_escapeTimer / xf10_escapeTotalTime; + float factor2 = factor * factor; + CCameraShakeData shakeData(1.f, factor2 * 0.2f * x900_activeRandom->Range(0.5f, 1.f)); + x870_cameraManager->AddCameraShaker(shakeData, true); + x88c_rumbleManager->Rumble(*this, ERumbleFxId::Seven, 0.75f, ERumblePriority::One); + g_EscapeShakeCountdown = -12.f * factor2 + 15.f; + } +} -void CStateManager::SetupParticleHook(const CActor& actor) const {} +float CStateManager::GetEscapeSequenceTimer() const { return xf0c_escapeTimer; } -void CStateManager::MurderScriptInstanceNames() {} +void CStateManager::ResetEscapeSequenceTimer(float time) +{ + xf0c_escapeTimer = time; + xf10_escapeTotalTime = time; +} + +void CStateManager::SetupParticleHook(const CActor& actor) const +{ + x884_actorModelParticles->SetupHook(actor.GetUniqueId()); +} + +void CStateManager::MurderScriptInstanceNames() +{ + xb40_uniqueInstanceNames.clear(); +} std::string CStateManager::HashInstanceName(CInputStream& in) { @@ -371,7 +416,27 @@ std::string CStateManager::HashInstanceName(CInputStream& in) #endif } -void CStateManager::SetActorAreaId(CActor& actor, TAreaId) {} +void CStateManager::SetActorAreaId(CActor& actor, TAreaId aid) +{ + TAreaId actorAid = actor.GetAreaIdAlways(); + if (actorAid == aid) + return; + + if (actorAid != kInvalidAreaId) + { + CGameArea* area = x850_world->GetArea(actorAid); + if (area->IsPostConstructed()) + area->GetAreaObjects().RemoveObject(actor.GetUniqueId()); + } + + if (aid == kInvalidAreaId) + return; + CGameArea* area = x850_world->GetArea(aid); + if (!area->IsPostConstructed() || area->GetAreaObjects().GetValidObjectById(actor.GetUniqueId())) + return; + + area->GetAreaObjects().AddObject(actor); +} void CStateManager::TouchSky() const { @@ -382,12 +447,8 @@ void CStateManager::TouchPlayerActor() { if (xf6c_playerActor == kInvalidUniqueId) return; - -#if 0 - TCastToPtr spa(ObjectById(xf6c_playerActor)); - if (spa) - spa->TouchModels(); -#endif + if (CEntity* ent = ObjectById(xf6c_playerActor)) + static_cast(ent)->TouchModels(); } void CStateManager::DrawSpaceWarp(const zeus::CVector3f& v, float strength) const @@ -400,9 +461,37 @@ void CStateManager::DrawSpaceWarp(const zeus::CVector3f& v, float strength) cons } } -void CStateManager::DrawReflection(const zeus::CVector3f&) {} +void CStateManager::DrawReflection(const zeus::CVector3f& reflectPoint) +{ + zeus::CAABox aabb = x84c_player->GetBoundingBox(); + zeus::CVector3f playerPos = aabb.center(); + zeus::CVector3f surfToPlayer = playerPos - reflectPoint; + surfToPlayer.z = 0.f; + zeus::CVector3f viewPos = playerPos - surfToPlayer.normalized() * 3.5f; + zeus::CTransform look = zeus::lookAt(viewPos, playerPos, {0.f, 0.f, -1.f}); -void CStateManager::CacheReflection() {} + zeus::CTransform backupView = CGraphics::g_ViewMatrix; + CGraphics::SetViewPointMatrix(look); + CGraphics::CProjectionState backupProj = CGraphics::GetProjectionState(); + CGameCamera* cam = x870_cameraManager->GetCurrentCamera(*this); + g_Renderer->SetPerspective(cam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height, + cam->GetNearClipDistance(), cam->GetFarClipDistance()); + + x84c_player->RenderReflectedPlayer(*this); + + CGraphics::SetViewPointMatrix(backupView); + CGraphics::SetProjectionState(backupProj); +} + +void CStateManager::ReflectionDrawer(void* ctx, const zeus::CVector3f& vec) +{ + reinterpret_cast(ctx)->DrawReflection(vec); +} + +void CStateManager::CacheReflection() +{ + g_Renderer->CacheReflection(ReflectionDrawer, this, true); +} bool CStateManager::CanCreateProjectile(TUniqueId, EWeaponType, int) const { return false; } @@ -472,7 +561,19 @@ zeus::CFrustum CStateManager::SetupViewForDraw(const SViewport& vp) const void CStateManager::ResetViewAfterDraw(const SViewport& backupViewport, const zeus::CTransform& backupViewMatrix) const { + g_Renderer->SetViewport(backupViewport.x0_left, backupViewport.x4_top, + backupViewport.x8_width, backupViewport.xc_height); + const CGameCamera* cam = x870_cameraManager->GetCurrentCamera(*this); + zeus::CFrustum frustum; + frustum.updatePlanes(backupViewMatrix, zeus::SProjPersp(zeus::degToRad(cam->GetFov()), + cam->GetAspectRatio(), + cam->GetNearClipDistance(), + cam->GetFarClipDistance())); + g_Renderer->SetClippingPlanes(frustum); + + g_Renderer->SetPerspective(cam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height, + cam->GetNearClipDistance(), cam->GetFarClipDistance()); } void CStateManager::DrawWorld() const @@ -1241,7 +1342,7 @@ void CStateManager::Update(float dt) CGameCollision::Move(*this, *x84c_player, dt, nullptr); UpdateSortedLists(); if (!_9f4_gt0) - CrossTouchActors(dt); + CrossTouchActors(); } else { @@ -1306,7 +1407,7 @@ void CStateManager::Update(float dt) g_GameState->CurrentWorldState().SetAreaId(x8cc_nextAreaId); x850_world->TravelToArea(x8cc_nextAreaId, *this, false); - BringOutYourDead(); + ClearGraveyard(); ++x8d8_updateFrameIdx; } @@ -1374,37 +1475,157 @@ void CStateManager::PreThinkEffects(float dt) void CStateManager::MovePlatforms(float dt) { - + for (CEntity* ent : GetPlatformAndDoorObjectList()) + { + if (!ent || !GetPlatformAndDoorObjectList().IsPlatform(*ent)) + continue; + CScriptPlatform& plat = static_cast(*ent); + if (!plat.GetActive() || plat.GetMass() == 0.f) + continue; + CGameCollision::Move(*this, plat, dt, nullptr); + } } void CStateManager::MoveDoors(float dt) { - + for (CEntity* ent : GetPhysicsActorObjectList()) + { + if (!ent || !ent->GetActive()) + continue; + CPhysicsActor& physActor = static_cast(*ent); + if (physActor.GetMass() == 0.f) + continue; + if (TCastToPtr ai = physActor) + { + bool doThink = !xf94_29_; + if (doThink && ai->GetAreaIdAlways() != kInvalidAreaId) + { + const CGameArea* area = x850_world->GetAreaAlways(ai->GetAreaIdAlways()); + float f1; + if (area->IsPostConstructed()) + f1 = area->GetPostConstructed()->x10e4_; + else + f1 = 0.f; + if (f1 > 5.f) + doThink = false; + } + if (!doThink) + SendScriptMsgAlways(ai->GetUniqueId(), kInvalidUniqueId, + EScriptObjectMessage::InternalMessage26); + else if (x84c_player.get() != ent) + if (!GetPlatformAndDoorObjectList().IsPlatform(*ent)) + CGameCollision::Move(*this, physActor, dt, nullptr); + } + } } -void CStateManager::CrossTouchActors(float dt) +void CStateManager::CrossTouchActors() { + bool visits[1024] = {}; + for (CEntity* ent : GetActorObjectList()) + { + if (!ent) + continue; + CActor& actor = static_cast(*ent); + if (!actor.GetActive() || !actor.GetCallTouch()) + continue; + rstl::optional_object touchAABB = actor.GetTouchBounds(); + if (!touchAABB) + continue; + CMaterialFilter filter = CMaterialFilter::skPassEverything; + if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Trigger)) + filter = CMaterialFilter::MakeExclude(EMaterialTypes::Trigger); + + rstl::reserved_vector nearList; + BuildNearList(nearList, *touchAABB, filter, &actor); + + for (TUniqueId id : nearList) + { + CActor* ent2 = static_cast(ObjectById(id)); + if (!ent2) + continue; + + rstl::optional_object touchAABB2 = ent2->GetTouchBounds(); + if (!ent2->GetActive() || touchAABB2) + continue; + + if (visits[ent2->GetUniqueId() & 0x3ff]) + continue; + + if (touchAABB->intersects(*touchAABB2)) + { + actor.Touch(*ent2, *this); + ent2->Touch(actor, *this); + } + + visits[ent2->GetUniqueId() & 0x3ff] = true; + } + } } void CStateManager::ThinkEffectsAndActors(float dt) { + if (x84c_player->x9f4_ > 0.f) + { + x84c_player->DoThink(dt, *this); + return; + } + if (x904_ == 1) + { + for (CEntity* ent : GetAllObjectList()) + if (TCastToPtr effect = ent) + effect->Think(dt, *this); + } + else + { + for (CEntity* ent : GetAllObjectList()) + if (TCastToPtr ai = ent) + { + bool doThink = !xf94_29_; + if (doThink && ai->GetAreaIdAlways() != kInvalidAreaId) + { + const CGameArea* area = x850_world->GetAreaAlways(ai->GetAreaIdAlways()); + float f1; + if (area->IsPostConstructed()) + f1 = area->GetPostConstructed()->x10e4_; + else + f1 = 0.f; + if (f1 > 5.f) + doThink = false; + } + if (doThink) + { + CEntity* ent2 = GetAllObjectList().GetObjectById(ai->GetUniqueId()); + ent2->Think(dt, *this); + } + } + } } void CStateManager::UpdatePlayer(float dt) { - + x84c_player->Update(dt, *this); } void CStateManager::ShowPausedHUDMemo(ResId strg, float time) { - + xf78_hudMessageTime = time; + xf08_pauseHudMessage = strg; + DeferStateTransition(EStateManagerTransition::MessageScreen); } -void CStateManager::BringOutYourDead() +void CStateManager::ClearGraveyard() { - + for (TUniqueId id : x854_objectGraveyard) + { + CEntity* ent = GetAllObjectList().GetValidObjectById(id); + RemoveObject(id); + if (ent) + std::default_delete()(ent); + } + x854_objectGraveyard.clear(); } void CStateManager::FrameBegin(s32 frameCount) @@ -1528,11 +1749,52 @@ const CObjectList* CStateManager::GetObjectListById(EGameObjectList type) const return x808_objLists[int(type)].get(); } -void CStateManager::RemoveObject(TUniqueId) {} +void CStateManager::RemoveObject(TUniqueId uid) +{ + if (CEntity* ent = GetAllObjectList().GetValidObjectById(uid)) + { + if (ent->GetEditorId() != kInvalidEditorId) + { + x890_scriptIdMap.erase(ent->GetEditorId()); + } + if (ent->GetAreaIdAlways() != kInvalidAreaId) + { + CGameArea* area = x850_world->GetArea(ent->GetAreaIdAlways()); + if (area->IsPostConstructed()) + area->GetAreaObjects().RemoveObject(uid); + } + if (TCastToPtr act = ent) + x874_sortedListManager->Remove(act.GetPtr()); + } + for (auto& list : x808_objLists) + list->RemoveObject(uid); +} -void CStateManager::RemoveActor(TUniqueId) {} +void CStateManager::UpdateRoomAcoustics(TAreaId aid) +{ + u32 updateCount = 0; + CScriptRoomAcoustics* updates[10]; + for (CEntity* ent : GetAllObjectList()) + { + if (TCastToPtr acoustics = ent) + { + if (acoustics->GetAreaIdAlways() != aid || !acoustics->GetActive()) + continue; + updates[updateCount++] = acoustics.GetPtr(); + } + if (updateCount >= 10) + break; + } -void CStateManager::UpdateRoomAcoustics(TAreaId) {} + if (!updateCount) + { + CScriptRoomAcoustics::DisableAuxCallbacks(); + return; + } + + int idx = updateCount * x900_activeRandom->Float() * 0.99f; + updates[idx]->EnableAuxCallbacks(); +} void CStateManager::SetCurrentAreaId(TAreaId aid) { @@ -1551,8 +1813,6 @@ void CStateManager::SetCurrentAreaId(TAreaId aid) x850_world->GetMapWorld()->RecalculateWorldSphere(*x8c0_mapWorldInfo, *x850_world); } -void CStateManager::ClearGraveyard() {} - void CStateManager::DeleteObjectRequest(TUniqueId id) { CEntity* entity = ObjectById(id); @@ -1584,19 +1844,23 @@ void CStateManager::PrepareAreaUnload(TAreaId) {} void CStateManager::AreaLoaded(TAreaId) {} -void CStateManager::BuildNearList(rstl::reserved_vector& listOut, const zeus::CVector3f&, - const zeus::CVector3f&, float, const CMaterialFilter&, const CActor*) const +void CStateManager::BuildNearList(rstl::reserved_vector& listOut, const zeus::CVector3f& v1, + const zeus::CVector3f& v2, float f1, const CMaterialFilter& filter, + const CActor* actor) const { + x874_sortedListManager->BuildNearList(listOut, v1, v2, f1, filter, actor); } -void CStateManager::BuildColliderList(rstl::reserved_vector& listOut, const CActor&, - const zeus::CAABox&) const +void CStateManager::BuildColliderList(rstl::reserved_vector& listOut, const CActor& actor, + const zeus::CAABox& aabb) const { + x874_sortedListManager->BuildNearList(listOut, actor, aabb); } -void CStateManager::BuildNearList(rstl::reserved_vector& listOut, const zeus::CAABox&, - const CMaterialFilter&, const CActor*) const +void CStateManager::BuildNearList(rstl::reserved_vector& listOut, const zeus::CAABox& aabb, + const CMaterialFilter& filter, const CActor* actor) const { + x874_sortedListManager->BuildNearList(listOut, aabb, filter, actor); } void CStateManager::UpdateActorInSortedLists(CActor& act) @@ -1781,4 +2045,7 @@ bool CStateManager::ApplyDamage(TUniqueId, TUniqueId, TUniqueId, const CDamageIn { return false; } + +float CStateManager::g_EscapeShakeCountdown; +bool CStateManager::g_EscapeShakeCountdownInit = false; } diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index a43424c31..211529ca5 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -158,8 +158,6 @@ class CStateManager bool xab0_worldLoaded = false; - std::set xab4_uniqueInstanceNames; - enum class EInitPhase { LoadWorld, @@ -167,6 +165,8 @@ class CStateManager Done } xb3c_initPhase = EInitPhase::LoadWorld; + std::set xb40_uniqueInstanceNames; + CFinalInput xb54_finalInput; CCameraFilterPass xb84_camFilterPasses[9]; CCameraBlurPass xd14_camBlurPasses[9]; @@ -199,8 +199,8 @@ class CStateManager SOnScreenTex xef4_pendingScreenTex; ResId xf08_pauseHudMessage = -1; - float xf0c_ = 0.f; - float xf10_ = 0.f; + float xf0c_escapeTimer = 0.f; + float xf10_escapeTotalTime = 0.f; float xf14_curTimeMod900 = 0.f; TUniqueId xf18_ = kInvalidUniqueId; float xf1c_ = 0.f; @@ -260,7 +260,7 @@ public: void AddDrawableActor(const CActor& actor, const zeus::CVector3f& vec, const zeus::CAABox& aabb) const; bool SpecialSkipCinematic(); TAreaId GetVisAreaId() const; - void GetWeaponIdCount(TUniqueId, EWeaponType); + s32 GetWeaponIdCount(TUniqueId, EWeaponType); void RemoveWeaponId(TUniqueId, EWeaponType); void AddWeaponId(TUniqueId, EWeaponType); void UpdateEscapeSequenceTimer(float); @@ -274,6 +274,7 @@ public: void TouchPlayerActor(); void DrawSpaceWarp(const zeus::CVector3f&, float) const; void DrawReflection(const zeus::CVector3f&); + static void ReflectionDrawer(void*, const zeus::CVector3f&); void CacheReflection(); bool CanCreateProjectile(TUniqueId, EWeaponType, int) const; const CGameLightList* GetDynamicLightList() const; @@ -333,11 +334,11 @@ public: void PreThinkEffects(float dt); void MovePlatforms(float dt); void MoveDoors(float dt); - void CrossTouchActors(float dt); + void CrossTouchActors(); void ThinkEffectsAndActors(float dt); void UpdatePlayer(float dt); void ShowPausedHUDMemo(ResId strg, float time); - void BringOutYourDead(); + void ClearGraveyard(); void FrameBegin(s32 frameCount); void InitializeState(ResId mlvlId, TAreaId aid, ResId mreaId); void CreateStandardGameObjects(); @@ -345,11 +346,9 @@ public: CObjectList* ObjectListById(EGameObjectList type); const CObjectList* GetObjectListById(EGameObjectList type) const; void RemoveObject(TUniqueId); - void RemoveActor(TUniqueId); void UpdateRoomAcoustics(TAreaId); TAreaId GetNextAreaId() const { return x8cc_nextAreaId; } void SetCurrentAreaId(TAreaId); - void ClearGraveyard(); void DeleteObjectRequest(TUniqueId); CEntity* ObjectById(TUniqueId uid); const CEntity* GetObjectById(TUniqueId uid) const; @@ -425,6 +424,9 @@ public: void SetIsGeneratingObject(bool gen) { xf94_26_generatingObject = gen; } u32 GetParticleFlags() const { return xf34_particleFlags; } const CFinalInput& GetFinalInput() const { return xb54_finalInput; } + + static float g_EscapeShakeCountdown; + static bool g_EscapeShakeCountdownInit; }; } diff --git a/Runtime/Camera/CCameraManager.cpp b/Runtime/Camera/CCameraManager.cpp index e337ae045..fe605a816 100644 --- a/Runtime/Camera/CCameraManager.cpp +++ b/Runtime/Camera/CCameraManager.cpp @@ -94,7 +94,7 @@ void CCameraManager::SetInsideFluid(bool val, TUniqueId fluidId) void CCameraManager::Update(float dt, CStateManager& stateMgr) { - sub800097AC(dt, stateMgr); + UpdateCameraHints(dt, stateMgr); ThinkCameras(dt, stateMgr); UpdateListener(stateMgr); UpdateRumble(dt, stateMgr); @@ -212,7 +212,7 @@ float CCameraManager::sub80009148() const std::cos(zeus::degToRad(30.f))), 1.f); } -void CCameraManager::sub800097AC(float, CStateManager& mgr) +void CCameraManager::UpdateCameraHints(float, CStateManager& mgr) { } diff --git a/Runtime/Camera/CCameraManager.hpp b/Runtime/Camera/CCameraManager.hpp index 4e4e20500..f8334a9a2 100644 --- a/Runtime/Camera/CCameraManager.hpp +++ b/Runtime/Camera/CCameraManager.hpp @@ -113,7 +113,7 @@ public: float sub80009148() const; - void sub800097AC(float, CStateManager&); + void UpdateCameraHints(float, CStateManager&); void ThinkCameras(float, CStateManager&); void UpdateFog(float, CStateManager&); void UpdateRumble(float, CStateManager&); diff --git a/Runtime/Camera/CCameraShakeData.cpp b/Runtime/Camera/CCameraShakeData.cpp index be97b73aa..9ab2da46c 100644 --- a/Runtime/Camera/CCameraShakeData.cpp +++ b/Runtime/Camera/CCameraShakeData.cpp @@ -29,6 +29,13 @@ CCameraShakeData::CCameraShakeData(float f1, float f2, u32 w1, const zeus::CVect : x0_duration(f1), x8_shaker1(shaker1), x44_shaker2(shaker2), x80_shaker3(shaker3), xc0_flags(w1), xc4_sfxPos(v1), xd0_f2(f2) {} +CCameraShakeData::CCameraShakeData(float f1, float f2) +: CCameraShakeData(f1, 100.f, 0, zeus::CVector3f::skZero, CCameraShakerComponent{}, CCameraShakerComponent{}, + CCameraShakerComponent{1, + SCameraShakePoint{0, 0.25f * f1, 0.f, 0.75f * f1, f2}, + SCameraShakePoint{1, 0.f, 0.f, 0.5f * f1, 2.f}}) +{} + float CCameraShakeData::GetSomething() const { float ret = 0.f; diff --git a/Runtime/Camera/CCameraShakeData.hpp b/Runtime/Camera/CCameraShakeData.hpp index 596b342ac..4299c6d3e 100644 --- a/Runtime/Camera/CCameraShakeData.hpp +++ b/Runtime/Camera/CCameraShakeData.hpp @@ -54,6 +54,7 @@ public: CCameraShakeData(float duration, float f2, u32 w1, const zeus::CVector3f& v1, const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2, const CCameraShakerComponent& shaker3); + CCameraShakeData(float f1, float f2); //zeus::CVector3f GeneratePoint(float dt, CRandom16& r); float GetSomething() const; float GetSomething2() const; diff --git a/Runtime/Collision/CGameCollision.cpp b/Runtime/Collision/CGameCollision.cpp index ba933f780..8e2dee35a 100644 --- a/Runtime/Collision/CGameCollision.cpp +++ b/Runtime/Collision/CGameCollision.cpp @@ -45,7 +45,7 @@ void CGameCollision::InitCollision() CCollisionPrimitive::InitEndColliders(); } -void CGameCollision::Move(CStateManager& mgr, CPlayer& player, float dt, const rstl::reserved_vector*) +void CGameCollision::Move(CStateManager& mgr, CPhysicsActor& actor, float dt, const rstl::reserved_vector*) { } diff --git a/Runtime/Collision/CGameCollision.hpp b/Runtime/Collision/CGameCollision.hpp index 78f54279c..e5006eebd 100644 --- a/Runtime/Collision/CGameCollision.hpp +++ b/Runtime/Collision/CGameCollision.hpp @@ -16,7 +16,7 @@ class CCollisionInfo; class CCollisionInfoList; class CMaterialList; class CStateManager; -class CPlayer; +class CPhysicsActor; class CGameCollision { @@ -28,7 +28,7 @@ public: static bool NullBooleanCollider(const CInternalCollisionStructure&) { return false; } static bool NullCollisionCollider(const CInternalCollisionStructure&, CCollisionInfoList&) { return false; } static void InitCollision(); - static void Move(CStateManager& mgr, CPlayer& player, float dt, const rstl::reserved_vector*); + static void Move(CStateManager& mgr, CPhysicsActor& actor, float dt, const rstl::reserved_vector*); static bool CanBlock(const CMaterialList&, const zeus::CVector3f&); static bool IsFloor(const CMaterialList&, const zeus::CVector3f&); diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index 8bf9a325c..cebcba061 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -978,6 +978,14 @@ void CBooRenderer::BeginScene() void CBooRenderer::EndScene() { CGraphics::EndScene(); + if (x2dc_reflectionAge >= 2) + { + // Delete reflection tex x14c_ + } + else + { + ++x2dc_reflectionAge; + } } void CBooRenderer::SetAmbientColor(const zeus::CColor& color) @@ -994,6 +1002,24 @@ u32 CBooRenderer::GetFPS() return 0; } +void CBooRenderer::CacheReflection(TReflectionCallback cb, void* ctx, bool clearAfter) +{ + if (!x318_24_refectionDirty) + return; + x318_24_refectionDirty = false; + x2dc_reflectionAge = 0; + + BindReflectionDrawTarget(); + SViewport backupVp = g_Viewport; + SetViewport(0, 0, 256, 256); + CGraphics::g_BooMainCommandQueue->clearTarget(); + cb(ctx, CBooModel::g_ReflectViewPos); + boo::SWindowRect rect(0, 0, 256, 256); + CGraphics::g_BooMainCommandQueue->resolveBindTexture(x14c_reflectionTex, rect, false, 0, true, false); + BindMainDrawTarget(); + SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height); +} + void CBooRenderer::DrawSpaceWarp(const zeus::CVector3f& pt, float strength) { m_spaceWarpFilter.setStrength(strength); diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index b3a2c398e..58464a302 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -134,6 +134,7 @@ class CBooRenderer : public IRenderer std::list m_fogVolumeFilters; std::list::iterator m_nextFogVolumeFilter; std::list> x2c4_spaceWarps; + u32 x2dc_reflectionAge = 2; zeus::CColor x2e0_ = zeus::CColor::skWhite; zeus::CVector3f x2e4_ = {0.f, 1.f, 0.f}; @@ -231,7 +232,7 @@ public: void SetAmbientColor(const zeus::CColor&); void DrawString(const char*, int, int); u32 GetFPS(); - //void CacheReflection(TReflectionCallback, void*, bool); + void CacheReflection(TReflectionCallback, void*, bool); void DrawSpaceWarp(const zeus::CVector3f&, float); void DrawThermalModel(const CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol); void DrawXRayOutline(const zeus::CAABox&); diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index 0df0c5304..6db30acb4 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -178,8 +178,11 @@ public: static void SetDrawingOccluders(bool occ) {g_DrawingOccluders = occ;} static void SetNewPlayerPositionAndTime(const zeus::CVector3f& pos); - static void KillCachedViewDepState(); + static zeus::CVector3f g_ReflectViewPos; + static void KillCachedViewDepState(); + static void EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf, + zeus::CMatrix4f*& mtxsOut, float& alphaOut); }; class CModel diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index e7d9e9a52..e9b0a1544 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -46,6 +46,83 @@ void CBooModel::KillCachedViewDepState() g_LastModelCached = nullptr; } +zeus::CVector3f CBooModel::g_ReflectViewPos = {}; + +static const zeus::CMatrix4f ReflectBaseMtx = +{ + 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f, + 0.f, 0.f, 0.f, 1.f +}; + +void CBooModel::EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf, + zeus::CMatrix4f*& mtxsOut, float& alphaOut) +{ + zeus::CVector3f modelToPlayer = g_PlayerPosition - CGraphics::g_GXModelMatrix.origin; + zeus::CVector3f modelToPlayerLocal = CGraphics::g_GXModelMatrix.transposeRotate(modelToPlayer); + + zeus::CVector3f surfPos; + float surfSize = 0.f; + if (surf) + { + zeus::CVector3f surfCenter(surf->m_data.centroid); + zeus::CVector3f surfNormal(surf->m_data.reflectionNormal); + float dotDelta = surfNormal.dot(modelToPlayerLocal) - surfCenter.dot(surfNormal); + surfPos = modelToPlayerLocal - surfNormal * dotDelta; + } + else + { + surfPos = model.x20_aabb.center(); + surfSize = (model.x20_aabb.max.x - model.x20_aabb.min.x) + (model.x20_aabb.max.y - model.x20_aabb.min.y) * 0.5f; + } + + if (g_Renderer->x318_24_refectionDirty) + { + zeus::CVector3f playerToPos = g_ReflectViewPos - g_PlayerPosition; + zeus::CVector3f vecToPos = surfPos - g_PlayerPosition; + if (playerToPos.dot(playerToPos) < vecToPos.dot(vecToPos)) + g_ReflectViewPos = surfPos; + } + else + { + g_ReflectViewPos = surfPos; + g_Renderer->x318_24_refectionDirty = true; + } + + zeus::CVector3f playerToSurf = surfPos - modelToPlayerLocal; + float distance = std::max(-(0.5f * surfSize - playerToSurf.magnitude()), FLT_EPSILON); + if (distance >= 5.f) + { + alphaOut = 0.f; + } + else + { + alphaOut = (5.f - distance) / 5.f; + + /* Indirect map matrix */ + mtxsOut[0] = (CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix).toMatrix4f(); + + /* Reflection map matrix */ + zeus::CVector3f v1 = playerToSurf * (1.f / surfSize); + zeus::CVector3f v2 = v1.cross(zeus::CVector3f::skUp); + if (v2.canBeNormalized()) + v2.normalize(); + else + v2 = zeus::CVector3f::skRight; + + float timeScale = 0.32258067f * (0.02f * distance + 1.f); + float f1 = timeScale * g_TransformedTime; + float f2 = timeScale * g_TransformedTime2; + mtxsOut[1] = ReflectBaseMtx; + mtxsOut[1][0][0] = f1 * v2.x; + mtxsOut[1][1][0] = f1 * v2.y; + mtxsOut[1][3][0] = -surfPos.dot(v2) * f1 + 0.5f; + mtxsOut[1][2][1] = f2; + mtxsOut[1][3][1] = -modelToPlayerLocal.z * f2; + } +} + CBooModel::~CBooModel() { if (m_prev) @@ -162,11 +239,24 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() uniBufSize += thisSz; } + /* Surface reflection texmatrix uniform with first identity slot */ + size_t reflectOff = uniBufSize; + uniBufSize += 256; + for (const CBooSurface& surf : *x0_surfaces) + { + const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx); + if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye()) + uniBufSize += 256; + } + /* Allocate resident buffer */ m_uniformDataSize = uniBufSize; newInst.m_uniformBuffer = ctx.newDynamicBuffer(boo::BufferUse::Uniform, uniBufSize, 1); - boo::IGraphicsBuffer* bufs[] = {newInst.m_uniformBuffer, newInst.m_uniformBuffer, newInst.m_uniformBuffer}; + boo::IGraphicsBuffer* bufs[] = {newInst.m_uniformBuffer, + newInst.m_uniformBuffer, + newInst.m_uniformBuffer, + newInst.m_uniformBuffer}; /* Binding for each surface */ newInst.m_shaderDataBindings.reserve(x0_surfaces->size()); @@ -175,14 +265,16 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() boo::ITexture* mbShadowTexs[] = {g_Renderer->m_ballShadowId, g_Renderer->x220_sphereRamp, g_Renderer->m_ballFade}; - size_t thisOffs[3]; - size_t thisSizes[3]; + size_t thisOffs[4]; + size_t thisSizes[4]; - static const boo::PipelineStage stages[3] = {boo::PipelineStage::Vertex, + static const boo::PipelineStage stages[4] = {boo::PipelineStage::Vertex, boo::PipelineStage::Vertex, - boo::PipelineStage::Fragment}; + boo::PipelineStage::Fragment, + boo::PipelineStage::Vertex}; /* Enumerate surfaces and build data bindings */ + size_t curReflect = reflectOff + 256; for (const CBooSurface& surf : *x0_surfaces) { const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx); @@ -193,6 +285,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() TCachedToken& tex = x1c_textures[idx]; texs[texCount++] = tex.GetObj()->GetBooTexture(); } + texs[6] = g_Renderer->x14c_reflectionTex; texs[7] = g_Renderer->x220_sphereRamp; if (m_skinBankCount) @@ -212,6 +305,18 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() thisOffs[2] = lightOff; thisSizes[2] = lightSz; + bool useReflection = mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye(); + if (useReflection) + { + thisOffs[3] = curReflect; + curReflect += 256; + } + else + { + thisOffs[3] = reflectOff; + } + thisSizes[3] = 256; + const std::shared_ptr& pipelines = m_pipelines->at(surf.m_data.matIdx); newInst.m_shaderDataBindings.emplace_back(); @@ -233,6 +338,11 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() texCount = 3; ltexs = mbShadowTexs; } + else if (useReflection) + { + texCount = 7; + ltexs = texs; + } else { texCount = mat.textureIdxs.size(); @@ -240,7 +350,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() } extendeds.push_back( ctx.newShaderDataBinding(pipeline, m_vtxFmt, - x8_vbo, nullptr, xc_ibo, 3, bufs, stages, + x8_vbo, nullptr, xc_ibo, 4, bufs, stages, thisOffs, thisSizes, texCount, ltexs, nullptr, nullptr)); ++idx; } @@ -704,6 +814,26 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags, lightingOut.fog = CGraphics::g_Fog; } + dataCur += sizeof(CModelShaders::LightingUniform); + dataCur = dataOut + ROUND_UP_256(dataCur - dataOut); + + /* Reflection texmtx uniform */ + zeus::CMatrix4f* identMtxs = reinterpret_cast(dataCur); + identMtxs[0] = zeus::CMatrix4f(); + identMtxs[1] = zeus::CMatrix4f(); + u8* curReflect = dataCur + 256; + for (const CBooSurface& surf : *x0_surfaces) + { + const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx); + if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye()) + { + zeus::CMatrix4f* mtxs = reinterpret_cast(curReflect); + float& alpha = reinterpret_cast(mtxs[2]); + curReflect += 256; + EnsureViewDepStateCached(*this, mat.flags.samusReflectionSurfaceEye() ? &surf : nullptr, mtxs, alpha); + } + } + inst->m_uniformBuffer->unmap(); } @@ -807,10 +937,17 @@ CModel::CModel(std::unique_ptr&& in, u32 /* dataLen */, IObjectStore* stor matSet.m_shaders.reserve(matSet.m_matSet.materials.size()); for (const MaterialSet::Material& mat : matSet.m_matSet.materials) { + hecl::Backend::ReflectionType reflectionType; + if (mat.flags.samusReflectionIndirectTexture()) + reflectionType = hecl::Backend::ReflectionType::Indirect; + else if (mat.flags.samusReflection()) + reflectionType = hecl::Backend::ReflectionType::Simple; + else + reflectionType = hecl::Backend::ReflectionType::None; hecl::Runtime::ShaderTag tag(mat.heclIr, hmdlMeta.colorCount, hmdlMeta.uvCount, hmdlMeta.weightCount, hmdlMeta.weightCount * 4, 8, boo::Primitive(hmdlMeta.topology), - true, true, true); + reflectionType, true, true, true); matSet.m_shaders.push_back(CModelShaders::g_ModelShaders->buildExtendedShader (tag, mat.heclIr, "CMDL", *CGraphics::g_BooFactory)); } diff --git a/Runtime/Graphics/CSkinnedModel.cpp b/Runtime/Graphics/CSkinnedModel.cpp index 493cbfcd7..2dad5aca9 100644 --- a/Runtime/Graphics/CSkinnedModel.cpp +++ b/Runtime/Graphics/CSkinnedModel.cpp @@ -51,4 +51,7 @@ CMorphableSkinnedModel::CMorphableSkinnedModel(IObjectStore& store, ResId model, { } +CSkinnedModel::FPointGenerator CSkinnedModel::g_PointGenFunc = nullptr; +void* CSkinnedModel::g_PointGenCtx = nullptr; + } diff --git a/Runtime/Graphics/CSkinnedModel.hpp b/Runtime/Graphics/CSkinnedModel.hpp index a69c26a4f..e24e1f90e 100644 --- a/Runtime/Graphics/CSkinnedModel.hpp +++ b/Runtime/Graphics/CSkinnedModel.hpp @@ -44,6 +44,15 @@ public: const std::experimental::optional& morphEffect, const float* morphMagnitudes); void Draw(const CModelFlags& drawFlags) const; + + typedef void(*FPointGenerator)(void* item, const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1); + static void SetPointGeneratorFunc(void* ctx, FPointGenerator func) + { + g_PointGenFunc = func; + g_PointGenCtx = ctx; + } + static FPointGenerator g_PointGenFunc; + static void* g_PointGenCtx; }; class CMorphableSkinnedModel : public CSkinnedModel diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index cbfe527d7..56a95ef6d 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -88,7 +88,7 @@ public: virtual void SetAmbientColor(const zeus::CColor&)=0; virtual void DrawString(const char*, int, int)=0; virtual u32 GetFPS()=0; - //virtual void CacheReflection(TReflectionCallback, void*, bool)=0; + virtual void CacheReflection(TReflectionCallback, void*, bool)=0; virtual void DrawSpaceWarp(const zeus::CVector3f&, float)=0; virtual void DrawThermalModel(const CModel&, const zeus::CColor&, const zeus::CColor&)=0; virtual void DrawXRayOutline(const zeus::CAABox&)=0; diff --git a/Runtime/Input/CRumbleManager.hpp b/Runtime/Input/CRumbleManager.hpp index 0a7b22230..976e4fc2f 100644 --- a/Runtime/Input/CRumbleManager.hpp +++ b/Runtime/Input/CRumbleManager.hpp @@ -13,8 +13,8 @@ public: CRumbleManager() = default; void Update(float); void StopRumble(u16) {} - void Rumble(ERumbleFxId, CStateManager&, ERumblePriority priority) {} - void Rumble(ERumbleFxId, float, CStateManager&, ERumblePriority priority) {} + void Rumble(CStateManager&, ERumbleFxId, ERumblePriority priority) {} + void Rumble(CStateManager&, ERumbleFxId, float, ERumblePriority priority) {} }; } diff --git a/Runtime/Input/CRumbleVoice.hpp b/Runtime/Input/CRumbleVoice.hpp index c9c59ed5a..fc509d71f 100644 --- a/Runtime/Input/CRumbleVoice.hpp +++ b/Runtime/Input/CRumbleVoice.hpp @@ -7,7 +7,8 @@ namespace urde { enum class ERumbleFxId { - Seven = 7 + Seven = 7, + Eleven = 11 }; enum class ERumblePriority { diff --git a/Runtime/Weapon/CWeaponMgr.cpp b/Runtime/Weapon/CWeaponMgr.cpp index 0a819bde2..ba34681e7 100644 --- a/Runtime/Weapon/CWeaponMgr.cpp +++ b/Runtime/Weapon/CWeaponMgr.cpp @@ -2,4 +2,35 @@ namespace urde { + +void CWeaponMgr::Add(TUniqueId, EWeaponType) +{ + +} + +void CWeaponMgr::Remove(TUniqueId) +{ + +} + +void CWeaponMgr::IncrCount(TUniqueId, EWeaponType) +{ + +} + +void CWeaponMgr::DecrCount(TUniqueId, EWeaponType) +{ + +} + +s32 CWeaponMgr::GetNumActive(TUniqueId, EWeaponType) const +{ + return 0; +} + +s32 CWeaponMgr::GetIndex(TUniqueId) const +{ + return 0; +} + } diff --git a/Runtime/World/CActorModelParticles.cpp b/Runtime/World/CActorModelParticles.cpp index 5b467fdaa..a9a0e8247 100644 --- a/Runtime/World/CActorModelParticles.cpp +++ b/Runtime/World/CActorModelParticles.cpp @@ -9,6 +9,7 @@ #include "Particle/CGenDescription.hpp" #include "World/CWorld.hpp" #include "Graphics/CBooRenderer.hpp" +#include "Graphics/CSkinnedModel.hpp" namespace urde { @@ -19,6 +20,11 @@ CActorModelParticles::CItem::CItem(const CEntity& ent, CActorModelParticles& par x8_.resize(8); } +void CActorModelParticles::CItem::GeneratePoints(const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1) +{ + +} + static const char* ParticleDGRPs[] = { "Effect_OnFire_DGRP", @@ -157,4 +163,25 @@ void CActorModelParticles::Update(float dt, CStateManager& mgr) } +void CActorModelParticles::PointGenerator(void* item, const zeus::CVector3f* v1, + const zeus::CVector3f* v2, int w1) +{ + reinterpret_cast(item)->GeneratePoints(v1, v2, w1); +} + +void CActorModelParticles::SetupHook(TUniqueId uid) +{ + auto search = FindSystem(uid); + if (search != x0_items.cend()) + CSkinnedModel::SetPointGeneratorFunc((void*)&*search, PointGenerator); +} + +std::list::const_iterator CActorModelParticles::FindSystem(TUniqueId uid) const +{ + for (auto it = x0_items.cbegin() ; it != x0_items.cend() ; ++it) + if (it->x0_id == uid) + return it; + return x0_items.cend(); +} + } diff --git a/Runtime/World/CActorModelParticles.hpp b/Runtime/World/CActorModelParticles.hpp index a22333712..5f72540f7 100644 --- a/Runtime/World/CActorModelParticles.hpp +++ b/Runtime/World/CActorModelParticles.hpp @@ -18,6 +18,7 @@ class CParticleElectric; class CActorModelParticles { +public: class CItem { friend class CActorModelParticles; @@ -60,8 +61,10 @@ class CActorModelParticles u8 x134_bits = 0; public: CItem(const CEntity& ent, CActorModelParticles& parent); + void GeneratePoints(const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1); }; +private: std::list x0_items; TToken x18_onFire; TToken x20_ash; @@ -84,8 +87,11 @@ class CActorModelParticles public: CActorModelParticles(); + static void PointGenerator(void* item, const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1); void AddStragglersToRenderer(const CStateManager& mgr); void Update(float dt, CStateManager& mgr); + void SetupHook(TUniqueId uid); + std::list::const_iterator FindSystem(TUniqueId uid) const; }; } diff --git a/Runtime/World/CGameArea.cpp b/Runtime/World/CGameArea.cpp index 60ed98268..77906094a 100644 --- a/Runtime/World/CGameArea.cpp +++ b/Runtime/World/CGameArea.cpp @@ -1050,7 +1050,7 @@ void CGameArea::SetAreaAttributes(const CScriptAreaAttributes* areaAttributes) bool CGameArea::CAreaObjectList::IsQualified(const CEntity& ent) { - return (ent.GetAreaId() == x200c_areaIdx); + return (ent.GetAreaIdAlways() == x200c_areaIdx); } } diff --git a/Runtime/World/CGameLight.cpp b/Runtime/World/CGameLight.cpp index 9dc294be0..b79b0fa3d 100644 --- a/Runtime/World/CGameLight.cpp +++ b/Runtime/World/CGameLight.cpp @@ -29,7 +29,7 @@ void CGameLight::Think(float dt, CStateManager& mgr) x144_lifeTime -= dt; if (x144_lifeTime <= 0.f) - mgr.RemoveActor(GetUniqueId()); + mgr.FreeScriptObject(GetUniqueId()); } void CGameLight::SetLightPriorityAndId() diff --git a/Runtime/World/CPhysicsActor.hpp b/Runtime/World/CPhysicsActor.hpp index b5ced2205..68afa98b9 100644 --- a/Runtime/World/CPhysicsActor.hpp +++ b/Runtime/World/CPhysicsActor.hpp @@ -121,6 +121,7 @@ public: virtual float GetStepDownHeight() const; virtual float GetWeight() const; + float GetMass() const { return xe8_mass; } void sub_8011A4C(float f); float sub_8011A4B8() const; void SetPrimitiveOffset(const zeus::CVector2f& offset); diff --git a/Runtime/World/CPlayer.cpp b/Runtime/World/CPlayer.cpp index da41e076d..8e4223063 100644 --- a/Runtime/World/CPlayer.cpp +++ b/Runtime/World/CPlayer.cpp @@ -104,6 +104,13 @@ void CPlayer::DoPreThink(float dt, CStateManager& mgr) ent->PreThink(dt, mgr); } +void CPlayer::DoThink(float dt, CStateManager& mgr) +{ + Think(dt, mgr); + if (CEntity* ent = mgr.ObjectById(xa00_)) + ent->Think(dt, mgr); +} + void CPlayer::UpdateScanningState(const CFinalInput& input, CStateManager& mgr, float) {} void CPlayer::ValidateScanning(const CFinalInput& input, CStateManager& mgr) {} diff --git a/Runtime/World/CPlayer.hpp b/Runtime/World/CPlayer.hpp index b4e89f973..49bad24a5 100644 --- a/Runtime/World/CPlayer.hpp +++ b/Runtime/World/CPlayer.hpp @@ -319,6 +319,7 @@ public: rstl::optional_object GetTouchBounds() const; void Touch(CActor&, CStateManager& mgr); void DoPreThink(float dt, CStateManager& mgr); + void DoThink(float dt, CStateManager& mgr); void UpdateScanningState(const CFinalInput& input, CStateManager& mgr, float); void ValidateScanning(const CFinalInput& input, CStateManager& mgr); void SetScanningState(EPlayerScanState, CStateManager& mgr); diff --git a/Runtime/World/CScriptPlayerActor.cpp b/Runtime/World/CScriptPlayerActor.cpp index 866081ca1..92bc90653 100644 --- a/Runtime/World/CScriptPlayerActor.cpp +++ b/Runtime/World/CScriptPlayerActor.cpp @@ -54,5 +54,10 @@ void CScriptPlayerActor::AddToRenderer(const zeus::CFrustum&, const CStateManage void CScriptPlayerActor::Render(const CStateManager& mgr) const { +} + +void CScriptPlayerActor::TouchModels() +{ + } } diff --git a/Runtime/World/CScriptPlayerActor.hpp b/Runtime/World/CScriptPlayerActor.hpp index 797cbfa78..f7be29ae2 100644 --- a/Runtime/World/CScriptPlayerActor.hpp +++ b/Runtime/World/CScriptPlayerActor.hpp @@ -50,6 +50,7 @@ public: void PreRender(CStateManager &, const zeus::CFrustum &); void AddToRenderer(const zeus::CFrustum &, const CStateManager &) const; void Render(const CStateManager &mgr) const; + void TouchModels(); }; } diff --git a/Runtime/World/CScriptRoomAcoustics.hpp b/Runtime/World/CScriptRoomAcoustics.hpp index e0d7e307b..f96de251f 100644 --- a/Runtime/World/CScriptRoomAcoustics.hpp +++ b/Runtime/World/CScriptRoomAcoustics.hpp @@ -25,8 +25,6 @@ class CScriptRoomAcoustics : public CEntity bool x7c_delay; amuse::EffectDelayInfo x80_delayInfo; - void EnableAuxCallbacks(); - public: CScriptRoomAcoustics(TUniqueId uid, const std::string& name, const CEntityInfo& info, bool active, u32 volScale, @@ -41,6 +39,7 @@ public: void Think(float dt, CStateManager& stateMgr); void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr); void Accept(IVisitor& visitor); + void EnableAuxCallbacks(); static void DisableAuxCallbacks(); }; diff --git a/Runtime/World/ScriptObjectSupport.hpp b/Runtime/World/ScriptObjectSupport.hpp index a41920c03..bc774e909 100644 --- a/Runtime/World/ScriptObjectSupport.hpp +++ b/Runtime/World/ScriptObjectSupport.hpp @@ -219,7 +219,8 @@ enum class EScriptObjectMessage InternalMessage17 = 39, InternalMessage18 = 40, InternalMessage19 = 41, - InternalMessage20 = 42 + InternalMessage20 = 42, + InternalMessage26 = 48 }; } diff --git a/hecl b/hecl index c3db26f4a..e88c5a689 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit c3db26f4a195a6db5f28dd160ea9849a707745c3 +Subproject commit e88c5a6891c2b68d8933df863022d3f5f3074bc2