From 5f8b0b881e5be69dc930d9074d04f39403f83661 Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 2 Jan 2026 01:55:47 +0100 Subject: [PATCH] One unattempted function remains --- .../SOUE01/rels/d_a_b_lastbossNP/symbols.txt | 77 +- config/SOUE01/symbols.txt | 20 +- include/d/a/b/d_a_b_lastboss.h | 117 +- include/d/a/e/d_a_en_base.h | 4 + include/d/d_camera.h | 2 + include/d/d_light_env.h | 8 +- include/d/d_player_act.h | 2 +- include/d/d_stage_mgr.h | 21 +- include/d/lyt/d_lyt_boss_caption.h | 28 + include/toBeSorted/d_d3d.h | 2 + src/REL/d/a/b/d_a_b_lastboss.cpp | 1002 ++++++++++++++--- src/REL/d/a/obj/d_a_obj_warp_hole.cpp | 2 +- 12 files changed, 1073 insertions(+), 212 deletions(-) create mode 100644 include/d/lyt/d_lyt_boss_caption.h diff --git a/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt b/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt index bc93a89d..0a839942 100644 --- a/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt +++ b/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt @@ -84,14 +84,14 @@ draw__14dAcBlastboss_cFv = .text:0x000073C0; // type:function size:0x60 checkForCloseRangeAttack__14dAcBlastboss_cFv = .text:0x00007420; // type:function size:0x17C checkForRangeAttack__14dAcBlastboss_cFv = .text:0x000075A0; // type:function size:0x218 checkForCounter__14dAcBlastboss_cFv = .text:0x000077C0; // type:function size:0x338 -fn_143_7B00__14dAcBlastboss_cFv = .text:0x00007B00; // type:function size:0x478 -fn_143_7F80__14dAcBlastboss_cFv = .text:0x00007F80; // type:function size:0x674 -fn_143_8600 = .text:0x00008600; // type:function size:0x860 -fn_143_8E60 = .text:0x00008E60; // type:function size:0x5B4 -fn_143_9420__14dAcBlastboss_cFv = .text:0x00009420; // type:function size:0x148 -fn_143_9570__14dAcBlastboss_cFl = .text:0x00009570; // type:function size:0x9C -fn_143_9610__14dAcBlastboss_cFv = .text:0x00009610; // type:function size:0xAF4 -fn_143_A110__14dAcBlastboss_cFl = .text:0x0000A110; // type:function size:0xBC +updateMainNodeTransforms__14dAcBlastboss_cFv = .text:0x00007B00; // type:function size:0x478 +updateSkirtHairTransforms__14dAcBlastboss_cFv = .text:0x00007F80; // type:function size:0x674 +updateSkirtTransform__14dAcBlastboss_cFl = .text:0x00008600; // type:function size:0x860 +updateHairTransform__14dAcBlastboss_cFl = .text:0x00008E60; // type:function size:0x5B4 +checkForLinkSwordBySwordHit__14dAcBlastboss_cFv = .text:0x00009420; // type:function size:0x148 +classifyAttackDirection__14dAcBlastboss_cFl = .text:0x00009570; // type:function size:0x9C +executeDemo__14dAcBlastboss_cFv = .text:0x00009610; // type:function size:0xAF4 +setLightningTimerMaybe__14dAcBlastboss_cFl = .text:0x0000A110; // type:function size:0xBC vt_0x88__11dAcEnBase_cFi = .text:0x0000A1D0; // type:function size:0x8 vt_0x84__11dAcEnBase_cFv = .text:0x0000A1E0; // type:function size:0x4 vt_0x80__11dAcEnBase_cFv = .text:0x0000A1F0; // type:function size:0x4 @@ -225,8 +225,42 @@ lbl_143_rodata_1C4 = .rodata:0x000001C4; // type:object size:0x4 align:4 data:fl lbl_143_rodata_1C8 = .rodata:0x000001C8; // type:object size:0x4 align:4 data:float lbl_143_rodata_1CC = .rodata:0x000001CC; // type:object size:0x4 align:4 data:float lbl_143_rodata_1D0 = .rodata:0x000001D0; // type:object size:0x4 align:4 data:float -lbl_143_rodata_1D4 = .rodata:0x000001D4; // type:object size:0x3C align:4 data:float -lbl_143_rodata_210 = .rodata:0x00000210; // type:object size:0x90 align:4 data:float +lbl_143_rodata_1D4 = .rodata:0x000001D4; // type:object size:0x4 align:4 data:float +lbl_143_rodata_1D8 = .rodata:0x000001D8; // type:object size:0x4 align:4 data:float +lbl_143_rodata_1E0 = .rodata:0x000001E0; // type:object size:0x10 +lbl_143_rodata_1F0 = .rodata:0x000001F0; // type:object size:0x10 +lbl_143_rodata_200 = .rodata:0x00000200; // type:object size:0x4 align:4 data:float +lbl_143_rodata_204 = .rodata:0x00000204; // type:object size:0x4 align:4 data:float +lbl_143_rodata_208 = .rodata:0x00000208; // type:object size:0x4 align:4 data:float +lbl_143_rodata_20C = .rodata:0x0000020C; // type:object size:0x4 align:4 data:float +lbl_143_rodata_210 = .rodata:0x00000210; // type:object size:0x4 align:4 data:float +lbl_143_rodata_214 = .rodata:0x00000214; // type:object size:0x24 align:4 data:float +lbl_143_rodata_238 = .rodata:0x00000238; // type:object size:0x4 align:4 data:float +lbl_143_rodata_23C = .rodata:0x0000023C; // type:object size:0x4 align:4 data:float +lbl_143_rodata_240 = .rodata:0x00000240; // type:object size:0x4 align:4 data:float +lbl_143_rodata_244 = .rodata:0x00000244; // type:object size:0x4 align:4 data:float +lbl_143_rodata_248 = .rodata:0x00000248; // type:object size:0x4 align:4 data:float +lbl_143_rodata_24C = .rodata:0x0000024C; // type:object size:0x4 align:4 data:float +lbl_143_rodata_250 = .rodata:0x00000250; // type:object size:0x4 align:4 data:float +lbl_143_rodata_254 = .rodata:0x00000254; // type:object size:0x4 align:4 data:float +lbl_143_rodata_258 = .rodata:0x00000258; // type:object size:0x4 align:4 data:float +lbl_143_rodata_25C = .rodata:0x0000025C; // type:object size:0x4 +lbl_143_rodata_260 = .rodata:0x00000260; // type:object size:0x4 +lbl_143_rodata_264 = .rodata:0x00000264; // type:object size:0x4 +lbl_143_rodata_268 = .rodata:0x00000268; // type:object size:0x4 +lbl_143_rodata_26C = .rodata:0x0000026C; // type:object size:0x4 +lbl_143_rodata_270 = .rodata:0x00000270; // type:object size:0x4 +lbl_143_rodata_274 = .rodata:0x00000274; // type:object size:0x4 +lbl_143_rodata_278 = .rodata:0x00000278; // type:object size:0x4 align:4 data:float +lbl_143_rodata_27C = .rodata:0x0000027C; // type:object size:0x4 +lbl_143_rodata_280 = .rodata:0x00000280; // type:object size:0x4 +lbl_143_rodata_284 = .rodata:0x00000284; // type:object size:0x4 +lbl_143_rodata_288 = .rodata:0x00000288; // type:object size:0x4 +lbl_143_rodata_28C = .rodata:0x0000028C; // type:object size:0x4 +lbl_143_rodata_290 = .rodata:0x00000290; // type:object size:0x4 +lbl_143_rodata_294 = .rodata:0x00000294; // type:object size:0x4 +lbl_143_rodata_298 = .rodata:0x00000298; // type:object size:0x4 +lbl_143_rodata_29C = .rodata:0x0000029C; // type:object size:0x4 g_profile_B_LASTBOSS = .data:0x00000000; // type:object size:0x10 data:4byte sSrcCyl1 = .data:0x00000010; // type:object size:0x30 sSrcCyl2 = .data:0x00000040; // type:object size:0x30 @@ -308,17 +342,30 @@ lbl_143_data_4A4 = .data:0x000004A4; // type:object size:0x4 lbl_143_data_4A8 = .data:0x000004A8; // type:object size:0xC lbl_143_data_4B4 = .data:0x000004B4; // type:object size:0xC lbl_143_data_4C0 = .data:0x000004C0; // type:object size:0x4 data:4byte -lbl_143_data_4C4 = .data:0x000004C4; // type:object size:0x5C data:4byte -__vt__14dAcBlastboss_c = .data:0x00000520; // type:object size:0x90 +lbl_143_data_4C4 = .data:0x000004C4; // type:object size:0x4 data:4byte +lbl_143_data_4C8 = .data:0x000004C8; // type:object size:0x4 data:4byte +lbl_143_data_4CC = .data:0x000004CC; // type:object size:0x4 data:4byte +lbl_143_data_4D0 = .data:0x000004D0; // type:object size:0x4 +lbl_143_data_4D4 = .data:0x000004D4; // type:object size:0x4 +lbl_143_data_4D8 = .data:0x000004D8; // type:object size:0x4 +lbl_143_data_4DC = .data:0x000004DC; // type:object size:0x4 +lbl_143_data_4E0 = .data:0x000004E0; // type:object size:0x4 +lbl_143_data_4E4 = .data:0x000004E4; // type:object size:0x4 +lbl_143_data_4E8 = .data:0x000004E8; // type:object size:0x4 +lbl_143_data_4EC = .data:0x000004EC; // type:object size:0xA data:string +lbl_143_data_4F8 = .data:0x000004F8; // type:object size:0x8 data:string +lbl_143_data_500 = .data:0x00000500; // type:object size:0xA data:string +lbl_143_data_510 = .data:0x00000510; // type:object size:0x10 data:string +__vt__14dAcBlastboss_c = .data:0x00000520; // type:object size:0x8C __vt__53sFStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c> = .data:0x000005B0; // type:object size:0x30 __vt__83sStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x000005E0; // type:object size:0x30 -__vt__30sFStateFct_c<14dAcBlastboss_c> = .data:0x00000610; // type:object size:0x18 +__vt__30sFStateFct_c<14dAcBlastboss_c> = .data:0x00000610; // type:object size:0x14 __vt__27sFState_c<14dAcBlastboss_c> = .data:0x00000628; // type:object size:0x18 __vt__15dCcD_Linked_Cyl = .data:0x00000640; // type:object size:0x70 __vt__Q214dAcBlastboss_c10callback_c = .data:0x000006B0; // type:object size:0x18 __vt__15dCcD_Linked_Sph = .data:0x000006C8; // type:object size:0x70 -__vt__16dEnemySwordMdl_c = .data:0x00000738; // type:object size:0x10 -lbl_143_data_748 = .data:0x00000748; // type:object size:0x70 +__vt__16dEnemySwordMdl_c = .data:0x00000738; // type:object size:0xC +__vt__15dCcD_Linked_Cps = .data:0x00000748; // type:object size:0x70 __vt__26dSwordSwingEffectProcMgr_c = .data:0x000007B8; // type:object size:0xC __vt__Q34nw4r3g3d15IScnObjCallback = .data:0x000007C8; // type:object size:0x20 lbl_143_data_7E8 = .data:0x000007E8; // type:object size:0x3E0 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index c30b856b..e86041fb 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -600,7 +600,7 @@ remove__Q23d3d12UnkWithWaterFv = .text:0x800190B0; // type:function size:0xB8 apply__Q23d3d16UnkWithWaterNodeFPC9_GXTexObj = .text:0x80019170; // type:function size:0x74 entry__Q23d3d14EggTextureProcFv = .text:0x800191F0; // type:function size:0x9C fn_80019290 = .text:0x80019290; // type:function size:0x5C -fn_800192F0 = .text:0x800192F0; // type:function size:0x6C +fn_800192F0__Q23d3d14EggTextureProcFUcRC6mMtx_cUc = .text:0x800192F0; // type:function size:0x6C doDraw__Q23d3d14EggTextureProcFv = .text:0x80019360; // type:function size:0x204 doRemove__Q23d3d14EggTextureProcFv = .text:0x80019570; // type:function size:0x44 create__Q23d3d7UnkProcFiiP12mAllocator_c = .text:0x800195C0; // type:function size:0xAC @@ -1147,9 +1147,9 @@ createActorUnkGroup3__12dAcObjBase_cFQ28fProfile14PROFILE_NAME_eUlUlP7mVec3_cP7m createActorUnkGroup3__12dAcObjBase_cFPCcUlUlPC7mVec3_cPC7mAng3_cPC7mVec3_cUlUsSc = .text:0x8002F260; // type:function size:0xA0 __ct__11dAcEnBase_cFv = .text:0x8002F300; // type:function size:0x74 __dt__11dAcEnBase_cFv = .text:0x8002F380; // type:function size:0x74 -ActorEnemyBase__shouldUpdateMaybe = .text:0x8002F400; // type:function size:0xB4 -ActorEnemyBase__postUpdate = .text:0x8002F4C0; // type:function size:0x7C -ActorEnemyBase__preDraw = .text:0x8002F540; // type:function size:0x74 +preExecute__11dAcEnBase_cFv = .text:0x8002F400; // type:function size:0xB4 +postExecute__11dAcEnBase_cFQ27fBase_c12MAIN_STATE_e = .text:0x8002F4C0; // type:function size:0x7C +preDraw__11dAcEnBase_cFv = .text:0x8002F540; // type:function size:0x74 fn_8002F5C0 = .text:0x8002F5C0; // type:function size:0x110 checkBeetleActorReferences__17daPlayerActBase_cFl = .text:0x8002F6D0; // type:function size:0x8 getBeetleActorReferencesSize__17daPlayerActBase_cFv = .text:0x8002F6E0; // type:function size:0x8 @@ -1290,7 +1290,7 @@ ActorLink__setObjActorFlags0x200 = .text:0x800346B0; // type:function size:0x14 ActorLink__unsetObjActorFlags0x200 = .text:0x800346D0; // type:function size:0x14 fn_800346F0 = .text:0x800346F0; // type:function size:0xDC vt_0x2AC__17daPlayerActBase_cFv = .text:0x800347D0; // type:function size:0x4 -triggerMoveEventMaybe__17daPlayerActBase_cFUlUlUlR7mVec3_cRC4mAngUlUl = .text:0x800347E0; // type:function size:0x4 +triggerMoveEventMaybe__17daPlayerActBase_cFUlUlUlPC7mVec3_cRC4mAngUlUl = .text:0x800347E0; // type:function size:0x4 vt_0x2C4__17daPlayerActBase_cFv = .text:0x800347F0; // type:function size:0x8 fn_80034800 = .text:0x80034800; // type:function size:0x170 fn_80034970 = .text:0x80034970; // type:function size:0xFC @@ -10737,8 +10737,8 @@ fn_8019E890 = .text:0x8019E890; // type:function size:0x40 fn_8019E8D0 = .text:0x8019E8D0; // type:function size:0x54 fn_8019E930 = .text:0x8019E930; // type:function size:0xC fn_8019E940 = .text:0x8019E940; // type:function size:0xC0 -fn_8019EA00 = .text:0x8019EA00; // type:function size:0x70 -fn_8019EA70 = .text:0x8019EA70; // type:function size:0x11C +fn_8019EA00__9dCamera_cFRC7mVec3_cRC7mVec3_cff = .text:0x8019EA00; // type:function size:0x70 +fn_8019EA70__9dCamera_cFb = .text:0x8019EA70; // type:function size:0x11C fn_8019EB90 = .text:0x8019EB90; // type:function size:0xC fn_8019EBA0 = .text:0x8019EBA0; // type:function size:0x160 fn_8019ED00 = .text:0x8019ED00; // type:function size:0xC @@ -15768,7 +15768,7 @@ fn_8029FE90 = .text:0x8029FE90; // type:function size:0x21C fn_802A00B0 = .text:0x802A00B0; // type:function size:0x10 fn_802A00C0 = .text:0x802A00C0; // type:function size:0x10 fn_802A00D0 = .text:0x802A00D0; // type:function size:0x40 -showBossCaption = .text:0x802A0110; // type:function size:0x158 +show__17dLytBossCaption_cFPCci = .text:0x802A0110; // type:function size:0x158 fn_802A0270 = .text:0x802A0270; // type:function size:0x9C fn_802A0310 = .text:0x802A0310; // type:function size:0x9C fn_802A03B0 = .text:0x802A03B0; // type:function size:0x4C @@ -17264,7 +17264,7 @@ ModuleDestructorsX = .text:0x802DFD30; // type:function size:0x44 cLib__memSet = .text:0x802DFD80; // type:function size:0x4 addCalcPos__4cLibFP7mVec3_cRC7mVec3_cfff = .text:0x802DFD90; // type:function size:0x234 addCalcPosXZ__4cLibFP7mVec3_cRC7mVec3_cfff = .text:0x802DFFD0; // type:function size:0x1B8 -cLib__addCalcPos2 = .text:0x802E0190; // type:function size:0x13C +addCalcPos2__4cLibFP7mVec3_cRC7mVec3_cff = .text:0x802E0190; // type:function size:0x13C cLib__addCalcPosXZ2 = .text:0x802E02D0; // type:function size:0xF8 cLib__chasePos = .text:0x802E03D0; // type:function size:0x174 chasePosXZ__4cLibFR7mVec3_cR7mVec3_cf = .text:0x802E0550; // type:function size:0x124 @@ -42586,7 +42586,7 @@ sInstance__21dLytMiniGameScoreSd_c = .sbss:0x80575984; // type:object size:0x4 d sInstance__14dLytMiniGame_c = .sbss:0x80575988; // type:object size:0x8 data:4byte lbl_80575990 = .sbss:0x80575990; // type:object size:0x8 data:4byte lbl_80575998 = .sbss:0x80575998; // type:object size:0x8 data:4byte -BOSS_CAPTION_PTR = .sbss:0x805759A0; // type:object size:0x8 data:4byte +sInstance__17dLytBossCaption_c = .sbss:0x805759A0; // type:object size:0x8 data:4byte sInstance__17dLytDemoDowsing_c = .sbss:0x805759A8; // type:object size:0x8 data:4byte lbl_805759B0 = .sbss:0x805759B0; // type:object size:0x2 data:2byte sInstance__10dLytShop_c = .sbss:0x805759B4; // type:object size:0x4 data:4byte diff --git a/include/d/a/b/d_a_b_lastboss.h b/include/d/a/b/d_a_b_lastboss.h index f38ace6c..2a82df80 100644 --- a/include/d/a/b/d_a_b_lastboss.h +++ b/include/d/a/b/d_a_b_lastboss.h @@ -19,7 +19,10 @@ class dTgSwordBattleGame_c; // TODO this might be a template but what about the offset? struct UnkLastBossCcSph1 { - /* 0x000 */ u8 _0x000[0x008 - 0x000]; + /* 0x000 */ u8 _0x000[0x002 - 0x000]; + /* 0x002 */ s16 field_0x002; + /* 0x004 */ s16 field_0x004; + /* 0x006 */ s16 field_0x006; /* 0x008 */ mVec3_c field_0x008[5]; /* 0x044 */ mVec3_c field_0x044[5]; /* 0x080 */ mVec3_c field_0x080[5]; @@ -29,9 +32,12 @@ struct UnkLastBossCcSph1 { struct UnkLastBossCcSph2 { /* 0x000 */ s16 field_0x000; /* 0x002 */ s16 field_0x002; - /* 0x004 */ u8 _0x004[0x008 - 0x004]; + /* 0x004 */ s16 field_0x004; + /* 0x006 */ s16 field_0x006; /* 0x008 */ s16 field_0x008; - /* 0x00A */ u8 _0x00A[0x014 - 0x00A]; + /* 0x00A */ s16 field_0x00A; + /* 0x00C */ f32 field_0x00C; + /* 0x010 */ f32 field_0x010; /* 0x014 */ mVec3_c field_0x014[10]; /* 0x08C */ mVec3_c field_0x08C[10]; /* 0x104 */ mVec3_c field_0x104[10]; @@ -219,6 +225,8 @@ class dAcBlastboss_c : public dAcEnBase_c { SUB_STATE_20 = 20, SUB_STATE_21, + + SUB_STATE_50 = 50, }; enum Timer_e { @@ -232,6 +240,38 @@ class dAcBlastboss_c : public dAcEnBase_c { TIMER_MAX, }; + // TODO: Maybe reused in other sword fight bosses? + // Names taken from the string array + enum GuardDirection_e { + GUARD_RIGHT, + GUARD_UPRIGHT, + GUARD_DOWNRIGHT, + GUARD_LEFT, + GUARD_UPLEFT, + GUARD_DOWNLEFT, + GUARD_UP, + GUARD_DOWN, + GUARD_CENTER, + GUARD_BT, // not sure + }; + + enum DemoState_e { + DEMO_STATE_NONE = 0, + + DEMO_STATE_1 = 1, + DEMO_STATE_2, + DEMO_STATE_3, + + DEMO_STATE_100 = 100, + DEMO_STATE_101, + + DEMO_STATE_200 = 200, + DEMO_STATE_201, + DEMO_STATE_2XX_LAST = 299, + + DEMO_STATE_1000 = 1000, + }; + public: dAcBlastboss_c() : mStateMgr(*this, sStateID::null), mScnCallback(this) {} virtual ~dAcBlastboss_c() {} @@ -266,12 +306,14 @@ private: bool checkForCloseRangeAttack(); bool checkForRangeAttack(); bool checkForCounter(); - void fn_143_7B00(); - void fn_143_7F80(); - bool fn_143_9420(); - u8 fn_143_9570(s32 dir); - void fn_143_9610(); - void fn_143_A110(s32); + void updateMainNodeTransforms(); + void updateSkirtHairTransforms(); + void updateSkirtTransform(s32 level); + void updateHairTransform(s32 level); + bool checkForLinkSwordBySwordHit(); + u8 classifyAttackDirection(s32 attackDir); + void executeDemo(); + void setLightningTimerMaybe(s32); /* 0x0378 */ d3d::AnmMdlWrapper mMdl; /* 0x03E8 */ m3d::anmTexSrt_c mAnmTexSrt; @@ -293,8 +335,8 @@ private: /* 0x1132 */ u8 field_0x1132; /* 0x1133 */ u8 field_0x1133; /* 0x1134 */ u8 field_0x1134; - /* 0x1135 */ s8 field_0x1135; - /* 0x1136 */ s8 field_0x1136; + /* 0x1135 */ s8 mNumConsecutiveOppositeDirectionAttacks; + /* 0x1136 */ s8 mNumConsecutiveSameDirectionAttacks; /* 0x1137 */ u8 field_0x1137; /* 0x1138 */ u8 field_0x1138; /* 0x1139 */ u8 field_0x1139; @@ -307,8 +349,8 @@ private: /* 0x1140 */ u8 field_0x1140; /* 0x1141 */ u8 field_0x1141; /* 0x1142 */ u8 field_0x1142; - /* 0x1143 */ u8 field_0x1143; - /* 0x1144 */ s8 field_0x1144; + /* 0x1143 */ u8 mInvulnerabilityTimerMaybe; + /* 0x1144 */ s8 mGuardDirection; /* 0x1145 */ s8 mLinkCloseRangeShieldTime; /* 0x1146 */ bool mIsSwordEmpowered; /* 0x1147 */ u8 field_0x1147; @@ -322,21 +364,23 @@ private: /* 0x114F */ u8 field_0x114F; /* 0x1150 */ u8 field_0x1150; /* 0x1152 */ u16 field_0x1152; - /* 0x1154 */ u16 field_0x1154; + /* 0x1154 */ u16 mStunCounter; /* 0x1156 */ u16 mTimers[TIMER_MAX]; /* 0x1162 */ u16 field_0x1162; - /* 0x1164 */ s16 field_0x1164; + /* 0x1164 */ s16 mCounter; /* 0x1166 */ s16 mSubState; /* 0x1168 */ u8 _0x1168[0x116A - 0x1168]; /* 0x116A */ s16 mYAngleToLink; - /* 0x116C */ u8 _0x116C[0x1172 - 0x116C]; + /* 0x116C */ u8 _0x116C[0x1170 - 0x116C]; + /* 0x1170 */ s16 field_0x1170; /* 0x1172 */ s16 field_0x1172; + /* 0x1174 */ s16 field_0x1174; - /* 0x1174 */ u8 _0x1174[0x1178 - 0x1174]; + /* 0x1176 */ u8 _0x1176[0x1178 - 0x1176]; /* 0x1178 */ s16 field_0x1178; /* 0x117A */ s16 field_0x117A; @@ -344,7 +388,7 @@ private: /* 0x117E */ s16 field_0x117E; /* 0x1180 */ s16 field_0x1180; /* 0x1182 */ s16 field_0x1182; - /* 0x1184 */ s16 field_0x1184; + /* 0x1184 */ s16 mLightningTimerMaybe; /* 0x1186 */ s16 mYRotationRelativeToLink; /* 0x1188 */ s16 field_0x1188; /* 0x118A */ mAng field_0x118A; @@ -360,36 +404,24 @@ private: /* 0x11A0 */ f32 field_0x11A0; /* 0x11A4 */ f32 field_0x11A4; /* 0x11A8 */ f32 mAnmRate; - - /* 0x11AC */ u8 _0x11AC[0x11B0 - 0x11AC]; - + /* 0x11AC */ f32 field_0x11AC; /* 0x11B0 */ f32 field_0x11B0; - - /* 0x11B4 */ u8 _0x11B4[0x11B8 - 0x11B4]; - + /* 0x11B0 */ f32 field_0x11B4; /* 0x11B8 */ f32 field_0x11B8; - /* 0x11BC */ f32 field_0x11BC; /* 0x11C0 */ f32 field_0x11C0; - - /* 0x11C4 */ u8 _0x11C4[0x11C8 - 0x11C4]; - - /* 0x11CC */ f32 field_0x11C8; + /* 0x11C4 */ f32 field_0x11C4; + /* 0x11C8 */ f32 field_0x11C8; /* 0x11CC */ f32 field_0x11CC; - - /* 0x11D0 */ u8 _0x11D0[0x11D4 - 0x11D0]; - + /* 0x11D0 */ f32 field_0x11D0; /* 0x11D4 */ s32 mLastAttackDir; - /* 0x11D8 */ s32 field_0x11D8; - + /* 0x11D8 */ s32 mSecondLastAttackDirection; /* 0x11DC */ mAng3_c field_0x11DC; /* 0x11E4 */ mVec3_c mThumbL2Translation; /* 0x11F0 */ mVec3_c mBackbone1Translation; /* 0x11FC */ mVec3_c mChestTranslation; /* 0x1208 */ mVec3_c field_0x1208; - - /* 0x1214 */ u8 _0x1214[0x1220 - 0x1214]; - + /* 0x1214 */ mVec3_c mBugNetPos; /* 0x1220 */ mVec3_c field_0x1220; /* 0x122C */ mVec3_c field_0x122C; /* 0x1238 */ mVec3_c mToeTranslation[2]; @@ -406,10 +438,15 @@ private: /* 0x2C68 */ dEmitter_c mEmitter6; /* 0x2C9C */ dEmitter_c mEmitter7; /* 0x2CD0 */ LIGHT_INFLUENCE mLightInfo; - /* 0x2CEC */ s16 field_0x2CEC; - /* 0x2CEE */ u8 _0x2CEE[0x2D00 - 0x2CEE]; + /* 0x2CEC */ s16 mDemoState; + /* 0x2CEE */ s16 field_0x2CEE; + /* 0x2CF0 */ s16 field_0x2CF0; + /* 0x2CF4 */ f32 field_0x2CF4; + /* 0x2CF8 */ u8 _0x2CF8[0x2CFC - 0x2CF8]; + /* 0x2CFC */ f32 field_0x2CFC; /* 0x2D00 */ f32 field_0x2D00; - /* 0x2D04 */ u8 _0x2D04[0x2D1C - 0x2D04]; + /* 0x2D04 */ mVec3_c field_0x2D04; + /* 0x2D10 */ mVec3_c field_0x2D10; /* 0x2D1C */ const char *mpCurrentAnm; /* 0x2D20 */ dTgSwordBattleGame_c *mpSwordBattleGame; }; diff --git a/include/d/a/e/d_a_en_base.h b/include/d/a/e/d_a_en_base.h index 03b22e45..328992a1 100644 --- a/include/d/a/e/d_a_en_base.h +++ b/include/d/a/e/d_a_en_base.h @@ -28,6 +28,10 @@ public: dAcEnBase_c(); virtual ~dAcEnBase_c(); + virtual int preExecute() override; + virtual void postExecute(MAIN_STATE_e state) override; + virtual int preDraw() override; + virtual void *getObjectListEntry() override { return &mEnemyLink; } diff --git a/include/d/d_camera.h b/include/d/d_camera.h index 8f4560a0..059647ba 100644 --- a/include/d/d_camera.h +++ b/include/d/d_camera.h @@ -61,9 +61,11 @@ public: bool isUnderwater() const; f32 getUnderwaterDepth() const; + void fn_8019EA00(const mVec3_c&, const mVec3_c&, f32, f32); void fn_8019E430(); void fn_8019E410(); mAng fn_8019E3B0() const; + void fn_8019EA70(bool); private: /* 0x068 */ u8 _0x068[0x6C - 0x068]; diff --git a/include/d/d_light_env.h b/include/d/d_light_env.h index 975b56a2..5e48e39e 100644 --- a/include/d/d_light_env.h +++ b/include/d/d_light_env.h @@ -442,6 +442,10 @@ public: field_0x38DC = v; } + void setField_0x5D48(f32 val) { + field_0x5D48 = val; + } + private: /* 0x0004 */ Spf currentSpf; /* 0x020C */ Spf spfs[20]; @@ -499,7 +503,9 @@ private: /* 0x48E4 */ Bpm4 field_0x48E4; /* 0x5CE4 */ PaletteDefaultMCF field_0x5CE4; /* 0x5D04 */ TwoPaletteDefaultMCF field_0x5D04; - /* 0x5D44 */ u8 field_0x5D44[0x5D59 - 0x5D44]; + /* 0x5D44 */ u8 field_0x5D44[0x5D48 - 0x5D44]; + /* 0x5D48 */ f32 field_0x5D48; + /* 0x5D4C */ u8 field_0x5D4C[0x5D59 - 0x5D4C]; /* 0x5D59 */ struct { // Anonymous until more is known bool mEnabled; u8 mValue; diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index 621b3cc2..4d3b9dc2 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -413,7 +413,7 @@ public: /* vt 0x2A8 */ virtual void lookTowardItem() {} /* vt 0x2AC */ virtual void vt_0x2AC() {} /* vt 0x2B0 */ virtual void vt_0x2B0() {} - /* vt 0x2B4 */ virtual void triggerMoveEventMaybe(u32, u32, u32, mVec3_c &, const mAng &, u32, u32) {} + /* vt 0x2B4 */ virtual void triggerMoveEventMaybe(u32, u32, u32, const mVec3_c *, const mAng&, u32, u32) {} /* vt 0x2B8 */ virtual void setActorRef9() {} /* vt 0x2BC */ virtual void unlinkActorRef9() {} /* vt 0x2C0 */ virtual bool vt_0x2C0() { diff --git a/include/d/d_stage_mgr.h b/include/d/d_stage_mgr.h index 65293fcc..f20c541d 100644 --- a/include/d/d_stage_mgr.h +++ b/include/d/d_stage_mgr.h @@ -5,6 +5,7 @@ #include "d/col/cc/d_cc_s.h" #include "d/d_base.h" #include "d/d_bzs_types.h" +#include "d/d_cursor_hit_check.h" #include "d/d_dylink.h" #include "d/d_fader.h" #include "egg/gfx/eggCpuTexture.h" @@ -12,6 +13,7 @@ #include "m/m_allocator.h" #include "m/m_dvd.h" #include "m/m_fader_base.h" +#include "m/m_mtx.h" #include "nw4r/g3d/g3d_camera.h" #include "s/s_FPhase.h" #include "s/s_State.hpp" @@ -103,6 +105,9 @@ public: s32 getMapNameId() const; bool fn_80199250(); + void procfn_800192F0(u8 a1, const mMtx_c &mtx, u8 a2) { + mProc1.fn_800192F0(a1, mtx, a2); + } static dStageMgr_c *GetInstance() { return sInstance; @@ -204,11 +209,19 @@ private: /* 0x0580 */ LayoutArcControl mLayoutArcCtrl2; /* 0x058C */ dBgS mBg; // ... - u8 _0x00001[0x778]; + u8 _0x00001[0x6C8]; + + /* 0x3E38 */ // ... + /* 0x3E40 */ dCcS mCc; + + /* 0x75D8 */ dCursorHitCheckCC_c mCsHitCheck; // ... /* 0x7814 */ dParticle::tex_c mParticleTex[2]; - // ... + /* 0x7898 */ d3d::EggTextureProc mProc1; + /* 0x78EC */ d3d::XluProc mProc2; + u8 _0x00002[0x28]; + /* 0x790C */ // ... /* 0x7930 */ dFader_c mFader; /* 0x7954 */ u16 mPcamCount; @@ -220,6 +233,8 @@ private: /* 0x7964 */ const STIF *mpStif; /* 0x7968 */ const RMPL *mpRmpl; + u8 _0x00003[0x30]; + /* 0x799C */ mDvd_callback_c *mpDvdCallback; /* 0x79A0 */ mDvd_callback_c *mpDvdCallback2; @@ -229,7 +244,7 @@ private: /* 0x8694 */ dTimeAreaMgr_c mTimeAreaMgr; // ... - u8 ___[438]; + u8 ___[390]; /* 0x8898 */ EGG::CpuTexture *field_0x8898; u8 _0x889C[4]; diff --git a/include/d/lyt/d_lyt_boss_caption.h b/include/d/lyt/d_lyt_boss_caption.h new file mode 100644 index 00000000..65436c12 --- /dev/null +++ b/include/d/lyt/d_lyt_boss_caption.h @@ -0,0 +1,28 @@ +#ifndef D_LYT_BOSS_CAPTION_H +#define D_LYT_BOSS_CAPTION_H + +#include "common.h" + +class dLytBossCaption_c { +public: + static dLytBossCaption_c *GetInstance() { + return sInstance; + } + + void show(const char *label, UNKWORD); + + // I believe this is the inline that causes all the Rev0 -> Rev1 pain in RELs... + void unk_inline() { + field_0x645 = 0; + field_0x646 = 0; + } + +private: + static dLytBossCaption_c *sInstance; + + u8 _0x00[0x645 - 0x00]; + u8 field_0x645; + u8 field_0x646; +}; + +#endif diff --git a/include/toBeSorted/d_d3d.h b/include/toBeSorted/d_d3d.h index ebfeafd2..e565ddf2 100644 --- a/include/toBeSorted/d_d3d.h +++ b/include/toBeSorted/d_d3d.h @@ -203,6 +203,8 @@ public: doDraw(); } + void fn_800192F0(u8, const mMtx_c&, u8); + private: void doRemove(); void doDraw(); diff --git a/src/REL/d/a/b/d_a_b_lastboss.cpp b/src/REL/d/a/b/d_a_b_lastboss.cpp index 6d614d1f..2ac38087 100644 --- a/src/REL/d/a/b/d_a_b_lastboss.cpp +++ b/src/REL/d/a/b/d_a_b_lastboss.cpp @@ -8,13 +8,17 @@ #include "d/col/c/c_cc_d.h" #include "d/col/cc/d_cc_s.h" #include "d/d_base.h" +#include "d/d_camera.h" #include "d/d_cc.h" #include "d/d_light_env.h" #include "d/d_player_act.h" #include "d/d_rumble.h" #include "d/d_sc_game.h" +#include "d/d_stage.h" #include "d/d_stage_mgr.h" #include "d/flag/sceneflag_manager.h" +#include "d/flag/storyflag_manager.h" +#include "d/lyt/d_lyt_boss_caption.h" #include "d/snd/d_snd_bgm_mgr.h" #include "d/snd/d_snd_wzsound.h" #include "d/t/d_t_sword_battle_game.h" @@ -27,8 +31,12 @@ #include "m/m_vec.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/math/math_arithmetic.h" +#include "rvl/MTX/mtxvec.h" #include "s/s_Math.h" #include "toBeSorted/d_emitter.h" +#include "toBeSorted/event.h" +#include "toBeSorted/event_manager.h" #include "toBeSorted/minigame_mgr.h" SPECIAL_ACTOR_PROFILE(B_LASTBOSS, dAcBlastboss_c, fProfile::B_LASTBOSS, 0xBA, 0, 0); @@ -207,12 +215,12 @@ int dAcBlastboss_c::create() { mStateMgr.changeState(StateID_Fight); field_0x1132 = 1; - field_0x1164 = cM::rndF(65536.0f); + mCounter = cM::rndF(65536.0f); mHealth = 400; mPositionCopy3 = mPosition; - mLastAttackDir = field_0x11D8 = -1; + mLastAttackDir = mSecondLastAttackDirection = -1; mWaterEmitter.init(this); mEmitter2.init(this); @@ -225,18 +233,18 @@ int dAcBlastboss_c::create() { mLightInfo.SetPosition(mPosition); mLightInfo.mClr.Set(100, 150, 255, 255); dLightEnv_c::GetPInstance()->plight_set(&mLightInfo); - fn_143_A110(100); + setLightningTimerMaybe(100); if (!field_0x114D) { - field_0x2CEC = 200; + mDemoState = DEMO_STATE_200; setActorProperty(AC_PROP_0x4); } return SUCCEEDED; } -// TODO -extern "C" const s16 notsure[] = {0xA000, 0xC000, 0xE000, 0xF000, 0x0000, 0x1000, 0x2000, 0x4000}; +// why are these up here? +static const s16 moreAngs[] = {0xA000, 0xC000, 0xE000, 0xF000, 0x0000, 0x1000, 0x2000, 0x4000}; int dAcBlastboss_c::doDelete() { dLightEnv_c::GetPInstance()->plight_cut(&mLightInfo); @@ -251,7 +259,7 @@ int dAcBlastboss_c::actorExecute() { } dAcPy_c *link = dAcPy_c::GetLinkM(); - field_0x1164++; + mCounter++; field_0x1133 = 0; field_0x1131 = 0; @@ -335,7 +343,7 @@ int dAcBlastboss_c::actorExecute() { field_0x1140 = 1; } - fn_143_7B00(); + updateMainNodeTransforms(); mWorldMtx.transS(mPosition); mWorldMtx.ZXYrotM(mRotation); @@ -362,8 +370,7 @@ int dAcBlastboss_c::actorExecute() { mSwordMdl.calc(nodeMtx, mRotation.y, false); vEff.set(0.0f, -120.0f, 0.0f); - // TODO number - if ((s32)field_0x1144 == 9) { + if (mGuardDirection == GUARD_BT) { vEff.y = -80.0f; if (mXZDistanceToLink > 300.0f) { vEff.y -= (mXZDistanceToLink - 300.0f); @@ -438,8 +445,7 @@ int dAcBlastboss_c::actorExecute() { mVec3_c tmpCc; if (link->isAttacking() && mStateMgr.isState(StateID_Guard)) { - // TODO number - if ((s32)field_0x1144 == 9) { + if (mGuardDirection == GUARD_BT) { tmpCc.x = 0.0f; tmpCc.y = 0.0f; tmpCc.z = 100.0f; @@ -474,7 +480,6 @@ int dAcBlastboss_c::actorExecute() { } mCc1.SetC(tmpCc); - // TODO - ... tmpCc.x = mChestTranslation.x; tmpCc.y = mChestTranslation.y; tmpCc.z = mChestTranslation.z; @@ -493,7 +498,6 @@ int dAcBlastboss_c::actorExecute() { mCc2.SetC(tmpCc); - // TODO field_0x1250[0] = mToeTranslation[0] + (mToeTranslation[1] - mToeTranslation[0]) * 0.5f; // UB: this should use string comparison functions for robustness, but // probably works fine in MWCC @@ -501,18 +505,18 @@ int dAcBlastboss_c::actorExecute() { field_0x11A4 = 25.0f; } - fn_143_7F80(); + updateSkirtHairTransforms(); if (!link->isAttacking()) { - field_0x1143 = 1; + mInvulnerabilityTimerMaybe = 1; } - if (field_0x1143 == 0) { + if (mInvulnerabilityTimerMaybe == 0) { mCc1.SetTg_0x4B(1); // TODO mCc1.mTg.field_0x6C = field_0x1208; } else { - field_0x1143--; + mInvulnerabilityTimerMaybe--; tmpCc.set(0.0f, -10000.0f, 0.0); mCc1.SetTg_0x4B(1); // TODO @@ -636,16 +640,16 @@ int dAcBlastboss_c::actorExecute() { if (field_0x1149 != 0) { if (!link->checkSwordAndMoreStates(0x400000) && (field_0x1149 < 0 || !mIsSwordEmpowered)) { - if (field_0x1184 == 0) { + if (mLightningTimerMaybe == 0) { if (dLightEnv_c::GetPInstance()->getField_0x38DC() == 0) { dLightEnv_c::GetPInstance()->setField_0x38DC(1); - fn_143_A110(100); + setLightningTimerMaybe(100); } } else if (!mIsSwordEmpowered || (dScGame_c::getUpdateFrameCount() & 0b11) == 0) { - field_0x1184--; + mLightningTimerMaybe--; } } else { - fn_143_A110(100); + setLightningTimerMaybe(100); } sLib::addCalcScaledDiff(&field_0x11CC, 1.0f, 1.0f, 0.01f); } @@ -745,7 +749,7 @@ int dAcBlastboss_c::actorExecute() { ); } } - fn_143_9610(); + executeDemo(); SceneflagManager *mgr = SceneflagManager::sInstance; if (mgr != nullptr) { @@ -946,7 +950,7 @@ void dAcBlastboss_c::initializeState_Fight() { } else { mTimers[TIMER_2] = cM::rndF(20.0f) + 10.0f; } - field_0x1144 = 9; + mGuardDirection = GUARD_BT; } void dAcBlastboss_c::executeState_Fight() { dAcPy_c *link = dAcPy_c::GetLinkM(); @@ -958,7 +962,7 @@ void dAcBlastboss_c::executeState_Fight() { bool b = false; s16 diff = mAngle.y - mYAngleToLink; - if (field_0x2CEC >= 200 && field_0x2CEC < 300) { + if (mDemoState >= DEMO_STATE_200 && mDemoState <= DEMO_STATE_2XX_LAST) { puVar2 = -100.0f; mTimers[TIMER_2] = cM::rndF(50.0f) + 100.0f; } @@ -1077,7 +1081,7 @@ void dAcBlastboss_c::executeState_Fight() { field_0x1172 = diff / 2; // TODO what is this constant sLib::addCalcScaledDiff(&mMdlCallback.field_0x30, diff * (1.0f / 409.59937f), 0.5f, 1.0f); - if (field_0x2CEC == 0 && !link->isUsingShield() && link->isUsingSword()) { + if (mDemoState == DEMO_STATE_NONE && !link->isUsingShield() && link->isUsingSword()) { mMtx_c rotMtx; rotMtx.YrotS(-mYAngleToLink); mVec3_c v = mVec3_c(link->getSwordPos() - mPosition); @@ -1118,10 +1122,10 @@ void dAcBlastboss_c::executeState_Fight() { if (mTimers[TIMER_4] == 1) { field_0x1178 = 40; } else if (mTimers[TIMER_4] <= 10) { - field_0x1136 = 0; - field_0x1135 = 0; + mNumConsecutiveSameDirectionAttacks = 0; + mNumConsecutiveOppositeDirectionAttacks = 0; mChanceAttackCounter = 0; - mLastAttackDir = field_0x11D8 = -1; + mLastAttackDir = mSecondLastAttackDirection = -1; } } void dAcBlastboss_c::finalizeState_Fight() {} @@ -1228,9 +1232,9 @@ void dAcBlastboss_c::initializeState_CounterAttack() { mMdl.setFrame(5.0f); } - field_0x1136 = 0; - field_0x1135 = 0; - mLastAttackDir = field_0x11D8 = -1; + mNumConsecutiveSameDirectionAttacks = 0; + mNumConsecutiveOppositeDirectionAttacks = 0; + mLastAttackDir = mSecondLastAttackDirection = -1; } void dAcBlastboss_c::executeState_CounterAttack() { dAcPy_c *link = dAcPy_c::GetLinkM(); @@ -1414,7 +1418,7 @@ void dAcBlastboss_c::executeState_SmallAttack() { case SUB_STATE_0: { if (mMdl.getAnm().getFrame() >= 31.0f && mMdl.getAnm().getFrame() <= 33.0f) { field_0x11A4 = 15.0f; - if (fn_143_9420()) { + if (checkForLinkSwordBySwordHit()) { mVec3_c effPos; effPos = link->vt_0x278() + (link->getSwordPos() - link->vt_0x278()) * 0.4f; @@ -1483,7 +1487,7 @@ void dAcBlastboss_c::executeState_ThunderAttack() { v.set(0.0f, 0.0f, 50.0f); MTXMultVec(mtx, v, field_0x122C); mCc5.setCenter(field_0x1220); - fn_143_A110(30); + setLightningTimerMaybe(30); startSound(SE_BLasBos_EmitThunderBeam); } } @@ -1531,11 +1535,11 @@ void dAcBlastboss_c::executeState_Guard() { mTimers[TIMER_0] = 5; break; } else { - if (field_0x1144 == 9) { - setAnm(sGuardNames[field_0x1144], 3.0f); + if (mGuardDirection == GUARD_BT) { + setAnm(sGuardNames[mGuardDirection], 3.0f); mTimers[TIMER_0] = 14; } else { - forceSetAnm(sGuardNames[field_0x1144], 3.0f); + forceSetAnm(sGuardNames[mGuardDirection], 3.0f); } mSubState = SUB_STATE_1; // fall-through @@ -1546,7 +1550,7 @@ void dAcBlastboss_c::executeState_Guard() { mTimers[TIMER_0] = 5; } - if (field_0x1144 == 9) { + if (mGuardDirection == GUARD_BT) { field_0x1133 = 1; if (mTimers[TIMER_0] == 0) { mStateMgr.changeState(StateID_Fight); @@ -1566,16 +1570,16 @@ void dAcBlastboss_c::executeState_Guard() { field_0x11A4 = 20.0f; targetSpeed = -30.0f; if (mTimers[TIMER_0] == 0) { - field_0x1144 = 6; - forceSetAnm(sGuardNames[field_0x1144], 3.0); + mGuardDirection = GUARD_UP; + forceSetAnm(sGuardNames[mGuardDirection], 3.0); mSubState = SUB_STATE_1; } break; } case SUB_STATE_10: { - if (field_0x1144 == 0) { + if (mGuardDirection == GUARD_RIGHT) { setAnm("AttackRGuard", 3.0f); - } else if (field_0x1144 == 3) { + } else if (mGuardDirection == GUARD_LEFT) { setAnm("AttackLGuard", 3.0f); } else { setAnm("GuardU", 3.0f); @@ -1601,21 +1605,21 @@ void dAcBlastboss_c::executeState_Guard() { setAnmRate(1.0f); if (link->isAttacking()) { switch (dAcPy_c::GetLinkM()->getSpecificAttackDirection()) { - case daPlayerActBase_c::ATTACK_DIRECTION_DOWN: field_0x1144 = 6; break; - case daPlayerActBase_c::ATTACK_DIRECTION_LEFT: field_0x1144 = 3; break; - case daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT: field_0x1144 = 4; break; - case daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT: field_0x1144 = 5; break; - case daPlayerActBase_c::ATTACK_DIRECTION_RIGHT: field_0x1144 = 0; break; - case daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT: field_0x1144 = 1; break; - case daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT: field_0x1144 = 2; break; - case daPlayerActBase_c::ATTACK_DIRECTION_UP: field_0x1144 = 7; break; - default: field_0x1144 = 8; break; + case daPlayerActBase_c::ATTACK_DIRECTION_DOWN: mGuardDirection = GUARD_UP; break; + case daPlayerActBase_c::ATTACK_DIRECTION_LEFT: mGuardDirection = GUARD_LEFT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT: mGuardDirection = GUARD_UPLEFT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT: mGuardDirection = GUARD_DOWNLEFT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_RIGHT: mGuardDirection = GUARD_RIGHT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT: mGuardDirection = GUARD_UPRIGHT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT: mGuardDirection = GUARD_DOWNRIGHT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_UP: mGuardDirection = GUARD_DOWN; break; + default: mGuardDirection = GUARD_CENTER; break; } - setAnm(sGuardNames[field_0x1144], 3.0); + setAnm(sGuardNames[mGuardDirection], 3.0); } } - mCc1.SetTgFlag_0xA(sGuardFlags[field_0x1144]); + mCc1.SetTgFlag_0xA(sGuardFlags[mGuardDirection]); checkForRangeAttack(); } void dAcBlastboss_c::finalizeState_Guard() {} @@ -1764,8 +1768,8 @@ void dAcBlastboss_c::executeState_Down() { field_0x1141 = 1; field_0x1142 = 5; bool b = false; - fn_143_A110(30); - field_0x1144 = -1; + setLightningTimerMaybe(30); + mGuardDirection = -1; // TODO: Are all these fall-throughs intentional?????? switch (mSubState) { @@ -1801,7 +1805,7 @@ void dAcBlastboss_c::executeState_Down() { if (mMdl.getAnm().isStop()) { setAnm("DownLoop", 0.0f); mSubState = SUB_STATE_3; - if (field_0x113B >= 3 || field_0x2CEC != 0) { + if (field_0x113B >= 3 || mDemoState != DEMO_STATE_NONE) { mTimers[TIMER_0] = 70; } else if (field_0x113B == 2) { mTimers[TIMER_0] = 40; @@ -1824,14 +1828,14 @@ void dAcBlastboss_c::executeState_Down() { sLib::addCalcScaled(&mSpeed, 1.0f, 1.0f); if (checkInteractionFlags(INTERACT_0x1000)) { setAnm("End", 3.0f); - mSubState = 50; - field_0x2CEC = 100; + mSubState = SUB_STATE_50; + mDemoState = DEMO_STATE_100; startSound(SE_BLasBos_LastHit); field_0x114F = 1; resetInteractionFlags(INTERACT_0x1000); resetInteractionFlags(INTERACT_0x1); } else if (mTimers[TIMER_0] == 0) { - if (cM::rnd() < 0.5f || field_0x2CEC != 0) { + if (cM::rnd() < 0.5f || mDemoState != DEMO_STATE_NONE) { setAnm("DownEscapeR", 10.0f); } else { setAnm("DownEscapeL", 10.0f); @@ -1840,8 +1844,8 @@ void dAcBlastboss_c::executeState_Down() { mSubState = SUB_STATE_5; field_0x11C8 = 0.0f; resetInteractionFlags(INTERACT_0x1); - if (field_0x2CEC != 0) { - field_0x2CEC = 3; + if (mDemoState != DEMO_STATE_NONE) { + mDemoState = DEMO_STATE_3; field_0x2D00 = 0.0f; dLightEnv_c::GetPInstance()->setField_0x38DC(1); } @@ -1883,7 +1887,7 @@ void dAcBlastboss_c::executeState_Down() { mPosition.z += v.z; if (mMdl.getAnm().isStop()) { - if (field_0x2CEC != 0) { + if (mDemoState != DEMO_STATE_NONE) { setAnm("ThunderDemo", 10.0f); mSubState = SUB_STATE_20; } else { @@ -1919,7 +1923,7 @@ void dAcBlastboss_c::executeState_Down() { if (mMdl.getAnm().isStop()) { mStateMgr.changeState(StateID_Fight); mTimers[TIMER_4] = 15; - field_0x2CEC = 1000; + mDemoState = DEMO_STATE_1000; } break; } @@ -1943,15 +1947,15 @@ void dAcBlastboss_c::initializeState_Stun() { setAnm("Stan", 3.0f); mSubState = SUB_STATE_0; mChanceAttackCounter = 0; - field_0x1143 = 10; - field_0x1154++; + mInvulnerabilityTimerMaybe = 10; + mStunCounter++; mIsSwordEmpowered = false; mCc1.ClrTg_0x8000000(); mSwordMdl.fn_8006B800(0); startSound(SE_BLasBos_HitThunderBeam); } void dAcBlastboss_c::executeState_Stun() { - fn_143_A110(40); + setLightningTimerMaybe(40); field_0x114B = 1; int frame = mMdl.getAnm().getFrame(); switch (mSubState) { @@ -1993,7 +1997,7 @@ void dAcBlastboss_c::executeState_Stun() { mCc1.SetTgFlag_0xA(0x1FF); checkForCounter(); } else { - if (field_0x1143 != 0) { + if (mInvulnerabilityTimerMaybe != 0) { mCc1.SetTgFlag_0xA(0x1FF); } else { mCc1.SetTgFlag_0xA(0); @@ -2005,7 +2009,7 @@ void dAcBlastboss_c::finalizeState_Stun() {} void dAcBlastboss_c::initializeState_ThunderWait() { setAnm("CatchThunderStart", 10.0f); mSubState = SUB_STATE_0; - field_0x1144 = -1; + mGuardDirection = -1; mTimers[TIMER_0] = 30; } void dAcBlastboss_c::executeState_ThunderWait() { @@ -2082,7 +2086,7 @@ bool dAcBlastboss_c::checkDamage() { } dAcPy_c *link = dAcPy_c::GetLinkM(); - s32 attackDir = link->getSpecificAttackDirection(); + s32 mLastAttackDirection = link->getSpecificAttackDirection(); // TODO: enum? switch (unk) { @@ -2105,7 +2109,7 @@ bool dAcBlastboss_c::checkDamage() { } if (tgHit->ChkTgAtHitType(AT_TYPE_0x800000)) { - field_0x1144 = 6; + mGuardDirection = GUARD_UP; mStateMgr.changeState(StateID_Guard); break; } @@ -2114,46 +2118,49 @@ bool dAcBlastboss_c::checkDamage() { mSubState = SUB_STATE_1; mStateMgr.changeState(StateID_CounterAttack); break; - } else if (field_0x1144 == 9) { - if (fn_143_9570(attackDir) == fn_143_9570(mLastAttackDir)) { - field_0x1135++; + } else if (mGuardDirection == GUARD_BT) { + if (classifyAttackDirection(mLastAttackDirection) == classifyAttackDirection(mLastAttackDir)) { + mNumConsecutiveOppositeDirectionAttacks++; } else { - field_0x1136++; + mNumConsecutiveSameDirectionAttacks++; } - if (field_0x1136 >= 2) { + if (mNumConsecutiveSameDirectionAttacks >= 2) { mSubState = SUB_STATE_1; mStateMgr.changeState(StateID_CounterAttack); break; } - if (fn_143_9570(attackDir) == 0) { + if (classifyAttackDirection(mLastAttackDirection) == 0) { + // Left mMdlCallback.field_0x30 += 3.0f; mMdlCallback.field_0x18 += 0x7D0; - } else if (fn_143_9570(attackDir) == 1) { + } else if (classifyAttackDirection(mLastAttackDirection) == 1) { + // Right mMdlCallback.field_0x30 -= 3.0f; mMdlCallback.field_0x18 -= 0x7D0; } - if (field_0x1135 >= 1) { + if (mNumConsecutiveOppositeDirectionAttacks >= 1) { mStateMgr.changeState(StateID_GuardBreak); } } else if (mLastAttackDir >= 0) { - if (fn_143_9570(attackDir) == fn_143_9570(mLastAttackDir)) { - field_0x1136++; + if (classifyAttackDirection(mLastAttackDirection) == classifyAttackDirection(mLastAttackDir)) { + mNumConsecutiveSameDirectionAttacks++; } else { - field_0x1135++; + mNumConsecutiveOppositeDirectionAttacks++; } s8 x = 3; - if (fn_143_9570(attackDir) == fn_143_9570(mLastAttackDir)) { + if (classifyAttackDirection(mLastAttackDirection) == classifyAttackDirection(mLastAttackDir)) { x = 1; } - if (field_0x1136 >= x || - (field_0x11D8 >= 0 && (fn_143_9570(field_0x11D8) & 2) == (fn_143_9570(attackDir) & 2))) { + if (mNumConsecutiveSameDirectionAttacks >= x || + (mSecondLastAttackDirection >= 0 && (classifyAttackDirection(mSecondLastAttackDirection) & 2) == + (classifyAttackDirection(mLastAttackDirection) & 2))) { mSubState = SUB_STATE_0; mStateMgr.changeState(StateID_CounterAttack); } else { - if (field_0x1135 >= 1) { + if (mNumConsecutiveOppositeDirectionAttacks >= 1) { field_0x113E = 25; - field_0x1135 = 1; + mNumConsecutiveOppositeDirectionAttacks = 1; field_0x1182 = 20; } } @@ -2165,7 +2172,7 @@ bool dAcBlastboss_c::checkDamage() { MTXMultVec(mtx, v, v2); field_0x119C = v2.x; field_0x11A0 = v2.z; - mLastAttackDir = attackDir; + mLastAttackDir = mLastAttackDirection; break; } case 7: { @@ -2176,7 +2183,7 @@ bool dAcBlastboss_c::checkDamage() { (tgHit->ChkTgAtHitType(AT_TYPE_SLINGSHOT) || tgHit->ChkTgAtHitType(AT_TYPE_CLAWSHOT) || tgHit->ChkTgAtHitType(AT_TYPE_BOMB) || tgHit->ChkTgAtHitType(AT_TYPE_ARROW) || tgHit->ChkTgAtHitType(AT_TYPE_WHIP) || tgHit->ChkTgAtHitType(AT_TYPE_0x40))) { - field_0x1144 = 6; + mGuardDirection = GUARD_UP; mStateMgr.changeState(StateID_Guard); if (tgHit->ChkTgAtHitType(AT_TYPE_BOMB)) { @@ -2216,7 +2223,7 @@ bool dAcBlastboss_c::checkDamage() { if (field_0x1152 == 30) { dStageMgr_c::GetInstance()->fn_80199B60(4); mStateMgr.changeState(StateID_Down); - field_0x2CEC = 1; + mDemoState = DEMO_STATE_1; startSound(SE_BLasBos_DownHit); break; } @@ -2224,7 +2231,6 @@ bool dAcBlastboss_c::checkDamage() { if (field_0x1152 == 50) { mStateMgr.changeState(StateID_Down); field_0x1152 = 45; - break; } } @@ -2242,8 +2248,8 @@ bool dAcBlastboss_c::checkDamage() { } if (mStateMgr.isState(StateID_Stun)) { - field_0x1136 = 0; - field_0x11D8 = attackDir; + mNumConsecutiveSameDirectionAttacks = 0; + mSecondLastAttackDirection = mLastAttackDirection; mChanceAttackCounter++; v.x = 0.0f; @@ -2256,15 +2262,15 @@ bool dAcBlastboss_c::checkDamage() { field_0x1138 = 10; field_0x11B8 = 5.0f; field_0x11A4 = 7.0f; - if (attackDir == daPlayerActBase_c::ATTACK_DIRECTION_LEFT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT) { + if (mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_LEFT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT) { field_0x1137 = 1; - } else if (attackDir == daPlayerActBase_c::ATTACK_DIRECTION_RIGHT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT) { + } else if (mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_RIGHT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT) { field_0x1137 = 2; - } else if (attackDir == daPlayerActBase_c::ATTACK_DIRECTION_STAB) { + } else if (mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_STAB) { field_0x1137 = 3; } else { field_0x1137 = 0; @@ -2274,8 +2280,8 @@ bool dAcBlastboss_c::checkDamage() { } if (mStateMgr.isState(StateID_SitDamage)) { - field_0x1136 = 0; - field_0x11D8 = attackDir; + mNumConsecutiveSameDirectionAttacks = 0; + mSecondLastAttackDirection = mLastAttackDirection; mChanceAttackCounter++; if (mChanceAttackCounter >= 5 && mChanceCounter >= 3) { @@ -2284,7 +2290,7 @@ bool dAcBlastboss_c::checkDamage() { field_0x1152 = 30; dStageMgr_c::GetInstance()->fn_80199B60(4); mStateMgr.changeState(StateID_Down); - field_0x2CEC = 1; + mDemoState = DEMO_STATE_1; startSound(SE_BLasBos_DownHit); break; } @@ -2302,15 +2308,15 @@ bool dAcBlastboss_c::checkDamage() { field_0x11A0 = v2.z; field_0x11B8 = 5.0f; field_0x11A4 = 7.0f; - if (attackDir == daPlayerActBase_c::ATTACK_DIRECTION_LEFT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT) { + if (mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_LEFT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT) { field_0x1137 = 1; - } else if (attackDir == daPlayerActBase_c::ATTACK_DIRECTION_RIGHT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT) { + } else if (mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_RIGHT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT) { field_0x1137 = 2; - } else if (attackDir == daPlayerActBase_c::ATTACK_DIRECTION_DOWN) { + } else if (mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_DOWN) { field_0x1137 = 3; } else { field_0x1137 = 0; @@ -2327,8 +2333,8 @@ bool dAcBlastboss_c::checkDamage() { mStateMgr.changeState(StateID_Damage); } - field_0x1136 = -1; - field_0x11D8 = attackDir; + mNumConsecutiveSameDirectionAttacks = -1; + mSecondLastAttackDirection = mLastAttackDirection; v.x = 0.0f; v.y = 0.0f; v.z = -20.0f; @@ -2339,15 +2345,15 @@ bool dAcBlastboss_c::checkDamage() { field_0x1138 = 10; field_0x11B8 = 5.0f; field_0x11A4 = 7.0f; - if (attackDir == daPlayerActBase_c::ATTACK_DIRECTION_LEFT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT) { + if (mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_LEFT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT) { field_0x1137 = 1; - } else if (attackDir == daPlayerActBase_c::ATTACK_DIRECTION_RIGHT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT || - attackDir == daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT) { + } else if (mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_RIGHT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT || + mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT) { field_0x1137 = 2; - } else if (attackDir == daPlayerActBase_c::ATTACK_DIRECTION_STAB) { + } else if (mLastAttackDirection == daPlayerActBase_c::ATTACK_DIRECTION_STAB) { field_0x1137 = 3; } else { field_0x1137 = 0; @@ -2405,7 +2411,7 @@ bool dAcBlastboss_c::checkForCloseRangeAttack() { mStateMgr.changeState(StateID_PunchAttack); ret = true; } else if (mTimers[TIMER_2] == 0) { - if (fn_143_9420() && cM::rnd() < 0.35f) { + if (checkForLinkSwordBySwordHit() && cM::rnd() < 0.35f) { mStateMgr.changeState(StateID_SmallAttack); ret = true; } else { @@ -2429,7 +2435,7 @@ bool dAcBlastboss_c::checkForRangeAttack() { bool ret = false; - if (field_0x1149 != 0 && !link->isRecovering() && field_0x1154 != 0 && link->getSwordPos().y > 270.0f) { + if (field_0x1149 != 0 && !link->isRecovering() && mStunCounter != 0 && link->getSwordPos().y > 270.0f) { field_0x1162++; } else { field_0x1162 = 0; @@ -2440,14 +2446,14 @@ bool dAcBlastboss_c::checkForRangeAttack() { mStateMgr.changeState(StateID_DashAttack); return true; } else if (mIsSwordEmpowered) { - if ((link->checkSwordAndMoreStates(0x400000) && field_0x1154 != 0) || + if ((link->checkSwordAndMoreStates(0x400000) && mStunCounter != 0) || (mXZDistanceToLink < 1500.0f && mTimers[TIMER_3] == 0)) { mStateMgr.changeState(StateID_ThunderAttack); ret = true; } } else { if (link->checkSwordAndMoreStates(0x400000)) { - if ((field_0x1164 & 7) == 0 && field_0x1154 != 0) { + if ((mCounter & 0x7) == 0 && mStunCounter != 0) { mStateMgr.changeState(StateID_DashAttack); ret = true; } @@ -2495,13 +2501,13 @@ bool dAcBlastboss_c::checkForCounter() { if (mpCurrentAnm == "AttackR" && (attackDir == dAcPy_c::ATTACK_DIRECTION_RIGHT || attackDir == dAcPy_c::ATTACK_DIRECTION_UPRIGHT || attackDir == dAcPy_c::ATTACK_DIRECTION_DOWNRIGHT)) { - field_0x1144 = 0; + mGuardDirection = GUARD_RIGHT; } else if (mpCurrentAnm == "AttackL" && (attackDir == dAcPy_c::ATTACK_DIRECTION_LEFT || attackDir == dAcPy_c::ATTACK_DIRECTION_UPLEFT || attackDir == dAcPy_c::ATTACK_DIRECTION_DOWNLEFT)) { - field_0x1144 = 3; + mGuardDirection = GUARD_LEFT; } else if (mpCurrentAnm == "AttackU" && attackDir == daPlayerActBase_c::ATTACK_DIRECTION_DOWN) { - field_0x1144 = 6; + mGuardDirection = GUARD_UP; } else { return false; } @@ -2509,20 +2515,20 @@ bool dAcBlastboss_c::checkForCounter() { mStateMgr.changeState(StateID_Guard); mSubState = SUB_STATE_10; } else { - if ((field_0x1149 > 0 || mXZDistanceToLink < 200.0f) && field_0x1135 < 1) { - field_0x1135 = 1; + if ((field_0x1149 > 0 || mXZDistanceToLink < 200.0f) && mNumConsecutiveOppositeDirectionAttacks < 1) { + mNumConsecutiveOppositeDirectionAttacks = 1; } switch (attackDir) { - case daPlayerActBase_c::ATTACK_DIRECTION_DOWN: field_0x1144 = 6; break; - case daPlayerActBase_c::ATTACK_DIRECTION_LEFT: field_0x1144 = 3; break; - case daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT: field_0x1144 = 4; break; - case daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT: field_0x1144 = 5; break; - case daPlayerActBase_c::ATTACK_DIRECTION_RIGHT: field_0x1144 = 0; break; - case daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT: field_0x1144 = 1; break; - case daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT: field_0x1144 = 2; break; - case daPlayerActBase_c::ATTACK_DIRECTION_UP: field_0x1144 = 7; break; - default: field_0x1144 = 8; break; + case daPlayerActBase_c::ATTACK_DIRECTION_DOWN: mGuardDirection = GUARD_UP; break; + case daPlayerActBase_c::ATTACK_DIRECTION_LEFT: mGuardDirection = GUARD_LEFT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT: mGuardDirection = GUARD_UPLEFT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT: mGuardDirection = GUARD_DOWNLEFT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_RIGHT: mGuardDirection = GUARD_RIGHT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT: mGuardDirection = GUARD_UPRIGHT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT: mGuardDirection = GUARD_DOWNRIGHT; break; + case daPlayerActBase_c::ATTACK_DIRECTION_UP: mGuardDirection = GUARD_DOWN; break; + default: mGuardDirection = GUARD_CENTER; break; } if (!mStateMgr.isState(StateID_Guard)) { mStateMgr.changeState(StateID_Guard); @@ -2536,12 +2542,726 @@ bool dAcBlastboss_c::checkForCounter() { return ret; } -void dAcBlastboss_c::fn_143_7B00() {} +void dAcBlastboss_c::updateMainNodeTransforms() { + if (field_0x1131 != 0) { + s16 ang = 0x800; + if (field_0x1131 == 2) { + ang = 0x300; + } + dAcPy_c *link = dAcPy_c::GetLinkM(); + mVec3_c attentionTarget = link->getPosition(); + attentionTarget.y += 250.0f; + if (link->isUsingBugnet() && mXZDistanceToLink < 400.0f) { + field_0x117C = 5; + mBugNetPos = link->getBugNetPos(); + } -void dAcBlastboss_c::fn_143_7F80() {} + s16 diff; + if (field_0x117C != 0) { + attentionTarget = mBugNetPos; + mAng targetAngle = cLib::targetAngleY(mPosition, attentionTarget); + diff = targetAngle - mRotation.y; + } else { + diff = mYAngleToLink - mRotation.y; + } + if (diff > 0x1800) { + diff = 0x1800; + } else if (diff < -0x1800) { + diff = -0x1800; + } + sLib::addCalcAngle(mMdlCallback.field_0x06.ref(), -diff, 2, ang); -bool dAcBlastboss_c::fn_143_9420() { - return true; + s16 diff2 = cLib::targetAngleX(attentionTarget, mPositionCopy2); + if (diff2 > 0x1000) { + diff2 = 0x1000; + } else if (diff2 < -0x1000) { + diff2 = -0x1000; + } + sLib::addCalcAngle(mMdlCallback.field_0x0A.ref(), diff2, 2, ang); + + if ((mCounter & 0xF) == 0 && cM::rnd() < 0.5f) { + field_0x1170 = cM::rndFX(2000.0f); + } + sLib::addCalcAngle(mMdlCallback.field_0x0C.ref(), field_0x1170, 8, 0x200); + } else { + mMdlCallback.field_0x06 = mMdlCallback.field_0x0A = mMdlCallback.field_0x0C = 0; + if (mDemoState == DEMO_STATE_101) { + mMdlCallback.field_0x0A = 2000; + } + } + + if (field_0x1178 != 0) { + field_0x1178--; + s16 target = mAng(field_0x1178 * 0xE00).sin() * 1500.0f; + sLib::addCalcAngle(mMdlCallback.field_0x08.ref(), target, 2, 200); + } else { + sLib::addCalcAngle(mMdlCallback.field_0x08.ref(), 0, 2, 100); + } + + s16 t3 = 0; + if (field_0x1182 != 0) { + field_0x1182--; + t3 = 4000; + } + sLib::addCalcAngle(mMdlCallback.field_0x12.ref(), t3, 4, 200); + sLib::addCalcAngle(mMdlCallback.field_0x14.ref(), field_0x1172, 2, 0x200); + sLib::addCalcAngle(mMdlCallback.field_0x16.ref(), field_0x1174, 2, 0x200); + + field_0x1172 = 0; + field_0x1174 = 0; + + if (field_0x1138 != 0) { + field_0x1138--; + + field_0x117A = 2000; + s16 t4 = 0, t5 = 0; + if (field_0x1137 == 0) { + field_0x117A = 3000; + t5 = 5000; + } else if (field_0x1137 == 1) { + t5 = 3000; + t4 = 3000; + } else if (field_0x1137 == 2) { + t5 = 3000; + t4 = -3000; + } else if (field_0x1137 == 3) { + field_0x117A = 3000; + t5 = -5000; + } + + sLib::addCalcAngle(mMdlCallback.field_0x0E.ref(), t4, 2, field_0x117A); + sLib::addCalcAngle(mMdlCallback.field_0x10.ref(), t5, 2, field_0x117A); + } else if (field_0x1188 != 0) { + field_0x1188--; + s16 target = mAng(mCounter * 0x6510).sin() * 300.0f; + mMdlCallback.field_0x2E = target; + } else { + sLib::addCalcAngle(mMdlCallback.field_0x0E.ref(), 0, 4, field_0x117A / 4); + sLib::addCalcAngle(mMdlCallback.field_0x10.ref(), 0, 4, field_0x117A / 4); + } + + if (field_0x1133 == 0) { + sLib::addCalcScaled(&mMdlCallback.field_0x30, 0.5f, 0.5f); + sLib::addCalcAngle(mMdlCallback.field_0x18.ref(), 0, 4, 400); + sLib::addCalcAngle(mMdlCallback.field_0x1A.ref(), 0, 4, 400); + } } -void dAcBlastboss_c::fn_143_9610() {} +void dAcBlastboss_c::updateSkirtHairTransforms() { + static const u16 sNodeIds[] = { + B_LAST_BOSS_NODE_skirtAU1, B_LAST_BOSS_NODE_skirtBU1, B_LAST_BOSS_NODE_skirtCU1, B_LAST_BOSS_NODE_skirtDU1, + B_LAST_BOSS_NODE_skirtEU1, B_LAST_BOSS_NODE_skirtFU1, B_LAST_BOSS_NODE_skirtGU1, B_LAST_BOSS_NODE_skirtHU1, + }; + + static const s16 sAngs[] = { + 0x2000, 0x4000, 0x6000, 0x8000, 0xA000, 0xC000, 0xE000, + }; + + f32 f = 80.0f; + + if (mpCurrentAnm == "AttackU") { + if (mMdl.getAnm().getFrame() >= 18.0f && mMdl.getAnm().getFrame() <= 40.0f) { + f = 150.0f; + } + } else if (mpCurrentAnm == "Counter") { + if (mMdl.getAnm().getFrame() >= 17.0f && mMdl.getAnm().getFrame() <= 68.0f) { + f = 120.0f; + } + } else if (mpCurrentAnm == "TurnR") { + if (mMdl.getAnm().getFrame() >= 19.0f && mMdl.getAnm().getFrame() <= 30.0f) { + f = 100.0f; + } + } else if (mpCurrentAnm == "AttackJumpEnd") { + if (mMdl.getAnm().getFrame() <= 18.0f) { + f = 120.0f; + } + } else if (mpCurrentAnm == "AttackJumpStart" || mpCurrentAnm == "AttackJumpLoop") { + f = 120.0f; + } else if (mpCurrentAnm == "DownGetUp") { + // same value + f = 80.0f; + } + sLib::addCalcScaledDiff(&field_0x11B4, f, 0.5f, 20.0f); + + mMtx_c mtx; + mVec3_c v; + mVec3_c t(0.0f, 0.0f, 12.0f); + for (int i = 0; i < (int)ARRAY_LENGTH(field_0x1268); i++) { + field_0x1268[i].field_0x002++; + field_0x1268[i].field_0x004 = sAngs[i] + mRotation.y; + mMdl.getModel().getNodeWorldMtx(sNodeIds[i], mtx); + mtx.getTranslation(v); + mtx.YrotS(field_0x1268[i].field_0x004); + MTXMultVec(mtx, t, field_0x1268[i].field_0x014[0]); + field_0x1268[i].field_0x014[0] += v; + if (nw4r::math::FAbs(field_0x1268[i].field_0x010) < 1.0f) { + // TODO - regswaps between tmp and abs result + f32 tmp = field_0x1268[(i + 1) & 7].field_0x010; + if (nw4r::math::FAbs(tmp) > 1.0f) { + field_0x1268[i].field_0x010 = tmp * 0.5f; + } + tmp = field_0x1268[(i - 1) & 7].field_0x010; + if (nw4r::math::FAbs(tmp) > 1.0f) { + field_0x1268[i].field_0x010 = tmp * 0.5f; + } + } + + f32 f4 = field_0x1268[i].field_0x010 + field_0x11A4; + if (nw4r::math::FAbs(f4) > 0.1f) { + if (field_0x11A4 > 0.1f) { + field_0x1268[i].field_0x006 = mRotation.y + 0x8000 + moreAngs[i]; + } else if (field_0x11A4 < -0.1f) { + field_0x1268[i].field_0x006 = mRotation.y + 0x8000 - moreAngs[i]; + } + + if (nw4r::math::FAbs(field_0x11A4) > 25.0f) { + field_0x1268[i].field_0x00A = 8000; + } else { + field_0x1268[i].field_0x00A = 5000; + } + + if (i >= 2 && i <= 6) { + field_0x1268[i].field_0x00C = f4; + } else { + field_0x1268[i].field_0x00C = 0.75f * f4; + } + field_0x11B0 = 0.0f; + } else { + sLib::addCalcScaled(&field_0x1268[i].field_0x00C, 0.05f, 2.0f); + sLib::addCalcAngle(&field_0x1268[i].field_0x00A, 1000, 4, 200); + } + field_0x1268[i].field_0x008 += field_0x1268[i].field_0x00A; + updateSkirtTransform(i); + } + + mMdl.getModel().getNodeWorldMtx(B_LAST_BOSS_NODE_head, mtx); + mtx.fn_802F1C40(0, 1); + mAng3_c ang; + mtx.toRot(ang); + ang.y += 0x4000; + ang.x += 0; + ang.z += 6500; + t.set(-20.0f, -20.0f, 0.0f); + for (int i = 0; i < 1; i++) { + field_0x2948[i].field_0x002 = ang.y; + field_0x2948[i].field_0x004 = -ang.z; + field_0x2948[i].field_0x006 = -ang.x; + mMdl.getModel().getNodeWorldMtx(B_LAST_BOSS_NODE_head, mtx); + MTXMultVec(mtx, t, field_0x2948[i].field_0x008[0]); + updateHairTransform(i); + } + + if (field_0x1141 == 0) { + for (int i = 0; i < 9; i++) { + f32 f = (i % 3) * 3 + 1; + if (i < 3) { + mMdlCallback.field_0x1C[i] = (s16)(f * 500.0f * mAng(mCounter * 0x2600 - (i * 24000)).sin()); + } else if (i < 6) { + mMdlCallback.field_0x1C[i] = -(s16)(f * 500.0f * mAng(mCounter * 0x2800 - (i * 25000)).sin()); + } else { + mMdlCallback.field_0x1C[i] = -(s16)(f * 500.0f * mAng(mCounter * 0x2A00 - (i * 26000)).sin()); + } + } + } + + if (field_0x114E != 0) { + holdSound(SE_BLasBos_SkirtAir); + } +} + +void dAcBlastboss_c::updateSkirtTransform(s32 level) { + // NONMATCHING but probably equivalent + + UnkLastBossCcSph2 &cc = field_0x1268[level]; + + mVec3_c t1(0.0f, 0.0f, 33.25f); + + s32 offset1 = 0; + + mVec3_c d1; + + d1 = mToeTranslation[0] - mBackbone1Translation; + + mMtx_c mtx; + mtx.YrotS(-mRotation.y); + MTXMultVec(mtx, d1, d1); + if (d1.z > 0.0f) { + offset1 = -1; + } + + d1 = mToeTranslation[1] - mBackbone1Translation; + MTXMultVec(mtx, d1, d1); + if (d1.z > 20.0f) { + offset1 = 1; + } + + // hmm yes + mVec3_c p3; + mVec3_c v4; + mVec3_c p2; + mVec3_c v5; + mVec3_c p1; + + p1.set(0.0f, 0.0f, 0.0f); + p2.set(0.0f, 0.0f, 0.0f); + bool isAttackJumpStart = false; + if (mpCurrentAnm == "AttackJumpStart") { + isAttackJumpStart = true; + } + f32 f; + if (level == 7 && offset1 > 0) { + f = 10.0f; + } else if (level >= 0 && level <= 1 && offset1 < 0) { + f = 50.0f; + } else { + f = -3.0f; + } + if (level >= 0 && level < 2 && isAttackJumpStart) { + p1.y = 500.0f; + f = 50.0f; + } + + sLib::addCalcScaledDiff(&field_0x11D0, f, 1.0f, 2.0f); + p1.z = field_0x11D0; + + p3.set(0.0f, 0.0f, 2.0f); + mtx.YrotS(cc.field_0x004); + MTXMultVec(mtx, p3, v4); + MTXMultVec(mtx, p1, v5); + mtx.YrotS(mRotation.y); + MTXMultVec(mtx, p2, p2); + + f32 fAdd = -15.0f; + f32 f1 = cc.field_0x00C; + sLib::addCalcScaledDiff(&field_0x11AC, field_0x11B0, 1.0f, 0.02f); + + s32 offset2 = 0; + if (offset1 < 0 && (level == 0) || level == 1 || level == 2 || level == 7) { + offset2 = 1; + } + + f32 f2 = field_0x11B4; + u32 u12 = (cc.field_0x002 & 1) + 1; + if (level >= 2 && level <= 6) { + u12 += 2; + cc.mCc.SetR(30.0f); + } else { + cc.mCc.SetR(50.0f); + } + + if (field_0x1141 != 0) { + offset2 = 0; + v4.set(0.0f, 0.0f, 0.0f); + p2.set(0.0f, 0.0f, 0.0f); + } + + f1 *= 0.75f; + + static const f32 sFloats[] = { + 15.0f, 15.0f, 15.0f, 15.0f, 13.0f, 11.0f, 9.0f, 7.0f, 5.0f, + }; + + s32 actual = offset2 - 1; + + for (u32 i = 1; i < 10; i++) { + // TODO: These strength reduced and moved to before the loop. + // However, we need them at the start of the function! + mVec3_c *v1 = &cc.field_0x014[i]; + mVec3_c *v2 = &cc.field_0x08C[i] - 1; + mVec3_c *v3 = &cc.field_0x104[i]; + + mtx.YrotS(cc.field_0x006); + d1.x = 0.0f; + d1.y = mAng(cc.field_0x008 - i * 8000).sin() * f1; + d1.z = f1; + mVec3_c v6; + MTXMultVec(mtx, d1, v6); + s32 zero = 0; + f1 = f1 * (zero * 0.01f + 1.1f); + + f32 fY = fAdd + v1[0].y + v4.y + v3[0].y + v6.y + v5.y; + if (i >= 1) { + v5.y = 0.0f; + } else { + // @bug unreachable + v5.y *= 0.5f; + } + + f32 f4; + if (field_0x1141 != 0) { + f4 = 5.0f; + } else { + f4 = sFloats[i - 1]; + } + + if (fY <= f4) { + fY = f4; + } + + f32 fX = v1[0].x + v4.x + p2.x + v3[0].x + v6.x + v5.x; + f32 fZ = v1[0].z + v4.z + p2.z + v3[0].z + v6.z + v5.z; + if (offset2 != 0) { + f32 dX = fX - field_0x1250[actual].x; + f32 dZ = fZ - field_0x1250[actual].z; + f32 f11 = nw4r::math::FSqrt(dX * dX + dZ * dZ); + if (f11 < f2) { + mtx.YrotS(cM::atan2s(dX, dZ)); + d1.set(0.0f, 0.0f, f2); + MTXMultVec(mtx, d1, d1); + fX = d1.x + field_0x1250[actual].x; + fZ = d1.z + field_0x1250[actual].z; + } + } + + f32 fX2 = fX - v1[-1].x; + f32 fY2 = fY - v1[-1].y; + f32 fZ2 = fZ - v1[-1].z; + v5.x *= 0.4f; + v5.z *= 0.4f; + v2[0].x = -cM::atan2s(fY2, fZ2); + f32 f8 = nw4r::math::FSqrt(fY2 * fY2 + fZ2 * fZ2); + + v2[0].y = cM::atan2s(fX2, f8); + v2[0].z = mRotation.y; + + mtx.XrotS(v2[0].x); + mtx.YrotM(v2[0].y); + MTXMultVec(mtx, t1, d1); + v3[0] = v1[0]; + v1[0] = v1[-1] + d1; + v3[0] = (v1[0] - v3[0]) * field_0x11AC; + if (i == u12) { + cc.field_0x010 = 0.0f; + cc.mCc.SetC(v1[0]); + if (cc.mCc.ChkTgHit()) { + cc.field_0x006 = moreAngs[level] + dAcPy_c::GetLinkM()->mRotation.y; + cc.field_0x010 = 25.0f; + field_0x114E = 1; + } + } + } +} + +void dAcBlastboss_c::updateHairTransform(s32 level) { + // Might hold off with this one until updateSkirtTransform is fixed + + // floats + 47.5f; + 0.9f; + 1.6f; +} + +bool dAcBlastboss_c::checkForLinkSwordBySwordHit() { + dAcPy_c *link = dAcPy_c::GetLinkM(); + + bool ret = !link->isUsingShield(); + if (ret) { + ret = link->isUsingSword(); + } + if (ret) { + ret = link->getSwordPos().y > 100.0f; + } + if (ret) { + ret = link->getSwordPos().y < 230.0f; + } + if (ret) { + ret = (mPosition - link->getSwordPos()).absXZ() < 260.0f; + } + + return ret; +} + +u8 dAcBlastboss_c::classifyAttackDirection(s32 attackDir) { + switch (attackDir) { + case daPlayerActBase_c::ATTACK_DIRECTION_LEFT: + case daPlayerActBase_c::ATTACK_DIRECTION_DOWNLEFT: + case daPlayerActBase_c::ATTACK_DIRECTION_UPLEFT: return 0; + + case daPlayerActBase_c::ATTACK_DIRECTION_RIGHT: + case daPlayerActBase_c::ATTACK_DIRECTION_DOWNRIGHT: + case daPlayerActBase_c::ATTACK_DIRECTION_UPRIGHT: return 1; + + case daPlayerActBase_c::ATTACK_DIRECTION_DOWN: return 2; + case daPlayerActBase_c::ATTACK_DIRECTION_UP: return 3; + + case daPlayerActBase_c::ATTACK_DIRECTION_STAB: return 4; + + default: return -1; + } +} + +void dAcBlastboss_c::executeDemo() { + dCamera_c *cam = dScGame_c::getCamera(); + dAcPy_c *link = dAcPy_c::GetLinkM(); + + mMtx_c mtx; + mMtx_c mtx1; + mVec3_c v; + mVec3_c effPos; + + bool b1 = false; + bool b2 = false; + bool spawnEffect = false; + dLightEnv_c &lightEnv = dLightEnv_c::GetInstance(); + + switch (mDemoState) { + case DEMO_STATE_1: { + { + // this works but I don't like it + static volatile u32 FLAGS_1 = 0x00000001; + static u32 FLAGS_2 = 0x00100001; + u32 f1 = FLAGS_1; + u32 f2 = FLAGS_2; + Event e = Event("BLS_demo2", 100, f2 & ~f1, nullptr, nullptr); + EventManager::alsoSetAsCurrentEvent(this, &e, nullptr); + } + if (EventManager::isInEvent(this, "BLS_demo2")) { + field_0x2CEE = 0; + field_0x2D00 = 0.0f; + field_0x2CFC = 60.0f; + mDemoState = DEMO_STATE_2; + // huh + field_0x2D10.x = cam->getField_0x78().x; + field_0x2D10.y = cam->getField_0x78().y; + field_0x2D10.z = cam->getField_0x78().z; + field_0x2D04.x = cam->getPositionMaybe().x; + field_0x2D04.y = cam->getPositionMaybe().y; + field_0x2D04.z = cam->getPositionMaybe().z; + field_0x1149 = -1; + // fall-through + } else { + break; + } + } + case DEMO_STATE_2: { + if (field_0x2CEE < 30) { + b2 = true; + } + mtx.YrotS((s16)field_0x2CF4 + mRotation.y); + v.set(0.0f, 100.0f, 400.0f); + MTXMultVec(mtx, v, v); + v += mPosition; + cLib::addCalcPos2(&field_0x2D04, v, 0.1f, 30.0f); + if (field_0x2CEE > 5) { + sLib::addCalcScaledDiff(&field_0x2D00, 1.0f, 1.0f, 0.1f); + sLib::addCalcScaledDiff(&field_0x2CF4, 6000.0f, 0.05f, field_0x2D00 * 100.0f); + } + // fall-through + } + case DEMO_STATE_3: { + b1 = true; + if (field_0x2CEE > 205) { + sLib::addCalcScaledDiff(&field_0x2D00, 1.0f, 1.0f, 0.1f); + if (field_0x2CEE >= 290) { + if (field_0x2CEE == 290) { + field_0x2D00 = 0.0f; + } + sLib::addCalcScaledDiff(&field_0x2CFC, 50.0f, 0.05f, field_0x2D00); + sLib::addCalcScaledDiff(&field_0x2D10.y, 290.0f, 0.1f, field_0x2D00 * 5.0f); + } else { + sLib::addCalcScaledDiff(&field_0x2CFC, 70.0f, 0.05f, field_0x2D00); + sLib::addCalcScaledDiff(&field_0x2D10.y, 420.0f, 0.1f, field_0x2D00 * 100.0f); + if (field_0x2CEE == 0xFA) { + dLightEnv_c::GetPInstance()->setField_0x38DC(7); + setAnm("CatchThunderEnd", 5.0f); + spawnEffect = true; + effPos.set(field_0x1208.x, field_0x1208.y + 110.0f, field_0x1208.z); + mIsSwordEmpowered = true; + mSwordMdl.fn_8006B800(4); + mCc1.OnTg_0x8000000(); + startSound(SE_BLasBos_ThunderFallSword); + mSubState = SUB_STATE_21; + mTimers[TIMER_3] = cM::rndF(30.0f) + 200.0f; + dRumble_c::start(dRumble_c::sRumblePreset4, dRumble_c::FLAG_ACTIVE | dRumble_c::FLAG_SLOT0); + field_0x2CF0 = 15; + } + if (field_0x2CEE >= 200 && field_0x2CEE <= 250) { + b2 = true; + } + } + } else { + cLib::addCalcPos2(&field_0x2D10, mChestTranslation, 0.1f, 50.0f); + } + break; + } + case DEMO_STATE_100: { + { + // this works but I don't like it + static volatile u32 FLAGS_1 = 0x00000001; + static u32 FLAGS_2 = 0x00100001; + u32 f1 = FLAGS_1; + u32 f2 = FLAGS_2; + Event e = Event("BLS_end", 100, f2 & ~f1, nullptr, nullptr); + EventManager::alsoSetAsCurrentEvent(this, &e, nullptr); + } + if (EventManager::isInEvent(this, "BLS_end")) { + field_0x2CEE = 0; + field_0x2D00 = 0.0f; + field_0x2CFC = 50.0f; + mDemoState = DEMO_STATE_101; + link->onFlags_0x360(0x200); + if (mpSwordBattleGame != nullptr) { + mpSwordBattleGame->notifyBossDeath(false); + } + StoryflagManager::sInstance->setFlagOrCounterToValue(STORYFLAG_692, 0); + dStage_c::GetInstance()->getRoom(0)->someLastBossThing(false); + // fall-through + } else { + break; + } + } + case DEMO_STATE_101: { + b1 = true; + if (field_0x2CEE < 30) { + b2 = true; + } + mtx.YrotS(mRotation.y - 0x4000); + v.set(0.0f, 100.0f, 1500.0f); + MTXMultVec(mtx, v, v); + field_0x2D04 = mBackbone1Translation + v; + field_0x2D10.x = mBackbone1Translation.x; + field_0x2D10.y = 400.0f; + field_0x2D10.z = mBackbone1Translation.z; + sLib::addCalcScaledDiff(&field_0x2CFC, 60.0f, 0.035f, 0.1f); + if (field_0x2CEE == 160) { + field_0x114C = 1; + } + + if (field_0x2CEE >= 159) { + if (field_0x2CEE < 170) { + sLib::addCalcScaledDiff(&field_0x11C4, cM::rndF(0.3f) + 0.7f, 1.0f, 0.4f); + } else { + sLib::addCalcScaled(&field_0x11C4, 1.0f, 0.02f); + } + } else { + if (field_0x2CEE < 10) { + sLib::addCalcScaledDiff(&field_0x11C4, 0.7f, 1.0f, 0.35f); + } else { + sLib::addCalcScaled(&field_0x11C4, 1.0f, 0.035f); + } + } + + if (field_0x2CEE == 230) { + link->offFlags_0x360(0x200); + } + + if (field_0x2CEE == 270 && mpSwordBattleGame != nullptr) { + mDemoState = DEMO_STATE_1000; + } else { + lightEnv.setField_0x5D48(field_0x11C4); + if (field_0x2CEE == 360) { + dScGame_c::GetInstance()->triggerExit(mRoomID, 1); + } + } + break; + } + case DEMO_STATE_200: { + { + // this works but I don't like it + static volatile u32 FLAGS_1 = 0x00000001; + static u32 FLAGS_2 = 0x00100001; + u32 f1 = FLAGS_1; + u32 f2 = FLAGS_2; + Event e = Event("BLS_start", 100, f2 & ~f1, nullptr, nullptr); + EventManager::alsoSetAsCurrentEvent(this, &e, nullptr); + } + if (EventManager::isInEvent(this, "BLS_start")) { + field_0x2CEE = 0; + field_0x2D00 = 0.0f; + field_0x2CFC = 60.0f; + mDemoState = DEMO_STATE_201; + field_0x2D10.set(0.0f, 200.0f, -587.0f); + field_0x2D04.set(0.0f, 197.0f, -207.0f); + dAcPy_c::GetLinkM()->vt_0x2AC(); + dLytBossCaption_c::GetInstance()->show("BOSS_11_caption", 0); + // fall-through + } else { + break; + } + } + case DEMO_STATE_201: { + b1 = true; + sLib::addCalcScaledDiff(&field_0x2D00, 1.0f, 1.0f, 0.05f); + cLib::addCalcPos2(&field_0x2D10, mVec3_c(-2.6f, 118.0f, 298.0f), 0.1f, field_0x2D00 * 80.0f); + cLib::addCalcPos2(&field_0x2D04, mVec3_c(-132.0f, 89.0f, 654.0f), 0.1f, field_0x2D00 * 80.0f); + + if (field_0x2CEE >= 20) { + sLib::addCalcScaledDiff(&field_0x2CFC, 40.0f, 0.05f, 0.1f); + } + + if (field_0x2CEE == 40) { + dAcPy_c::GetLinkM()->triggerMoveEventMaybe(4, 0, 0, nullptr, 0, 1, 0); + } + + if (field_0x2CEE == 110) { + dLytBossCaption_c::GetInstance()->unk_inline(); + } + + if (field_0x2CEE >= 140) { + EventManager::finishEvent(this, nullptr); + dScGame_c::getCamera()->fn_8019EA70(true); + mDemoState = DEMO_STATE_NONE; + unsetActorProperty(AC_PROP_0x4); + } + break; + } + case DEMO_STATE_1000: { + EventManager::finishEvent(this, nullptr); + dScGame_c::getCamera()->fn_8019EA70(true); + mDemoState = DEMO_STATE_NONE; + break; + } + } + + if (spawnEffect) { + dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_624_, effPos, nullptr, nullptr, nullptr, nullptr, 0, 0 + ); + field_0x114A = 10; + } + + if (b1) { + field_0x2CEE++; + mVec3_c tmp1 = field_0x2D10; + if (field_0x2CF0 != 0) { + field_0x2CF0--; + s16 val = field_0x2CF0; + f32 fac = val * 3.0f; + tmp1.y += mAng(val * 0x1C20).cos() * fac; + } + cam->fn_8019EA00(tmp1, field_0x2D04, field_0x2CFC, 0.0f); + if (b2) { + mtx1.transS(0.5f, 0.5f, 0.0f); + // REGSWAP + s32 scale = 95; + mtx1.scaleM(scale / 100.0f, scale / 100.0f, 0.0f); + mtx1.transM(-0.5f, -0.5f, 0.0f); + dStageMgr_c::GetInstance()->procfn_800192F0(0x96, mtx1, 0x32); + } + } + + if (field_0x114C != 0) { + mtx.YrotS(cam->fn_8019E3B0()); + v.set(0.0f, 10.0f, 10000.0f); + MTXMultVec(mtx, v, v); + v.x += cam->getPositionMaybe().x; + v.z += cam->getPositionMaybe().z; + mtx.transS(v); + v.set(0.7f, 0.7f, 0.7f); + mThunderMdl.setScale(v); + mThunderMdl.setLocalMtx(mtx); + mThunderAnmMatClr.play(); + } +} + +void dAcBlastboss_c::setLightningTimerMaybe(s32 arg) { + f32 f = arg + cM::rndF(arg * 0.5f); + + if (mStunCounter >= 2) { + f *= 0.5f; + } else if (mStunCounter == 1) { + f *= 0.75f; + } + + mLightningTimerMaybe = f; +} diff --git a/src/REL/d/a/obj/d_a_obj_warp_hole.cpp b/src/REL/d/a/obj/d_a_obj_warp_hole.cpp index 73228b42..d0ee7416 100644 --- a/src/REL/d/a/obj/d_a_obj_warp_hole.cpp +++ b/src/REL/d/a/obj/d_a_obj_warp_hole.cpp @@ -86,7 +86,7 @@ int dAcOwarpHole_c::actorExecuteInEvent() { if (EventManager::isCurrentEvent("BeforeLastBossBattleChicken")) { dAcPy_c* player = dAcPy_c::GetLinkM(); player->vt_0x2AC(); - player->triggerMoveEventMaybe(2, 0, 0, mLinkPos, 0, 0, 0); + player->triggerMoveEventMaybe(2, 0, 0, &mLinkPos, 0, 0, 0); } } if (dAcPy_c::GetLinkM()->mPosition.absXZTo(mLinkPos) < 10.0f) {