From ad24f6547454d3df064ac6956195a7d8070480e7 Mon Sep 17 00:00:00 2001 From: shibbo Date: Mon, 26 Feb 2024 22:49:52 -0500 Subject: [PATCH] `SkeletalFishBoss.o` 100% --- csv/Boss.csv | 54 +- data/Game.json | 2 +- data/json/Boss.json | 2 +- docs/PROGRESS.md | 2 +- docs/lib/Boss.md | 2 +- docs/lib/Boss/SkeletalFishBoss.md | 56 +- include/Game/Boss/SkeletalFishBoss.hpp | 16 +- include/Game/Util/CameraUtil.hpp | 5 + include/Game/Util/JointController.hpp | 12 +- include/Game/Util/MathUtil.hpp | 4 + include/Game/Util/ScreenUtil.hpp | 4 +- include/Game/Util/SoundUtil.hpp | 2 + .../JSystem/JMath/JMATrigonometric.hpp | 4 + source/Game/Boss/SkeletalFishBoss.cpp | 603 +++++++++++++++++- 14 files changed, 689 insertions(+), 79 deletions(-) diff --git a/csv/Boss.csv b/csv/Boss.csv index 1b8d99e5..e8e331c4 100644 --- a/csv/Boss.csv +++ b/csv/Boss.csv @@ -3009,25 +3009,25 @@ initAfterPlacement__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true makeActorAppeared__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true appear__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true kill__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true -control__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -calcAnim__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -calcJoint__16SkeletalFishBossFPQ29JGeometry64TPosition3>>RC19JointControllerInfo,SkeletalFishBoss.o,Boss.a,false -damage__16SkeletalFishBossFPC9HitSensorRCQ29JGeometry8TVec3,SkeletalFishBoss.o,Boss.a,false -exeSwim__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeOpen__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeOpenWait__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeClose__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeBite__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeDamage__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeDown__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeDeadDamage__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeDead__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeAppearWait__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeAppearDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exePowerUpDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeDeadDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeBreakDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false -exeDemoWait__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false +control__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +calcAnim__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +calcJoint__16SkeletalFishBossFPQ29JGeometry64TPosition3>>RC19JointControllerInfo,SkeletalFishBoss.o,Boss.a,true +damage__16SkeletalFishBossFPC9HitSensorRCQ29JGeometry8TVec3,SkeletalFishBoss.o,Boss.a,true +exeSwim__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeOpen__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeOpenWait__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeClose__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeBite__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeDamage__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeDown__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeDeadDamage__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeDead__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeAppearWait__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeAppearDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exePowerUpDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeDeadDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeBreakDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true +exeDemoWait__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true notifyAttack__16SkeletalFishBossFP17SkeletalFishGuard,SkeletalFishBoss.o,Boss.a,true getCurrentRail__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true getBodyThickness__16SkeletalFishBossCFv,SkeletalFishBoss.o,Boss.a,true @@ -3041,7 +3041,7 @@ initScarFlash__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true initBreakModel__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true initSwitch__16SkeletalFishBossFRC12JMapInfoIter,SkeletalFishBoss.o,Boss.a,true createGuards__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true -initShadow__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,false +initShadow__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true initCamera__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true validateCollision__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true invalidateCollision__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true @@ -3065,13 +3065,13 @@ endPowerUpDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true startDeadDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true endBreakDemo__16SkeletalFishBossFv,SkeletalFishBoss.o,Boss.a,true isEnableToBeDamaged__16SkeletalFishBossCFv,SkeletalFishBoss.o,Boss.a,true -__ct__20SkeletalFishBossHeadFP9LiveActor,SkeletalFishBoss.o,Boss.a,false -movement__20SkeletalFishBossHeadFv,SkeletalFishBoss.o,Boss.a,false -calcAnim__20SkeletalFishBossHeadFv,SkeletalFishBoss.o,Boss.a,false -receiveMsgPlayerAttack__20SkeletalFishBossHeadFUlP9HitSensorP9HitSensor,SkeletalFishBoss.o,Boss.a,false -attackSensor__20SkeletalFishBossHeadFP9HitSensorP9HitSensor,SkeletalFishBoss.o,Boss.a,false -updateCollisionMtx__20SkeletalFishBossHeadFv,SkeletalFishBoss.o,Boss.a,false -createSubModel__20SkeletalFishBossHeadFv,SkeletalFishBoss.o,Boss.a,false +__ct__20SkeletalFishBossHeadFP9LiveActor,SkeletalFishBoss.o,Boss.a,true +movement__20SkeletalFishBossHeadFv,SkeletalFishBoss.o,Boss.a,true +calcAnim__20SkeletalFishBossHeadFv,SkeletalFishBoss.o,Boss.a,true +receiveMsgPlayerAttack__20SkeletalFishBossHeadFUlP9HitSensorP9HitSensor,SkeletalFishBoss.o,Boss.a,true +attackSensor__20SkeletalFishBossHeadFP9HitSensorP9HitSensor,SkeletalFishBoss.o,Boss.a,true +updateCollisionMtx__20SkeletalFishBossHeadFv,SkeletalFishBoss.o,Boss.a,true +createSubModel__20SkeletalFishBossHeadFv,SkeletalFishBoss.o,Boss.a,true __ct__25SkeletalFishBossScarFlashFP9LiveActor,SkeletalFishBoss.o,Boss.a,true init__25SkeletalFishBossScarFlashFRC12JMapInfoIter,SkeletalFishBoss.o,Boss.a,true appear__25SkeletalFishBossScarFlashFv,SkeletalFishBoss.o,Boss.a,true diff --git a/data/Game.json b/data/Game.json index ddbb7839..f32d1f61 100644 --- a/data/Game.json +++ b/data/Game.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, "label": "Game", - "message": "12.949%", + "message": "13.104%", "color": "blue" } \ No newline at end of file diff --git a/data/json/Boss.json b/data/json/Boss.json index abae73d4..0a3a5c0b 100644 --- a/data/json/Boss.json +++ b/data/json/Boss.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, "label": "Boss", - "message": "3.898%", + "message": "5.562%", "color": "orange" } \ No newline at end of file diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index b883c619..c304283f 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -3,7 +3,7 @@ | [Animation](https://github.com/shibbo/Petari/blob/master/docs/lib/Animation.md) | 4.860149543062863% | | [AreaObj](https://github.com/shibbo/Petari/blob/master/docs/lib/AreaObj.md) | 57.68352365415987% | | [AudioLib](https://github.com/shibbo/Petari/blob/master/docs/lib/AudioLib.md) | 0.0% | -| [Boss](https://github.com/shibbo/Petari/blob/master/docs/lib/Boss.md) | 3.898724696777415% | +| [Boss](https://github.com/shibbo/Petari/blob/master/docs/lib/Boss.md) | 5.562028002579733% | | [Camera](https://github.com/shibbo/Petari/blob/master/docs/lib/Camera.md) | 34.12644987572494% | | [Demo](https://github.com/shibbo/Petari/blob/master/docs/lib/Demo.md) | 3.7442572741194486% | | [Effect](https://github.com/shibbo/Petari/blob/master/docs/lib/Effect.md) | 1.855215360664245% | diff --git a/docs/lib/Boss.md b/docs/lib/Boss.md index eba0a090..7574b144 100644 --- a/docs/lib/Boss.md +++ b/docs/lib/Boss.md @@ -131,7 +131,7 @@ | [SkeletalFishBaby.o](https://github.com/shibbo/Petari/blob/master/docs/lib/Boss/SkeletalFishBaby.md) | 0.0% | 0 / 38 | 0.0% | :x: | [SkeletalFishBabyRail.o](https://github.com/shibbo/Petari/blob/master/docs/lib/Boss/SkeletalFishBabyRail.md) | 100.0% | 3 / 3 | 100.0% | :white_check_mark: | [SkeletalFishBabyRailHolder.o](https://github.com/shibbo/Petari/blob/master/docs/lib/Boss/SkeletalFishBabyRailHolder.md) | 100.0% | 12 / 12 | 100.0% | :white_check_mark: -| [SkeletalFishBoss.o](https://github.com/shibbo/Petari/blob/master/docs/lib/Boss/SkeletalFishBoss.md) | 54.48334756618275% | 87 / 114 | 76.31578947368422% | :eight_pointed_black_star: +| [SkeletalFishBoss.o](https://github.com/shibbo/Petari/blob/master/docs/lib/Boss/SkeletalFishBoss.md) | 100.0% | 114 / 114 | 100.0% | :white_check_mark: | [SkeletalFishBossBattleDirector.o](https://github.com/shibbo/Petari/blob/master/docs/lib/Boss/SkeletalFishBossBattleDirector.md) | 100.0% | 14 / 14 | 100.0% | :white_check_mark: | [SkeletalFishBossFunc.o](https://github.com/shibbo/Petari/blob/master/docs/lib/Boss/SkeletalFishBossFunc.md) | 100.0% | 2 / 2 | 100.0% | :white_check_mark: | [SkeletalFishBossInfo.o](https://github.com/shibbo/Petari/blob/master/docs/lib/Boss/SkeletalFishBossInfo.md) | 100.0% | 8 / 8 | 100.0% | :white_check_mark: diff --git a/docs/lib/Boss/SkeletalFishBoss.md b/docs/lib/Boss/SkeletalFishBoss.md index 47250d05..745002aa 100644 --- a/docs/lib/Boss/SkeletalFishBoss.md +++ b/docs/lib/Boss/SkeletalFishBoss.md @@ -5,7 +5,7 @@ | :white_check_mark: | Function is completed. -# 87 / 114 Completed -- (76.31578947368422%) +# 114 / 114 Completed -- (100.0%) # SkeletalFishBoss.o | Symbol | Decompiled? | | ------------- | ------------- | @@ -17,25 +17,25 @@ | `makeActorAppeared__16SkeletalFishBossFv` | :white_check_mark: | | `appear__16SkeletalFishBossFv` | :white_check_mark: | | `kill__16SkeletalFishBossFv` | :white_check_mark: | -| `control__16SkeletalFishBossFv` | :x: | -| `calcAnim__16SkeletalFishBossFv` | :x: | -| `calcJoint__16SkeletalFishBossFPQ29JGeometry64TPosition3>>RC19JointControllerInfo` | :x: | -| `damage__16SkeletalFishBossFPC9HitSensorRCQ29JGeometry8TVec3` | :x: | -| `exeSwim__16SkeletalFishBossFv` | :x: | -| `exeOpen__16SkeletalFishBossFv` | :x: | -| `exeOpenWait__16SkeletalFishBossFv` | :x: | -| `exeClose__16SkeletalFishBossFv` | :x: | -| `exeBite__16SkeletalFishBossFv` | :x: | -| `exeDamage__16SkeletalFishBossFv` | :x: | -| `exeDown__16SkeletalFishBossFv` | :x: | -| `exeDeadDamage__16SkeletalFishBossFv` | :x: | -| `exeDead__16SkeletalFishBossFv` | :x: | -| `exeAppearWait__16SkeletalFishBossFv` | :x: | -| `exeAppearDemo__16SkeletalFishBossFv` | :x: | -| `exePowerUpDemo__16SkeletalFishBossFv` | :x: | -| `exeDeadDemo__16SkeletalFishBossFv` | :x: | -| `exeBreakDemo__16SkeletalFishBossFv` | :x: | -| `exeDemoWait__16SkeletalFishBossFv` | :x: | +| `control__16SkeletalFishBossFv` | :white_check_mark: | +| `calcAnim__16SkeletalFishBossFv` | :white_check_mark: | +| `calcJoint__16SkeletalFishBossFPQ29JGeometry64TPosition3>>RC19JointControllerInfo` | :white_check_mark: | +| `damage__16SkeletalFishBossFPC9HitSensorRCQ29JGeometry8TVec3` | :white_check_mark: | +| `exeSwim__16SkeletalFishBossFv` | :white_check_mark: | +| `exeOpen__16SkeletalFishBossFv` | :white_check_mark: | +| `exeOpenWait__16SkeletalFishBossFv` | :white_check_mark: | +| `exeClose__16SkeletalFishBossFv` | :white_check_mark: | +| `exeBite__16SkeletalFishBossFv` | :white_check_mark: | +| `exeDamage__16SkeletalFishBossFv` | :white_check_mark: | +| `exeDown__16SkeletalFishBossFv` | :white_check_mark: | +| `exeDeadDamage__16SkeletalFishBossFv` | :white_check_mark: | +| `exeDead__16SkeletalFishBossFv` | :white_check_mark: | +| `exeAppearWait__16SkeletalFishBossFv` | :white_check_mark: | +| `exeAppearDemo__16SkeletalFishBossFv` | :white_check_mark: | +| `exePowerUpDemo__16SkeletalFishBossFv` | :white_check_mark: | +| `exeDeadDemo__16SkeletalFishBossFv` | :white_check_mark: | +| `exeBreakDemo__16SkeletalFishBossFv` | :white_check_mark: | +| `exeDemoWait__16SkeletalFishBossFv` | :white_check_mark: | | `notifyAttack__16SkeletalFishBossFP17SkeletalFishGuard` | :white_check_mark: | | `getCurrentRail__16SkeletalFishBossFv` | :white_check_mark: | | `getBodyThickness__16SkeletalFishBossCFv` | :white_check_mark: | @@ -49,7 +49,7 @@ | `initBreakModel__16SkeletalFishBossFv` | :white_check_mark: | | `initSwitch__16SkeletalFishBossFRC12JMapInfoIter` | :white_check_mark: | | `createGuards__16SkeletalFishBossFv` | :white_check_mark: | -| `initShadow__16SkeletalFishBossFv` | :x: | +| `initShadow__16SkeletalFishBossFv` | :white_check_mark: | | `initCamera__16SkeletalFishBossFv` | :white_check_mark: | | `validateCollision__16SkeletalFishBossFv` | :white_check_mark: | | `invalidateCollision__16SkeletalFishBossFv` | :white_check_mark: | @@ -73,13 +73,13 @@ | `startDeadDemo__16SkeletalFishBossFv` | :white_check_mark: | | `endBreakDemo__16SkeletalFishBossFv` | :white_check_mark: | | `isEnableToBeDamaged__16SkeletalFishBossCFv` | :white_check_mark: | -| `__ct__20SkeletalFishBossHeadFP9LiveActor` | :x: | -| `movement__20SkeletalFishBossHeadFv` | :x: | -| `calcAnim__20SkeletalFishBossHeadFv` | :x: | -| `receiveMsgPlayerAttack__20SkeletalFishBossHeadFUlP9HitSensorP9HitSensor` | :x: | -| `attackSensor__20SkeletalFishBossHeadFP9HitSensorP9HitSensor` | :x: | -| `updateCollisionMtx__20SkeletalFishBossHeadFv` | :x: | -| `createSubModel__20SkeletalFishBossHeadFv` | :x: | +| `__ct__20SkeletalFishBossHeadFP9LiveActor` | :white_check_mark: | +| `movement__20SkeletalFishBossHeadFv` | :white_check_mark: | +| `calcAnim__20SkeletalFishBossHeadFv` | :white_check_mark: | +| `receiveMsgPlayerAttack__20SkeletalFishBossHeadFUlP9HitSensorP9HitSensor` | :white_check_mark: | +| `attackSensor__20SkeletalFishBossHeadFP9HitSensorP9HitSensor` | :white_check_mark: | +| `updateCollisionMtx__20SkeletalFishBossHeadFv` | :white_check_mark: | +| `createSubModel__20SkeletalFishBossHeadFv` | :white_check_mark: | | `__ct__25SkeletalFishBossScarFlashFP9LiveActor` | :white_check_mark: | | `init__25SkeletalFishBossScarFlashFRC12JMapInfoIter` | :white_check_mark: | | `appear__25SkeletalFishBossScarFlashFv` | :white_check_mark: | diff --git a/include/Game/Boss/SkeletalFishBoss.hpp b/include/Game/Boss/SkeletalFishBoss.hpp index 7251f606..3310df21 100644 --- a/include/Game/Boss/SkeletalFishBoss.hpp +++ b/include/Game/Boss/SkeletalFishBoss.hpp @@ -28,6 +28,12 @@ public: const char* mShadowName; }; + struct HitPos { + const char* mName; + const char* mSensorName; + Vec mOffset; + }; + typedef void (SkeletalFishBoss::*SceneFunc)(void); SkeletalFishBoss(const char *); @@ -102,12 +108,12 @@ public: SkeletalFishBossHead* mBossHead; // _C8 SkeletalFishBossScarFlash* mScarFlash; // _CC ModelObj* mBreakModel; // _D0 - HitSensor* _D4; + const HitSensor* _D4; TPos3f _D8; SkeletalFishRailControl* mRailControl; // _108 SkeletalFishBossBattleDirector* mBossDirector; // _10C s32 _110; - u32 _114; + s32 _114; u32 _118; CameraTargetMtx* mCameraTargetMtx; // _11C TPos3f _120; @@ -151,10 +157,8 @@ public: CollisionParts* _CC; TMtx34f _D0; CollisionParts* _100; - ModelObj** _104; - u32 _108; - ModelObj** _10C; - u32 _110; + ModelObj* mLightModels[2]; // _104 + ModelObj* mBloomModels[2]; // _10C u8 _114; }; diff --git a/include/Game/Util/CameraUtil.hpp b/include/Game/Util/CameraUtil.hpp index 9c3b4517..9cf5c3a9 100644 --- a/include/Game/Util/CameraUtil.hpp +++ b/include/Game/Util/CameraUtil.hpp @@ -86,4 +86,9 @@ namespace MR { bool isCameraInWater(); void startGlobalEventCameraTargetPlayer(const char *, s32); + + bool isEventCameraActive(); + bool isEventCameraActive(const ActorCameraInfo *, const char *); + + void endGlobalEventCamera(const char *, s32, bool); }; diff --git a/include/Game/Util/JointController.hpp b/include/Game/Util/JointController.hpp index d0862ba6..5c17a00d 100644 --- a/include/Game/Util/JointController.hpp +++ b/include/Game/Util/JointController.hpp @@ -7,8 +7,18 @@ class J3DJoint; class J3DModel; class LiveActor; -struct JointControllerInfo { +struct UnkStruct { + u32 _0; + u32 _4; + u32 _8; + u32 _C; + u32 _10; + u16 _14; +}; +struct JointControllerInfo { + u32 _0; + UnkStruct* _4; }; diff --git a/include/Game/Util/MathUtil.hpp b/include/Game/Util/MathUtil.hpp index 4304f566..7f9ce6c3 100644 --- a/include/Game/Util/MathUtil.hpp +++ b/include/Game/Util/MathUtil.hpp @@ -277,6 +277,10 @@ namespace MR { return remainder; } + inline f32 getZero() { + return 0.0f; + } + f32 cos(f32); f32 sin(f32); }; diff --git a/include/Game/Util/ScreenUtil.hpp b/include/Game/Util/ScreenUtil.hpp index 019d4fa1..84bd0fa6 100644 --- a/include/Game/Util/ScreenUtil.hpp +++ b/include/Game/Util/ScreenUtil.hpp @@ -22,7 +22,7 @@ namespace MR { void setNormalBloomBlurIntensity2(u8); void createScreenBlur(); - void startCenterScreenBlur(long, float, unsigned char, long, long); + void startCenterScreenBlur(s32, f32, u8, s32, s32); void createDepthOfFieldBlur(); void turnOffDOFInSubjective(); @@ -75,4 +75,6 @@ namespace MR { bool isSystemWipeActive(); void closeSystemWipeWhiteFade(s32); + + void setImageEffectControlAuto(); }; diff --git a/include/Game/Util/SoundUtil.hpp b/include/Game/Util/SoundUtil.hpp index 53860270..d458f3bf 100644 --- a/include/Game/Util/SoundUtil.hpp +++ b/include/Game/Util/SoundUtil.hpp @@ -12,6 +12,8 @@ namespace MR { void startStageBGM(const char *, bool); void startStageBGMFromStageName(const char *, const char * , s32); + void startAtmosphereSE(const char *, s32, s32); + void stopStageBGM(u32); void unlockStageBGM(); diff --git a/libs/JSystem/include/JSystem/JMath/JMATrigonometric.hpp b/libs/JSystem/include/JSystem/JMath/JMATrigonometric.hpp index 36ed4092..5be26639 100644 --- a/libs/JSystem/include/JSystem/JMath/JMATrigonometric.hpp +++ b/libs/JSystem/include/JSystem/JMath/JMATrigonometric.hpp @@ -34,6 +34,10 @@ namespace JMath return table[(u16)v & 0x3FFF].a1; } } + + inline f32 get(f32 v) { + return table[(u16)v & 0x3FFF].b1; + } }; template diff --git a/source/Game/Boss/SkeletalFishBoss.cpp b/source/Game/Boss/SkeletalFishBoss.cpp index 78dbdaa1..2f94fb31 100644 --- a/source/Game/Boss/SkeletalFishBoss.cpp +++ b/source/Game/Boss/SkeletalFishBoss.cpp @@ -4,15 +4,18 @@ #include "Game/Boss/SkeletalFishBossRail.hpp" #include "Game/Boss/SkeletalFishBossRailHolder.hpp" #include "Game/Boss/SkeletalFishGuardHolder.hpp" +#include "Game/Boss/SkeletalFishJointCalc.hpp" #include "Game/Boss/SkeletalFishRailControl.hpp" #include "Game/Camera/CameraTargetMtx.hpp" #include "Game/LiveActor/ActorCameraInfo.hpp" #include "Game/LiveActor/ModelObj.hpp" #include "Game/LiveActor/SensorHitChecker.hpp" #include "Game/Map/CollisionParts.hpp" +#include "Game/NameObj/NameObjExecuteHolder.hpp" #include "Game/System/ResourceHolder.hpp" #include #include +#include namespace { static SkeletalFishBoss::SensorToCollider sColInfo[0xE] = { @@ -29,12 +32,39 @@ namespace { { "Joint11", "BackBone11" }, { "Joint12", "BackFin" }, { "LeftFinJoint", "LeftFinJoint" }, - { "RightFinJoint", "RightFinJoint" }, + { "RightFinJoint", "RightFinJoint" } }; + static SkeletalFishBoss::HitPos sHitPosData[0x10] = { + { "Wound0", "Head", { 26.144243f, 414.56268f, 552.11462} } + }; +}; + +namespace { + char* test[] = { + "Shadow00", + "Joint02", + "SkeletalFishBossShadow" + }; static SkeletalFishBoss::JointToShadow sShadowInfo = { "Shadow00", "Joint02", "SkeletalFishBossShadow" - }; + }; + + inline SkeletalFishBoss::JointToShadow& testInline() { + return sShadowInfo; + } + + inline const char* getName(SkeletalFishBoss::JointToShadow& jointToShadow) { + return jointToShadow.mName; + } + + inline const char* getShadowName(SkeletalFishBoss::JointToShadow& jointToShadow) { + return jointToShadow.mShadowName; + } + + inline const char* getJointName(SkeletalFishBoss::JointToShadow& jointToShadow) { + return jointToShadow.mJointName; + } }; SkeletalFishBoss::SkeletalFishBoss(const char *pName) : LiveActor(pName) { @@ -145,13 +175,428 @@ void SkeletalFishBoss::kill() { mScarFlash->kill(); } -// SkeletalFishBoss::control -// SkeletalFishBoss::calcAnim -// SkeletalFishBoss::calcJoint -// SkeletalFishBoss::damage -// SkeletalFishBoss::exeSwim +void SkeletalFishBoss::control() { + ActorCameraInfo info(-1, 0); -// ... + if (MR::isEventCameraActive(&info, "デモ終了後カメラ") && MR::isGreaterEqualStep(this, 60)) { + MR::endGlobalEventCamera("デモ終了後カメラ", -1, true); + } + + if (!isNerve(&::SkeletalFishBossNrvDead::sInstance) && !isNerve(&::SkeletalFishBossNrvAppearWait::sInstance)) { + bool isInDemo = false; + + if (isNerve(&::SkeletalFishBossNrvAppearDemo::sInstance) + || isNerve(&::SkeletalFishBossNrvPowerUpDemo::sInstance) + || isNerve(&::SkeletalFishBossNrvDeadDemo::sInstance)) { + isInDemo = true; + } + + if (!isInDemo) { + mRailControl->update(); + mRailControl->getPos(&mPosition, 0.0f); + updateCollision(); + mGuardHolder->movement(); + updateBgm(); + } + + mBossDirector->tryColumnCollision(mBossHead->getSensor("body")); + } +} + +void SkeletalFishBoss::calcAnim() { + LiveActor::calcAnim(); + TVec3f zDir; + MR::getCameraInvViewMtx()->getZDir(zDir); + zDir.negate(); + + if (!MR::isNoCalcAnim(this)) { + SkeletalFishBoss::JointToShadow* shadow = &sShadowInfo; + f32 idx_mult; + f32 val = MR::getZero(); + idx_mult = 2607.5945f; + JMath::TSinCosTable<14, f32>* tbl = &JMath::sSinCosTable; + + TPos3f jointMtx; + JMath::gekko_ps_copy12(&jointMtx, MR::getJointMtx(this, shadow->mJointName)); + TVec3f trans; + jointMtx.getTrans(trans); + TVec3f gravity; + MR::calcGravityVector(this, trans, &gravity, nullptr, 0); + f32 v4 = 1.8325958f; + v4 = (v4 < val) ? -v4 : v4; + + f32 v10 = (v4 * idx_mult); + f64 e = tbl->get(v10); + + if (zDir.dot(gravity) < e) { + MR::invalidateShadow(this, shadow->mName); + } + else { + MR::validateShadow(this, shadow->mName); + } + + MR::setShadowDropPosition(this, shadow->mName, trans); + MR::setShadowDropDirection(this, shadow->mName, gravity); + } + + mBossHead->updateCollisionMtx(); +} + +bool SkeletalFishBoss::calcJoint(TPos3f *pJointPos, const JointControllerInfo &rInfo) { + if (mJointIndicies[rInfo._4->_14] == -1) { + return false; + } + + SkeletalFishJointCalc::calcJoint(pJointPos, &_120, mRailControl, rInfo); + return true; +} + +void SkeletalFishBoss::damage(const HitSensor *pSensor, const TVec3f &rStarPieceOffs) { + if (isEnableToBeDamaged()) { + _D4 = pSensor; + MR::shakeCameraStrong(); + playDamageBrk(); + + u32 numHitsLeft = _114; + _114--; + + if (_114 == 1 && _110 + 1 == _1A0) { + MR::emitEffect(this, "SkeltalDamageLast"); + } + + if (_114 <= 0) { + if (_110 + 1 == _1A0) { + setNerve(&::SkeletalFishBossNrvDeadDamage::sInstance); + } + else if (MR::isDemoExist("スカルシャークデモ")) { + setNerve(&::SkeletalFishBossNrvDown::sInstance); + } + } + else { + u32 numStarPiece = (_110 + 1 == _1A0) ? 15 : 10; + MR::appearStarPiece(this, rStarPieceOffs, numStarPiece, 10.0f, 14.0f, false); + MR::startSound(this, "SE_OJ_STAR_PIECE_BURST_W_F", -1, -1); + setNerve(&::SkeletalFishBossNrvDamage::sInstance); + } + } +} + +void SkeletalFishBoss::exeSwim() { + if (MR::isFirstStep(this)) { + if (!MR::isBckPlaying(this, "Swim")) { + MR::startBckWithInterpole(this, "Swim", 60); + MR::startBckWithInterpole(mBossHead, "Wait", 60); + } + + mGuardHolder->validate(); + } + + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_FAR", -1, -1, -1); + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_NEAR", -1, -1, -1); + TVec3f mouthPos; + getMouthSensorCenterPos(mouthPos, 5000.0f); + + bool isClose = PSVECDistance(mouthPos.toCVec(), MR::getPlayerPos()->toCVec()) < 5000.0f; + + if (isClose) { + setNerve(&::SkeletalFishBossNrvOpen::sInstance); + } +} + +void SkeletalFishBoss::exeOpen() { + if (MR::isFirstStep(this)) { + MR::startBck(mBossHead, "Open", nullptr); + MR::startSound(mBossHead, "SE_B_SKL_BOSS_MOUTH_OPEN", -1, -1); + } + + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_FAR", -1, -1, -1); + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_NEAR", -1, -1, -1); + + if (MR::isBckStopped(mBossHead)) { + MR::startBck(mBossHead, "OpenWait", nullptr); + setNerve(&::SkeletalFishBossNrvOpenWait::sInstance); + } +} + +void SkeletalFishBoss::exeOpenWait() { + TVec3f mouthPos; + getMouthSensorCenterPos(mouthPos, 7800.0f); + bool isClose = PSVECDistance(mouthPos.toCVec(), MR::getPlayerPos()->toCVec()) < 7000.0f; + + if (isClose) { + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_FAR", -1, -1, -1); + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_NEAR", -1, -1, -1); + } + else { + setNerve(&::SkeletalFishBossNrvClose::sInstance); + } +} + +void SkeletalFishBoss::exeClose() { + if (MR::isFirstStep(this)) { + MR::startBck(mBossHead, "Close", nullptr); + MR::startSound(mBossHead, "SE_BM_SKL_BOSS_MOUTH_CLOSE", -1, -1); + } + + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_FAR", -1, -1, -1); + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_NEAR", -1, -1, -1); + + if (MR::isBckStopped(mBossHead)) { + MR::startBck(mBossHead, "Wait", nullptr); + setNerve(&::SkeletalFishBossNrvSwim::sInstance); + } +} + +void SkeletalFishBoss::exeBite() { + if (MR::isFirstStep(this)) { + MR::startBck(mBossHead, "Bite", nullptr); + } + + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_FAR", -1, -1, -1); + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_NEAR", -1, -1, -1); + + if (MR::isBckStopped(mBossHead)) { + MR::startBck(mBossHead, "Wait", nullptr); + setNerve(&::SkeletalFishBossNrvSwim::sInstance); + } +} + +void SkeletalFishBoss::exeDamage() { + if (MR::isFirstStep(this)) { + startDamageAnim(); + MR::startSound(mBossHead, "SE_BM_SKL_BOSS_DAMAGE_S", -1, -1); + MR::startSystemSE("SE_SY_VS_BOSS_DAMAGE_1", -1, -1); + mGuardHolder->invalidate(); + } + + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_FAR", -1, -1, -1); + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_NEAR", -1, -1, -1); + + if (MR::isBckStopped(this)) { + if (_114 == 2) { + MR::startBrk(this, "Damage1Color"); + MR::startBrk(mBossHead, "Damage1Color"); + } + else if (_114 == 1) { + MR::startBrk(this, "Damage2Color"); + MR::startBrk(mBossHead, "Damage2Color"); + } + + setNerve(&::SkeletalFishBossNrvSwim::sInstance); + MR::appearStarPiece(this, mPosition, 6, 10.0f, 40.0f, false); + MR::startSound(this, "SE_OJ_STAR_PIECE_BURST_W_F", -1, -1); + } +} + +void SkeletalFishBoss::exeDown() { + if (MR::isFirstStep(this)) { + startDamageAnim(); + MR::startSound(mBossHead, "SE_BM_SKL_BOSS_DAMAGE_L", -1, -1); + MR::startSystemSE("SE_SY_BOSS_DAMAGE_3", -1, -1); + mGuardHolder->invalidate(); + + if (_110 == 1) { + MR::startBva(this, "Crack"); + MR::startBva(mBossHead, "Crack"); + } + } + + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_FAR", -1, -1, -1); + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_NEAR", -1, -1, -1); + + if (MR::isStep(this, 120)) { + stopScene("スカルシャークパワーアップ", &::SkeletalFishBossNrvPowerUpDemo::sInstance, &SkeletalFishBoss::startPowerUpDemo); + } +} + +void SkeletalFishBoss::exeDeadDamage() { + if (MR::isFirstStep(this)) { + startDamageAnim(); + MR::startSound(mBossHead, "SE_BM_SKL_BOSS_DAMAGE_LAST", -1, -1); + MR::startSystemSE("SE_SY_VS_BOSS_LAST_HIT", -1, -1); + mGuardHolder->invalidate(); + mGuardHolder->killAll(); + mBossHead->_114 = 0; + } + + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_FAR", -1, -1, -1); + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_NEAR", -1, -1, -1); + + if (MR::isStep(this, 120)) { + MR::stopStageBGM(30); + stopScene("スカルシャーク死亡", &::SkeletalFishBossNrvDeadDemo::sInstance, &SkeletalFishBoss::startDeadDemo); + } +} + +void SkeletalFishBoss::exeDead() { + if (MR::isFirstStep(this)) { + Mtx pos; + if (MR::tryFindNamePos("マリオ再セット位置2", pos)) { + MR::setPlayerBaseMtx(pos); + } + + resetCamera(); + } + else { + ActorCameraInfo info(-1, 0); + bool isCameraActive = MR::isEventCameraActive(&info, "デモ終了後カメラ") == false; + if (isCameraActive) { + kill(); + } + } +} + +void SkeletalFishBoss::exeAppearWait() { + if (!MR::isPlayerInBind() && !MR::isEventCameraActive()) { + stopScene("スカルシャーク出現", &::SkeletalFishBossNrvAppearDemo::sInstance, &SkeletalFishBoss::startAppearDemo); + } +} + +void SkeletalFishBoss::exeAppearDemo() { + if (MR::isFirstStep(this)) { + MR::showModel(this); + MR::startBck(this, "BattleStart", nullptr); + MR::startBck(mBossHead, "BattleStart", nullptr); + MR::stopStageBGM(60); + mBossDirector->appearBirdLouse(); + mGuardHolder->invalidate(); + } + + if (MR::isStep(this, 280)) { + MR::startStageBGM("MBGM_BOSS_09_A", false); + } + + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_APPEAR", -1, -1, -1); + + if (MR::isBckStopped(this)) { + if (!MR::isPlayingStageBgm()) { + MR::startStageBGM("MBGM_BOSS_09_A", false); + } + + _1B4 = 120; + mBossDirector->killBirdLouse(); + endAppearDemo(); + } +} + +void SkeletalFishBoss::exePowerUpDemo() { + if (MR::isFirstStep(this)) { + MR::showModel(this); + powerUp(); + mGuardHolder->invalidate(); + mGuardHolder->forceKillAll(); + mRailControl->_14 = 60.0f; + + if (_110 == 1) { + MR::startBck(this, "PowerUp1", nullptr); + MR::startBck(mBossHead, "PowerUp1", nullptr); + mBossDirector->startPowerUpDemo1(); + } + else { + MR::startBck(this, "PowerUp2", nullptr); + MR::startBck(mBossHead, "PowerUp2", nullptr); + mBossDirector->startPowerUpDemo2(); + } + + mBossDirector->appearBirdLouse(); + + if (_110 > 1) { + MR::stopStageBGM(30); + } + } + + if (_110 == 2 && MR::isStep(this, 240)) { + MR::startAtmosphereSE("SE_BM_SKL_GUARD_COME_FRONT", -1, -1); + } + + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_POW_UP", -1, -1, -1); + + if (MR::isBckStopped(this)) { + if (_110 > 1) { + MR::startStageBGM("MBGM_BOSS_09_B", false); + } + + _1B4 = 120; + mBossDirector->killBirdLouse(); + endPowerUpDemo(); + } +} + +void SkeletalFishBoss::exeDeadDemo() { + if (MR::isFirstStep(this)) { + MR::startBck(this, "Down", nullptr); + MR::startBrk(this, "Down"); + MR::startBck(mBossHead, "Down", nullptr); + MR::startBrk(mBossHead, "Down"); + MR::startSound(mBossHead, "SE_BM_SKL_BOSS_MOUTH_OPEN", -1, -1); + MR::setImageEffectControlAuto(); + mGuardHolder->invalidate(); + mBossDirector->appearBirdLouse(); + } + + if (MR::isStep(this, 30)) { + MR::startSound(mBossHead, "SE_BM_SKL_BOSS_BODY_SOLID", -1, -1); + } + + if (MR::isLessStep(this, 218)) { + MR::startLevelSound(mBossHead, "SE_BM_LV_SKL_BOSS_SWIM_DIE", -1, -1, -1); + } + + if (MR::isBckStopped(this)) { + mBossDirector->killBirdLouse(); + MR::overlayWithPreviousScreen(2); + setNerve(&::SkeletalFishBossNrvBreakDemo::sInstance); + } +} + +void SkeletalFishBoss::exeBreakDemo() { + if (MR::isFirstStep(this)) { + MR::hideModel(this); + mBossHead->kill(); + mBreakModel->makeActorAppeared(); + MR::requestMovementOn(mBreakModel); + MR::startBck(mBreakModel, "Break", nullptr); + MR::startBrk(mBreakModel, "Break"); + MR::startSound(mBossHead, "SE_BM_SKL_BOSS_EXPLODE", -1, -1); + mGuardHolder->invalidate(); + mBossDirector->appearBirdLouse(); + MR::tryRumblePadMiddle(this, 0); + } + + if (MR::isStep(this, 204)) { + MR::tryRumblePadStrong(this, 0); + } + + if (MR::isStep(this, 206)) { + MR::startSound(mBossHead, "SE_BM_SKL_BOSS_EXPLODE_2", -1, -1); + } + + if (MR::isStep(this, 0)) { + MR::startCenterScreenBlur(60, 5.0f, 0x50, 5, 30); + } + + if (MR::isStep(this, 200)) { + MR::startCenterScreenBlur(60, 80.0f, 0x50, 5, 30); + } + + if (MR::isBckStopped(mBreakModel)) { + MR::startAfterBossBGM(); + mBossDirector->killBirdLouse(); + endBreakDemo(); + setNerve(&::SkeletalFishBossNrvDead::sInstance); + } +} + +void SkeletalFishBoss::exeDemoWait() { + if (MR::tryStartDemo(this, mCurScene)) { + (this->*mSceneFunc)(); + MR::requestMovementOn(this); + MR::requestMovementOn(mBossHead); + MR::requestMovementOn(mScarFlash); + mBossDirector->pauseOffCast(); + setNerve(mSceneNerve); + } +} void SkeletalFishBoss::notifyAttack(SkeletalFishGuard *pGuard) { mGuardHolder->notifyAttack(pGuard); @@ -259,14 +704,17 @@ void SkeletalFishBoss::createGuards() { mGuardHolder = new SkeletalFishGuardHolder(this, _1A4, "スカルシャークガード管理"); } -#ifdef NON_MATCHING void SkeletalFishBoss::initShadow() { MR::initShadowController(this, 1); - MR::addShadowVolumeFlatModel(this, "Shadow00", sShadowInfo.mShadowName, MR::getJointMtx(this, sShadowInfo.mJointName)); - MR::setShadowDropLength(this, sShadowInfo.mName, 4000.0f); + SkeletalFishBoss::JointToShadow& shadow = testInline(); + const char** bruh = (const char**)test; + const char* name = bruh[0]; + MtxPtr mtx = MR::getJointMtx(this, bruh[1]); + //SkeletalFishBoss::JointToShadow* shadow = &sShadowInfo; + MR::addShadowVolumeFlatModel(this, name, test[2], mtx); + MR::setShadowDropLength(this, name, 4000.0f); MR::excludeCalcShadowToSensorAll(this, mBossHead->getSensor("body")); } -#endif void SkeletalFishBoss::initCamera() { ActorCameraInfo cameraInfo(-1, 0); @@ -578,6 +1026,137 @@ bool SkeletalFishBoss::isEnableToBeDamaged() const { return isDmg; } +SkeletalFishBossHead::SkeletalFishBossHead(LiveActor *pActor) : PartsModel(pActor, "スカルシャーク頭", "SkeletalFishBossHeadA", nullptr, 0x12, false) { + initFixedPosition("Head"); + initHitSensor(17); + MR::addHitSensorAtJointEnemy(this, "body", "Head", 8, 400.0f, TVec3f(0.0f, -120.0f, 320.0f)); + + for (u32 i = 0; i < 0xD; i++) { + //SkeletalFishBoss::HitPos* data = &sHitPosData[i]; + TVec3f offset(sHitPosData[i].mOffset); + //offset.setInlinePS((TVec3f)data->mOffset); + offset.scale(9.0f / 10.0f); + MR::addHitSensorAtJointEnemyAttack(this, sHitPosData[i].mName, sHitPosData[i].mSensorName, 8, 270.0f, offset); + } + + MR::initLightCtrl(this); + _9C.identity(); + _CC = MR::createCollisionPartsFromLiveActor(this, "Head", getSensor("body"), (MR::CollisionScaleType)2); + MR::validateCollisionParts(_CC); + _D0.identity(); + _100 = MR::createCollisionPartsFromLiveActor(this, "Jow", getSensor("body"), (MR::CollisionScaleType)2); + MR::validateCollisionParts(_100); + MR::addToAttributeGroupSearchTurtle(this); + createSubModel(); +} + +void SkeletalFishBossHead::attackSensor(HitSensor *a1, HitSensor *a2) { + if (MR::isSensor(a1, "body")) { + LiveActor* host = mHost; + bool curFlag = false; + + if (host->isNerve(&::SkeletalFishBossNrvDeadDamage::sInstance) + || host->isNerve(&::SkeletalFishBossNrvDead::sInstance)) { + curFlag = true; + } + + if (!curFlag) { + if (MR::isSensorPlayer(a2)) { + curFlag = false; + + if (host->isNerve(&::SkeletalFishBossNrvAppearDemo::sInstance) + || host->isNerve(&::SkeletalFishBossNrvPowerUpDemo::sInstance) + || host->isNerve(&::SkeletalFishBossNrvDeadDemo::sInstance)) { + curFlag = true; + } + + if (!curFlag) { + if (host->isNerve(&::SkeletalFishBossNrvDamage::sInstance)) { + MR::sendMsgPush(a2, a1); + } + else { + MR::sendMsgPush(a2, a1); + + if (host->isNerve(&::SkeletalFishBossNrvOpenWait::sInstance)) { + host->setNerve(&::SkeletalFishBossNrvBite::sInstance); + } + } + } + } + else if (!MR::isSensorEnemyAttack(a1) && MR::isSensorEnemy(a2)) { + MR::sendMsgEnemyAttack(a2, a1); + } + } + } +} + +void SkeletalFishBossHead::movement() { + PartsModel::movement(); + + if (_114) { + if (MR::isConnectToDrawTemporarily(this) && !MR::isHiddenModel(this)) { + if (!MR::isConnectToDrawTemporarily(mLightModels[0])) { + for (s32 i = 0; i < 2; i++) { + MR::disconnectToDrawTemporarily(mLightModels[i]); + MR::disconnectToDrawTemporarily(mBloomModels[i]); + } + } + } + else if (MR::isConnectToDrawTemporarily(mLightModels[0])) { + for (s32 i = 0; i < 2; i++) { + MR::connectToDrawTemporarily(mLightModels[i]); + MR::connectToDrawTemporarily(mBloomModels[i]); + } + } + } + else if (MR::isConnectToDrawTemporarily(mLightModels[0])) { + for (s32 i = 0; i < 2; i++) { + MR::disconnectToDrawTemporarily(mLightModels[i]); + MR::disconnectToDrawTemporarily(mBloomModels[i]); + } + } +} + +void SkeletalFishBossHead::calcAnim() { + PartsModel::calcAnim(); + + if (MR::isConnectToDrawTemporarily(this)) { + for (s32 i = 0; i < 2; i++) { + mLightModels[i]->calcAnim(); + mBloomModels[i]->calcAnim(); + } + } +} + +bool SkeletalFishBossHead::receiveMsgPlayerAttack(u32 msg, HitSensor *a2, HitSensor *a3) { + if (MR::isMsgJetTurtleAttack(msg)) { + SkeletalFishBoss* boss = (SkeletalFishBoss*)mHost; + boss->damage(a3, a2->mPosition); + return true; + } + + return MR::isMsgStarPieceReflect(msg); +} + +void SkeletalFishBossHead::updateCollisionMtx() { + JMath::gekko_ps_copy12(&_9C, MR::getJointMtx(this, "Head")); + JMath::gekko_ps_copy12(&_D0, MR::getJointMtx(this, "Jow")); +} + +void SkeletalFishBossHead::createSubModel() { + const char* coneMdls[2] = { "LightConeLeft", "LightConeRight" }; + + for (s32 i = 0; i < 2; i++) { + mLightModels[i] = new ModelObj("眼光", "SkeletalFishBossLight", MR::getJointMtx(this, coneMdls[i]), 18, -1, -1, false); + mLightModels[i]->initWithoutIter(); + MR::invalidateClipping(mLightModels[i]); + + mBloomModels[i] = new ModelObj("眼光ブルーム", "SkeletalFishBossLightBloom", MR::getJointMtx(this, coneMdls[i]), 30, -1, -1, false); + mBloomModels[i]->initWithoutIter(); + MR::invalidateClipping(mBloomModels[i]); + } +} + SkeletalFishBossScarFlash::SkeletalFishBossScarFlash(LiveActor *pActor) : PartsModel(pActor, "スカルシャーク傷跡エフェクトモデル", "SkeletalFishBossScarFlash", nullptr, 0x12, false) { initFixedPosition("Head"); }