From 776ee9b9782e5406c2521270b9b659c83b705e2a Mon Sep 17 00:00:00 2001 From: TakaRikka Date: Thu, 11 Jun 2026 21:55:58 -0700 Subject: [PATCH] partially fix los exit portals --- include/d/actor/d_a_alink.h | 2 ++ src/d/actor/d_a_alink_demo.inc | 6 ++++ src/d/actor/d_a_alink_link.inc | 6 +++- src/d/actor/d_a_e_ai.cpp | 5 +++- src/d/actor/d_a_obj_bosswarp.cpp | 51 +++++++++++++++++++++++++++++++- 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/include/d/actor/d_a_alink.h b/include/d/actor/d_a_alink.h index fa75c085fb..889bed2a4f 100644 --- a/include/d/actor/d_a_alink.h +++ b/include/d/actor/d_a_alink.h @@ -4559,6 +4559,8 @@ public: void onIronBallChainInterpCallback(); + f32 mLosStickValue; + static const int IRON_BALL_CHAIN_COUNT = 102; cXyz mIBChainInterpPrevPos[IRON_BALL_CHAIN_COUNT]; cXyz mIBChainInterpCurrPos[IRON_BALL_CHAIN_COUNT]; diff --git a/src/d/actor/d_a_alink_demo.inc b/src/d/actor/d_a_alink_demo.inc index b1eb71a85d..f6d98fa351 100644 --- a/src/d/actor/d_a_alink_demo.inc +++ b/src/d/actor/d_a_alink_demo.inc @@ -737,6 +737,12 @@ void daAlink_c::setDemoData() { } else { mDemo.setStick(1.0f); } + +#if TARGET_PC + if (dusk::tphd::is_los_active() && mLosStickValue > 0.0f) { + mDemo.setStick(mLosStickValue); + } +#endif } if ((demo_mode == daPy_demo_c::DEMO_UNK_2_e || demo_mode == daPy_demo_c::DEMO_UNK_3_e) && prm1_p != NULL && *prm1_p == 1) { diff --git a/src/d/actor/d_a_alink_link.inc b/src/d/actor/d_a_alink_link.inc index 4d93f39457..c2320d3f73 100644 --- a/src/d/actor/d_a_alink_link.inc +++ b/src/d/actor/d_a_alink_link.inc @@ -425,4 +425,8 @@ daAlink_c::daAlink_c() mFaceBtkHeap(0x400), mFaceBckHeap(0xC00), mAnmHeap9(0x800) - {} +{ +#if TARGET_PC + mLosStickValue = -1.0f; +#endif +} diff --git a/src/d/actor/d_a_e_ai.cpp b/src/d/actor/d_a_e_ai.cpp index 251a026b88..c765b30b14 100644 --- a/src/d/actor/d_a_e_ai.cpp +++ b/src/d/actor/d_a_e_ai.cpp @@ -403,7 +403,10 @@ void e_ai_class::e_ai_damage() { if (m_timers[1] == 0) { m_sound.startCreatureSound(Z2SE_EN_AI_FLASH, 0, -1); mpEmitter = dComIfGp_particle_set(0x81ED, ¤t.pos, &tevStr, &shape_angle, NULL); - mpEmitter->becomeImmortalEmitter(); + if (mpEmitter != NULL) { + mpEmitter->becomeImmortalEmitter(); + } + m_timers[1] = 1000; m_timers[2] = 56; } diff --git a/src/d/actor/d_a_obj_bosswarp.cpp b/src/d/actor/d_a_obj_bosswarp.cpp index e286ce1640..dd544cc0cf 100644 --- a/src/d/actor/d_a_obj_bosswarp.cpp +++ b/src/d/actor/d_a_obj_bosswarp.cpp @@ -14,6 +14,9 @@ #include "d/actor/d_a_obj_ystone.h" #include +#include "d/actor/d_a_alink.h" +#include "dusk/tphd/LosTable.hpp" + static DUSK_CONST char* l_arcName = "ef_Portal"; static char const* l_clearEvName[9] = { @@ -101,7 +104,7 @@ int daObjBossWarp_c::Create() { } mBossClearMapToolId = 0xff; - if (!isFirst() || level == 8) { + if ((!isFirst() || level == 8) IF_DUSK(&& !dusk::tphd::is_los_active())) { mBossWarpInEventId = dComIfGp_getEventManager().getEventIdx(this, "BOSS_WARPIN", 0xff); mBossWarpInMapToolId = 0xff; mAction = 3; @@ -217,6 +220,31 @@ BOOL daObjBossWarp_c::checkDistance() { } int daObjBossWarp_c::execute() { +#if TARGET_PC + if (dusk::tphd::is_los_active()) { + u8 sw = getSwNo(); + if (sw == 0xff || fopAcM_isSwitch(this, sw)) { + if (mAction == ACT_WAIT) { + mAction = ACT_WAIT_WARP; + } + + set_appear(); + + if (!dComIfGp_evmng_checkStartDemo()) { + field_0x595 = true; + field_0x620 = current.pos; + } + + event_proc_call(); + + daMidna_c* midna = (daMidna_c*)daPy_py_c::getMidnaActor(); + if (field_0x595 && midna != NULL) { + midna->onTagWaitPos(&field_0x620); + } + } + } +#endif + if (dStage_stagInfo_GetSTType(dComIfGp_getStage()->getStagInfo()) != 3) { u8 sw = getSwNo(); if (sw == 0xff || fopAcM_isSwitch(this, sw)) { @@ -476,6 +504,14 @@ int daObjBossWarp_c::demoProc() { disappear(0); break; case 3: // SCENE_CHG + #if TARGET_PC + if (dusk::tphd::is_los_active()) { + // tphd sets some event flags here for bookkeeping, ignoring for now + daAlink_getAlinkActorClass()->mLosStickValue = -1.0f; + break; + } + #endif + int scene; if (isFirst()) { scene = getSceneListNo(); @@ -536,6 +572,11 @@ int daObjBossWarp_c::demoProc() { break; case 6: // WALK_TARGET1 dComIfGp_evmng_setGoal(¤t.pos); +#if TARGET_PC + if (dusk::tphd::is_los_active()) { + daAlink_getAlinkActorClass()->mLosStickValue = 1.0f; + } +#endif break; case 7: // APPEAR_END break; @@ -573,6 +614,14 @@ int daObjBossWarp_c::demoProc() { dComIfGp_evmng_cutEnd(mStaffId); break; case 3: // SCENE_CHG +#if TARGET_PC + if (dusk::tphd::is_los_active()) { + if (mCounter++ == 0) { + fopAcM_offDraw(this); + dComIfGp_event_remove(); + } + } +#endif break; case 4: // STONE_FALL if (ystone != NULL) {