This commit is contained in:
Sebastian Mischke 2026-01-08 00:38:51 +01:00 committed by GitHub
commit 280874b4ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 99 additions and 92 deletions

View File

@ -12,7 +12,7 @@ class Act3;
// SIZE 0x0c
class HelicopterState : public LegoState {
public:
HelicopterState() : m_unk0x08(0) {}
HelicopterState() : m_status(0) {}
// FUNCTION: LEGO1 0x1000e0b0
MxBool IsSerializable() override { return FALSE; } // vtable+0x14
@ -20,7 +20,7 @@ class HelicopterState : public LegoState {
// FUNCTION: LEGO1 0x1000e0c0
MxBool Reset() override
{
m_unk0x08 = 0;
m_status = 0;
return TRUE;
} // vtable+0x18
@ -41,7 +41,14 @@ class HelicopterState : public LegoState {
// SYNTHETIC: LEGO1 0x1000e190
// HelicopterState::`scalar deleting destructor'
MxU32 m_unk0x08; // 0x08
// Status of the helicopter:
// 0: Landed
// 1: Taking off
// 2: In the air
// 3: Landing
// 4: Good ending
// 5: Bad ending
MxU32 m_status; // 0x08
};
// VTABLE: LEGO1 0x100d40f8
@ -76,8 +83,8 @@ class Helicopter : public IslePathActor {
void Exit() override; // vtable+0xe4
void CreateState();
void FUN_10004640(const Matrix4& p_matrix);
void FUN_10004670(const Matrix4& p_matrix);
void StartGoodEndingCamera(const Matrix4& p_matrix);
void StartBadEndingCamera(const Matrix4& p_matrix);
// SYNTHETIC: LEGO1 0x10003210
// Helicopter::`scalar deleting destructor'
@ -86,14 +93,14 @@ class Helicopter : public IslePathActor {
friend class Act3;
protected:
void FUN_100042a0(const Matrix4& p_matrix);
void SetupCameraTransition(const Matrix4& p_matrix);
MxMatrix m_unk0x160; // 0x160
MxMatrix m_unk0x1a8; // 0x1a8
float m_unk0x1f0; // 0x1f0
MxQuaternionTransformer m_unk0x1f4; // 0x1f4
HelicopterState* m_state; // 0x228
MxAtomId m_script; // 0x22c
MxMatrix m_cameraTransitionStartMatrix; // 0x160
MxMatrix m_cameraTransitionEndMatrix; // 0x1a8
float m_cameraTransitionTime; // 0x1f0
MxQuaternionTransformer m_cameraTransitionInterpolator; // 0x1f4
HelicopterState* m_state; // 0x228
MxAtomId m_script; // 0x22c
};
#endif // HELICOPTER_H

View File

@ -102,7 +102,7 @@ void Helicopter::Exit()
}
}
m_state->m_unk0x08 = 0;
m_state->m_status = 0;
RemoveFromCurrentWorld(m_script, IsleScript::c_HelicopterDashboard_Bitmap);
RemoveFromCurrentWorld(m_script, IsleScript::c_HelicopterArms_Ctl);
RemoveFromCurrentWorld(m_script, IsleScript::c_Helicopter_TakeOff_Ctl);
@ -198,7 +198,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param)
((Act3*) CurrentWorld())->SetDestLocation(LegoGameState::e_infomain);
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
}
else if (m_state->m_unk0x08 != 0) {
else if (m_state->m_status != 0) {
break;
}
@ -213,9 +213,9 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param)
Act1State* act1State = (Act1State*) GameState()->GetState("Act1State");
assert(act1State);
if (m_state->m_unk0x08 == 0) {
if (m_state->m_status == 0) {
act1State->m_state = Act1State::e_helicopter;
m_state->m_unk0x08 = 1;
m_state->m_status = 1;
m_world->RemoveActor(this);
InvokeAction(Extra::ActionType::e_start, script, IsleScript::c_HelicopterTakeOff_Anim, NULL);
SetActorState(c_initial);
@ -229,8 +229,8 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param)
break;
}
if (m_state->m_unk0x08 == 2) {
m_state->m_unk0x08 = 3;
if (m_state->m_status == 2) {
m_state->m_status = 3;
m_world->RemoveActor(this);
InvokeAction(Extra::ActionType::e_start, script, IsleScript::c_HelicopterLand_Anim, NULL);
SetActorState(c_disabled);
@ -261,11 +261,11 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param)
lookat *= 3.0f;
location += lookat;
Mx3DPointFloat v68, va4, up;
Mx3DPointFloat v90(0, 1, 0);
v68 = m_world->GetCameraController()->GetWorldUp();
va4.EqualsCross(v68, direction);
up.EqualsCross(va4, v90);
Mx3DPointFloat cameraUp, right, up;
Mx3DPointFloat worldUp(0, 1, 0);
cameraUp = m_world->GetCameraController()->GetWorldUp();
right.EqualsCross(cameraUp, direction);
up.EqualsCross(right, worldUp);
if (isPizza) {
if (((Act3*) m_world)->ShootPizza(m_pathController, location, direction, up) != SUCCESS) {
@ -313,7 +313,7 @@ MxLong Helicopter::HandleEndAnim(LegoEndAnimNotificationParam& p_param)
{
MxLong result = 0;
switch (m_state->m_unk0x08) {
switch (m_state->m_status) {
case 1: {
if (GameState()->GetCurrentAct() == LegoGameState::e_act1) {
Act1State* act1State = (Act1State*) GameState()->GetState("Act1State");
@ -333,7 +333,7 @@ MxLong Helicopter::HandleEndAnim(LegoEndAnimNotificationParam& p_param)
);
}
m_state->m_unk0x08 = 2;
m_state->m_status = 2;
MxMatrix matrix;
matrix.SetIdentity();
@ -374,7 +374,7 @@ MxLong Helicopter::HandleEndAnim(LegoEndAnimNotificationParam& p_param)
);
}
m_state->m_unk0x08 = 0;
m_state->m_status = 0;
result = 1;
break;
}
@ -402,34 +402,34 @@ void Helicopter::VTable0x74(Matrix4& p_transform)
// FUNCTION: LEGO1 0x10003ee0
void Helicopter::Animate(float p_time)
{
if (m_state->m_unk0x08 == 4 || m_state->m_unk0x08 == 5) {
float f = m_unk0x1f0 - p_time + 3000.0f;
if (f >= 0) {
float f2 = f / -3000.0f + 1;
if (f2 < 0) {
f2 = 0;
if (m_state->m_status == 4 || m_state->m_status == 5) {
float remainingTime = m_cameraTransitionTime - p_time + 3000.0f;
if (remainingTime >= 0) {
float interpolationFactor = remainingTime / -3000.0f + 1;
if (interpolationFactor < 0) {
interpolationFactor = 0;
}
if (f2 > 1.0f) {
f2 = 1.0f;
if (interpolationFactor > 1.0f) {
interpolationFactor = 1.0f;
}
MxMatrix mat;
Vector3 v1(m_unk0x160[3]);
Vector3 v2(mat[3]);
Vector3 v3(m_unk0x1a8[3]);
MxMatrix transform;
Vector3 startPosition(m_cameraTransitionStartMatrix[3]);
Vector3 interpolatedPosition(transform[3]);
Vector3 endPosition(m_cameraTransitionEndMatrix[3]);
mat.SetIdentity();
m_unk0x1f4.InterpolateToMatrix(mat, f2);
transform.SetIdentity();
m_cameraTransitionInterpolator.InterpolateToMatrix(transform, interpolationFactor);
v2 = v3;
v2 -= v1;
v2 *= f2;
v2 += v1;
interpolatedPosition = endPosition;
interpolatedPosition -= startPosition;
interpolatedPosition *= interpolationFactor;
interpolatedPosition += startPosition;
m_world->GetCameraController()->TransformPointOfView(mat, 0);
m_world->GetCameraController()->TransformPointOfView(transform, 0);
}
else {
if (m_state->m_unk0x08 == 4) {
if (m_state->m_status == 4) {
((Act3*) m_world)->FUN_10073400();
}
else {
@ -445,63 +445,63 @@ void Helicopter::Animate(float p_time)
}
// FUNCTION: LEGO1 0x100042a0
void Helicopter::FUN_100042a0(const Matrix4& p_matrix)
void Helicopter::SetupCameraTransition(const Matrix4& p_matrix)
{
MxMatrix local48;
MxMatrix local90;
MxMatrix startMatrix;
MxMatrix endMatrix;
Vector3 vec1(local48[3]); // local98 // esp+0x30
Vector3 vec2(local90[3]); // localac // esp+0x1c
Vector3 vec3(m_unk0x1a8[0]); // locala8 // esp+0x20
Vector3 vec4(m_unk0x1a8[1]); // localb8 // esp+0x10
Vector3 vec5(m_unk0x1a8[2]); // EDI
Vector3 startPos(startMatrix[3]); // local98 // esp+0x30
Vector3 endPos(endMatrix[3]); // localac // esp+0x1c
Vector3 endMatrixX(m_cameraTransitionEndMatrix[0]); // locala8 // esp+0x20
Vector3 endMatrixY(m_cameraTransitionEndMatrix[1]); // localb8 // esp+0x10
Vector3 endMatrixZ(m_cameraTransitionEndMatrix[2]); // EDI
// the typecast makes this function match for unknown reasons
Vector3 vec6((const float*) m_unk0x1a8[3]); // locala0 // esp+0x28
Vector3 endMatrixPos((const float*) m_cameraTransitionEndMatrix[3]); // locala0 // esp+0x28
m_world->GetCameraController()->GetPointOfView(local48);
m_unk0x1a8.SetIdentity();
local90 = p_matrix;
m_world->GetCameraController()->GetPointOfView(startMatrix);
m_cameraTransitionEndMatrix.SetIdentity();
endMatrix = p_matrix;
vec2[1] += 20.0f;
vec4 = vec2;
vec4 -= vec1;
vec4.Unitize();
endPos[1] += 20.0f;
endMatrixY = endPos;
endMatrixY -= startPos;
endMatrixY.Unitize();
vec5[0] = vec5[2] = 0.0f;
vec5[1] = -1.0f;
endMatrixZ[0] = endMatrixZ[2] = 0.0f;
endMatrixZ[1] = -1.0f;
vec3.EqualsCross(vec4, vec5);
vec3.Unitize();
vec4.EqualsCross(vec5, vec3);
vec6 = vec2;
endMatrixX.EqualsCross(endMatrixY, endMatrixZ);
endMatrixX.Unitize();
endMatrixY.EqualsCross(endMatrixZ, endMatrixX);
endMatrixPos = endPos;
local90 = m_unk0x1a8;
m_unk0x160 = local48;
endMatrix = m_cameraTransitionEndMatrix;
m_cameraTransitionStartMatrix = startMatrix;
vec1.Clear();
vec2.Clear();
startPos.Clear();
endPos.Clear();
m_unk0x1f0 = Timer()->GetTime();
m_cameraTransitionTime = Timer()->GetTime();
m_unk0x1f4.SetStartEnd(local48, local90);
m_unk0x1f4.NormalizeDirection();
m_cameraTransitionInterpolator.SetStartEnd(startMatrix, endMatrix);
m_cameraTransitionInterpolator.NormalizeDirection();
}
// FUNCTION: LEGO1 0x10004640
void Helicopter::FUN_10004640(const Matrix4& p_matrix)
void Helicopter::StartGoodEndingCamera(const Matrix4& p_matrix)
{
if (m_state->m_unk0x08 != 4 && m_state->m_unk0x08 != 5) {
m_state->m_unk0x08 = 4;
FUN_100042a0(p_matrix);
if (m_state->m_status != 4 && m_state->m_status != 5) {
m_state->m_status = 4;
SetupCameraTransition(p_matrix);
}
}
// FUNCTION: LEGO1 0x10004670
void Helicopter::FUN_10004670(const Matrix4& p_matrix)
void Helicopter::StartBadEndingCamera(const Matrix4& p_matrix)
{
if (m_state->m_unk0x08 != 4 && m_state->m_unk0x08 != 5) {
m_state->m_unk0x08 = 5;
FUN_100042a0(p_matrix);
if (m_state->m_status != 4 && m_state->m_status != 5) {
m_state->m_status = 5;
SetupCameraTransition(p_matrix);
}
}

View File

@ -650,7 +650,7 @@ MxLong Act3::Notify(MxParam& p_param)
m_state->m_state = Act3State::e_initial;
Disable(TRUE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
m_copter->HandleClick();
m_copter->m_state->m_unk0x08 = 1;
m_copter->m_state->m_status = 1;
m_copter->HandleEndAnim((LegoEndAnimNotificationParam&) param);
}
break;
@ -783,15 +783,15 @@ void Act3::GoodEnding(const Matrix4& p_destination)
#ifndef BETA10
m_unk0x4220.Clear();
m_copter->FUN_10004640(p_destination);
m_copter->StartGoodEndingCamera(p_destination);
DebugPrintf("In Good Ending...");
DebugCopter(
m_copter->GetROI()->GetLocal2World(),
p_destination,
m_copter->m_unk0x160,
m_copter->m_unk0x1a8,
m_copter->m_unk0x1f4
m_copter->m_cameraTransitionStartMatrix,
m_copter->m_cameraTransitionEndMatrix,
m_copter->m_cameraTransitionInterpolator
);
#else
m_state->m_state = Act3State::e_goodEnding;
@ -866,15 +866,15 @@ void Act3::BadEnding(const Matrix4& p_destination)
m_brickster->SetActorState(LegoPathActor::c_disabled);
m_unk0x4220.Clear();
m_copter->FUN_10004670(p_destination);
m_copter->StartBadEndingCamera(p_destination);
DebugPrintf("In Bad Ending...");
DebugCopter(
m_copter->GetROI()->GetLocal2World(),
p_destination,
m_copter->m_unk0x160,
m_copter->m_unk0x1a8,
m_copter->m_unk0x1f4
m_copter->m_cameraTransitionStartMatrix,
m_copter->m_cameraTransitionEndMatrix,
m_copter->m_cameraTransitionInterpolator
);
}