mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-05-02 10:33:57 +00:00
Fix 3rd person camera 180-degree flip after cam anim ends (#5)
* Fix 3rd person camera 180-degree flip after cam anim ends When a cam anim (NPC interaction cutscene) ends, FUN_1004b6d0 places the player actor at the camera's final position using the camera's direction, which uses standard convention (z = visual forward). The 3rd person camera relies on backward-z convention (z = visual backward, from TurnAround). This mismatch caused the camera to face 180 degrees wrong permanently after any cam anim. Add a HandleCamAnimEnd extension hook in FUN_1004b6d0 that, when the 3rd person camera is active, flips the ROI direction back to backward-z and re-establishes the correct camera position.
This commit is contained in:
parent
237dca8f51
commit
dcf3b66173
@ -3,6 +3,7 @@
|
|||||||
#include "3dmanager/lego3dmanager.h"
|
#include "3dmanager/lego3dmanager.h"
|
||||||
#include "decomp.h"
|
#include "decomp.h"
|
||||||
#include "define.h"
|
#include "define.h"
|
||||||
|
#include "extensions/multiplayer.h"
|
||||||
#include "islepathactor.h"
|
#include "islepathactor.h"
|
||||||
#include "legoanimationmanager.h"
|
#include "legoanimationmanager.h"
|
||||||
#include "legoanimpresenter.h"
|
#include "legoanimpresenter.h"
|
||||||
@ -20,6 +21,8 @@
|
|||||||
#include "mxtimer.h"
|
#include "mxtimer.h"
|
||||||
#include "mxutilities.h"
|
#include "mxutilities.h"
|
||||||
|
|
||||||
|
using namespace Extensions;
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(LegoAnimMMPresenter, 0x74)
|
DECOMP_SIZE_ASSERT(LegoAnimMMPresenter, 0x74)
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x1004a8d0
|
// FUNCTION: LEGO1 0x1004a8d0
|
||||||
@ -480,6 +483,10 @@ MxBool LegoAnimMMPresenter::FUN_1004b6d0(MxLong p_time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
actor->SetActorState(LegoPathActor::c_initial);
|
actor->SetActorState(LegoPathActor::c_initial);
|
||||||
|
|
||||||
|
if (m_tranInfo->m_unk0x29) {
|
||||||
|
Extension<MultiplayerExt>::Call(HandleCamAnimEnd, actor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@ -38,6 +38,7 @@ class MultiplayerExt {
|
|||||||
|
|
||||||
static void HandleActorEnter(IslePathActor* p_actor);
|
static void HandleActorEnter(IslePathActor* p_actor);
|
||||||
static void HandleActorExit(IslePathActor* p_actor);
|
static void HandleActorExit(IslePathActor* p_actor);
|
||||||
|
static void HandleCamAnimEnd(LegoPathActor* p_actor);
|
||||||
static MxBool ShouldInvertMovement(LegoPathActor* p_actor);
|
static MxBool ShouldInvertMovement(LegoPathActor* p_actor);
|
||||||
|
|
||||||
// Returns true if the multiplayer connection was rejected (e.g. room full).
|
// Returns true if the multiplayer connection was rejected (e.g. room full).
|
||||||
@ -59,6 +60,7 @@ constexpr auto HandleWorldEnable = &MultiplayerExt::HandleWorldEnable;
|
|||||||
constexpr auto HandleEntityNotify = &MultiplayerExt::HandleEntityNotify;
|
constexpr auto HandleEntityNotify = &MultiplayerExt::HandleEntityNotify;
|
||||||
constexpr auto HandleActorEnter = &MultiplayerExt::HandleActorEnter;
|
constexpr auto HandleActorEnter = &MultiplayerExt::HandleActorEnter;
|
||||||
constexpr auto HandleActorExit = &MultiplayerExt::HandleActorExit;
|
constexpr auto HandleActorExit = &MultiplayerExt::HandleActorExit;
|
||||||
|
constexpr auto HandleCamAnimEnd = &MultiplayerExt::HandleCamAnimEnd;
|
||||||
constexpr auto ShouldInvertMovement = &MultiplayerExt::ShouldInvertMovement;
|
constexpr auto ShouldInvertMovement = &MultiplayerExt::ShouldInvertMovement;
|
||||||
constexpr auto CheckRejected = &MultiplayerExt::CheckRejected;
|
constexpr auto CheckRejected = &MultiplayerExt::CheckRejected;
|
||||||
#else
|
#else
|
||||||
@ -66,6 +68,7 @@ constexpr decltype(&MultiplayerExt::HandleWorldEnable) HandleWorldEnable = nullp
|
|||||||
constexpr decltype(&MultiplayerExt::HandleEntityNotify) HandleEntityNotify = nullptr;
|
constexpr decltype(&MultiplayerExt::HandleEntityNotify) HandleEntityNotify = nullptr;
|
||||||
constexpr decltype(&MultiplayerExt::HandleActorEnter) HandleActorEnter = nullptr;
|
constexpr decltype(&MultiplayerExt::HandleActorEnter) HandleActorEnter = nullptr;
|
||||||
constexpr decltype(&MultiplayerExt::HandleActorExit) HandleActorExit = nullptr;
|
constexpr decltype(&MultiplayerExt::HandleActorExit) HandleActorExit = nullptr;
|
||||||
|
constexpr decltype(&MultiplayerExt::HandleCamAnimEnd) HandleCamAnimEnd = nullptr;
|
||||||
constexpr decltype(&MultiplayerExt::ShouldInvertMovement) ShouldInvertMovement = nullptr;
|
constexpr decltype(&MultiplayerExt::ShouldInvertMovement) ShouldInvertMovement = nullptr;
|
||||||
constexpr decltype(&MultiplayerExt::CheckRejected) CheckRejected = nullptr;
|
constexpr decltype(&MultiplayerExt::CheckRejected) CheckRejected = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -30,6 +30,7 @@ class ThirdPersonCamera {
|
|||||||
// Core hooks
|
// Core hooks
|
||||||
void OnActorEnter(IslePathActor* p_actor);
|
void OnActorEnter(IslePathActor* p_actor);
|
||||||
void OnActorExit(IslePathActor* p_actor);
|
void OnActorExit(IslePathActor* p_actor);
|
||||||
|
void OnCamAnimEnd(LegoPathActor* p_actor);
|
||||||
|
|
||||||
// Called every frame from NetworkManager::Tickle()
|
// Called every frame from NetworkManager::Tickle()
|
||||||
void Tick(float p_deltaTime);
|
void Tick(float p_deltaTime);
|
||||||
|
|||||||
@ -124,6 +124,13 @@ void MultiplayerExt::HandleActorExit(IslePathActor* p_actor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MultiplayerExt::HandleCamAnimEnd(LegoPathActor* p_actor)
|
||||||
|
{
|
||||||
|
if (s_networkManager) {
|
||||||
|
s_networkManager->GetThirdPersonCamera().OnCamAnimEnd(p_actor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MxBool MultiplayerExt::ShouldInvertMovement(LegoPathActor* p_actor)
|
MxBool MultiplayerExt::ShouldInvertMovement(LegoPathActor* p_actor)
|
||||||
{
|
{
|
||||||
if (s_networkManager && UserActor() == p_actor) {
|
if (s_networkManager && UserActor() == p_actor) {
|
||||||
|
|||||||
@ -207,6 +207,23 @@ void ThirdPersonCamera::OnActorExit(IslePathActor* p_actor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThirdPersonCamera::OnCamAnimEnd(LegoPathActor* p_actor)
|
||||||
|
{
|
||||||
|
if (!m_active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUN_1004b6d0's PlaceActor set the ROI with standard direction
|
||||||
|
// (z = visual forward). The 3rd person camera needs backward-z.
|
||||||
|
// Flip the ROI direction, then re-setup the camera.
|
||||||
|
LegoROI* roi = (m_currentVehicleType == VEHICLE_NONE) ? m_playerROI : p_actor->GetROI();
|
||||||
|
if (roi) {
|
||||||
|
FlipROIDirection(roi);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupCamera(p_actor);
|
||||||
|
}
|
||||||
|
|
||||||
void ThirdPersonCamera::Tick(float p_deltaTime)
|
void ThirdPersonCamera::Tick(float p_deltaTime)
|
||||||
{
|
{
|
||||||
if (!m_active) {
|
if (!m_active) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user