summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpetrie911 <69443847+petrie911@users.noreply.github.com>2021-08-08 14:26:56 -0500
committerGitHub <noreply@github.com>2021-08-08 15:26:56 -0400
commit6ce382bc8d2d33ed3233daf4e2e0add7f4b0f827 (patch)
tree540a2b01bea3c814e7d5303e94c802cf4d4deac6 /src
parent65f65870a115c7310c960e316800904295477dd1 (diff)
Morpha (ovl_Boss_Mo) (#438)
* Darkmeiro decompilation Bg_Gnd_Darkmeiro decompiled, matched, and documented. * give this a shot * fix conflict * one more try * it begins * more functions * another match * starting documentation * the big function works. also two more matches * small fix * data cleanup * removed .s * match with player * inching closer to matching * two more matches. almost there * OH MY GOD IT MATCHES * cleanup: part 1 of infinity * named a bunch of stuff * Naming particle fields * terminal commas * terminal commas * small enum fix * added description of droplet widths * merge * updating * Gfx * vt * xml * bgcheck * more on objects * unused stuff * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "44f5d7cb9" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "44f5d7cb9" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "6f874af4a" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "6f874af4a" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * object names * fixes * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "6f874af4a" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "6f874af4a" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "0305ec2c2" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "0305ec2c2" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * ZAPD works * .s * merge * starting work * more stuff * builds OK * first pass * PR fixes (Louis) * Bg_toki_hikari all functions matching (#781) * starting toki_hikari * func_808BA018 matched and some work on other func * init and draw matched, one to go * matched final function, removed ASM, updated spec * adding suggested changes * Volvagia (ovl_Boss_Fd) and related actors (#352) * Darkmeiro decompilation Bg_Gnd_Darkmeiro decompiled, matched, and documented. * Lots of functions matched. Some big ones are close. * Five left unmatched, one close. * Merged data and decompiled the giant function into something readable. Its branch structure has yet to be matched. * Three unmatched, one essentially matched, the rest matched. * More fixes. * Documented more of the structure and cleaned up a bit. * BossFd2, BgVbSima, and EnVbBall matched and documented * Also removed unneeded .s files * And need to name EnVbBall's functions * give this a shot * fix conflict * one more try * removing darkmeiro changes * and again * now OK from make clean * minor cleanup * One more matching function for BossFd * which means it doesn't need its .s * splitting * splitting * splitting * forgot some .s * fancy new names * fancy new names * trying again * sneaky .s files * sound effects and some hex to decimal conversions * Sound effects and static variable cleanup * format.sh and clean up static variables * sfx and formatting * ZAP and cleanup * small cleanup * cleanup and ZAP * ZAP * looking at the giant function again * looking at the giant function again * Only the big function left. * Those .s files aren't mine, officer * float literals might be fixed. regalloc still a nightmare * almost done with the big function * should make now * not much of a change * all functions match. rodata somehow doesn't. * forgot some things * lots of cleanup * and a little more * small error * large cleanup. Also BossFd has function names and inlined variable declarations * still more cleanup * the quest for 0.1f continues * forgot to put NON_MATCHING back in * Data structures fully documented. Still more cleanup. * DECR now works with BossFd2 * should match now * cleanup * small cleanup * cleanup and names * tiny thing * particles and headers and stuff * now with more enums * merge * test * end test * update * cleanup * object 2 * object 1 * doc object_fd2 * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "6f874af4a" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "6f874af4a" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * formatting * .s * merge actor * vertex arrays * a little more * formatting * merge opd * fixed damage check * cleanup * fixes * effect struct * review Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain> Co-authored-by: fig02 <fig02srl@gmail.com> * fix mistake in z_bg_hidan_hamstep (#771) if you're just going to close this pr just wait a week and review it then. * ovl_En_River_Sound 1 non-matching (#786) * ovl_En_River_Sound * Implement review suggestions, run through clang-format * Responding to PR comments * Use CHECK_QUEST_ITEM, run through clang-tidy. * EnTp, 1 nonmatching, and object_tp (#782) * Data imported, 8 easy functions matched * Init only remaining nonmatching, data in * some renaming & fiddling with Init, still nonmatching * fix colours * Init still not matching * Decompile object_tp * renames * Rename func_80B20DE0 * Horrible new idea * Known equivalent, docs next * Another attempt * Finished naming in object_tp * Named functions, more enums * DrawBridge -> Drawbridge * skulltulla -> Skulltula * Name almost all struct variables * Named most of the temps * delete asm * spec * Missed data file, whoops * Review * More review changes * cleanup en_dha (#787) * Set __FILE__ in asm_processor (#793) * Set __FILE__ in asm_processor * bss fix * Update to upstream version Co-authored-by: zelda2774 <zelda2774@invalid> * ovl_Efc_Erupc OK (#773) * a few good dead Gfx_TwoTexScrolls * EfcErupc OK, mostly documented * review * remove fake match Co-authored-by: Fig02 <fig02srl@gmail.com> * z_bg_mizu_movebg and object_mizu_objects (#747) * OK a few functions * BgMizuMovebg_Draw OK, make tweaks to bg_mizu_bwall * migrate data * create mizu_objects, defines for water temple water level * clean up some code * implement most suggestions * review * review2 * formatting Co-authored-by: Fig02 <fig02srl@gmail.com> * Document BodyBreak (en_part, body part spawner) (#797) * done * status defines * whoops * comment wording * size calc change * elseif * Improve the format in z_map_mark_data.c and cleanup mapmark.py (#798) * Cleanup mapmark.py script * Rename map mark defines * Remove unused entries from map_mark_data * `assert` macro OK (#755) * create assert macro and replace a bunch of __assert Signed-off-by: angie <angheloalf95@gmail.com> * Another bunch of assert Signed-off-by: angie <angheloalf95@gmail.com> * more assert Signed-off-by: angie <angheloalf95@gmail.com> * assert(false) Signed-off-by: angie <angheloalf95@gmail.com> * last assert used in matching code Signed-off-by: angie <angheloalf95@gmail.com> * the non-matchings Signed-off-by: angie <angheloalf95@gmail.com> * typo Signed-off-by: angie <angheloalf95@gmail.com> * format Signed-off-by: angie <angheloalf95@gmail.com> * change macro to uppercase Signed-off-by: angie <angheloalf95@gmail.com> * Apply suggestions from code review Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com> * Change ASSERT(false) to ASSERT(0) Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com> * General object cleanup (#799) * Object cleanup * Fix running man * fix mm symbols * Updated to use latest version of ZAPD (#777) * Updated config file * Added missing files * Temporarily removed asm_processor changes. * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "96ffc1e62" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "96ffc1e62" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "179af7d11" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "179af7d11" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * Cleanup and fixes. * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "50ad2fe78" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "50ad2fe78" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * Makefile fix * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "b9120803e" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "b9120803e" git-subrepo: version: "0.4.3" origin: "???" commit: "???" Co-authored-by: Jack Walker <7463599+Jack-Walker@users.noreply.github.com> * Decompile `object_zo` :dolphin: (#794) * Initial xml * most of in-code references * Add limbs and evrything else * Functions used by EnRiverSound * Fix forearm and use void* for textures * Run formatter * Change Hints in scene's XMLs (#800) * Remove blobhint * Add segments and offsets, and remove most hints * Change PathHint to Path * Add missing final new lines in scenes xmls * finished object_skb (#790) * finished object_skb * neglected the limbs and dlists, so I added them * adding the textures * fixing some names * ....forgot to change the c file.... * hopefully fixed formatting issue * EnFish, OK and documented (#795) * Matching * Some naming * spec * Name another function * Name animations, clarify use of GI_MAX and GI_NONE * Documented bottle range functions * Simplify squared distance function in EnIceHono, actor descriptions * Functions for dropped fish * More naming * Change 65535.5f to (0xFFFF + 0.5f) * Change 65535.5f to (0xFFFF + 0.5f) * name phases * Named other types, Docile functions * Naming complete * delete asm * format, remove outdated comment * Fix a few DrawFlexOpa arguments * Review changes * Change back to original playSound * Function comments per review * Update asm-processor and add make dependencies for global asm and early includes (#801) * Update asm-processor to latest master * Add make dependencies for global asm and early includes * Update asm-processor to latest master * Decompile the pause menu aka. ovl_kaleido_scope (+ minor changes) (#803) * Decompile ovl_kaleido_scope + minor cleanups * Add a common header for ovl_kaleido_scope * Start cleaning up and documenting kaleido_scope (+ some interface docs) * Improve and fix some kaleido_scope non matchings * Match KaleidoSetup_Init * Extract icon_item_fra/ger_static files * Add more documentation and matches to kaleido_scope * Improve the z_kaleido_collect.c non matching * Rename z_kaleido_8081EFF0.c to z_kaleido_prompt.c * Update most kaleido variables to be static * Improve GS flag macros * Improve z_lmap_mark.c and extract z_lmap_mark_data.c with a script * Various minor fixes and improvements * Minor fixes and review changes * Review changes part 2 * Rename gSetTileCustom to gDPSetTileCustom * Review changes part 3 * Delete `-j` from `make setup` and document use of `-jN` and `-j` in readme (#804) * Add nproc to make setup * Add cross-platform nproc equivalents * Scrap that, just ditch -j in makefile altogether * Clarified thread advice * ViMode progress (#802) * ViMode OK * Fix variable name in regconvert tool * ViMode: fix formatting * Add nonmatching impl for ViMode_Configure, respond to PR - Fixed struct field naming (unkXX -> unk_XX) - ViMode_Configure args are not flags for top/left etc; seem to be for video mode - Used @Random06457's implementation of `ViMode_LogPrint` * Use plain LOG_ADDRESS in ViMode_LogPrint * Incorporate PR feedback from Roman971 * Add scene macros (#792) * add scene macros * SCENECMD -> SCENE_CMD * light renaming * SCENE_CMD_ROOM_BEHAVIOR * update params names * Remove extra spaces * More review changes by fig * remove MM cmd ids * more review changes * last minute edit * I keep confusing both lights commands * Review changes * Yet another cutscene change * Unused02 is unused * Add UNK_09 macro and other minor fixes (#813) (cherry picked from commit d3a6d4d2e1794f3b12f22d7808d65f24ef4c220a) * Match BossFd_Fly (ovl_Boss_Fd OK) (#807) * Simplify PNGs rules in the makefile (#814) * simplify rules * update `-eh` * Add every unreserved object in an automated way (#805) * it's crashing * fix stuff * fix xmls * problematic objects * fix tabs * Fix suffixes * add missing new lines * Add comments to the problematic objects * Find and replace fixes * Add Fig's objects * I forgot to add a Name in a cutscene, so I'm adding it here * Update object decomp tutorial a little bit * Update problematic objects * Update docs/tutorial/object_decomp.md Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * Change comments * comment out a few blobs * dammit tluts * Change a bunch of objects * update the last bunch * update comments on oA11 and oB2 * Ninja-edit to fix compatibility with ZAPD's PR 142 Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * Add clean assets (#785) * makefile change * also delete * Add cleantools * rename cleanassets and assetclean * add rules to PHONY in makefile * Remove toolsclean * object_hata OK (#806) * everything except limbs * spec * object_hata OK * Replace symbols, unused data, enums, some cleanup * Fix compiler warnings in EnRiverSound * Address Roman's review * Correct limbs name * Changed unk_192 to timer, as well as add missing trailing comma for formating (#817) * Remove some unused duplicated C files (#818) * Removes qemu from the README.md (#819) * Removes qemu from the README.md * Increments the step references in other parts of the README.md * Update README.md Co-authored-by: Anghelo Carvajal <anghelo.carvajal.14@sansano.usm.cl> * Update README.md Co-authored-by: Anghelo Carvajal <anghelo.carvajal.14@sansano.usm.cl> * Update README.md Co-authored-by: Anghelo Carvajal <anghelo.carvajal.14@sansano.usm.cl> * Update README.md Co-authored-by: Anghelo Carvajal <anghelo.carvajal.14@sansano.usm.cl> Co-authored-by: Anghelo Carvajal <anghelo.carvajal.14@sansano.usm.cl> * Match EnSkb_PostLimbDraw (obl_en_skb OK) (#821) * Small bgcheck documentation pass (#816) * implement some documentation * remove unnecessary comments related to decomp * eliminate comment function prototypes * Add `actorfixer.py` ~~and `graphovl.py`~~; and a few improvements to `extract_assets.py` (#783) * Only process touched files and abort the extraction if one file wasn't extracted properly Signed-off-by: angie <angheloalf95@gmail.com> * add actorfixer and graphovl Signed-off-by: angie <angheloalf95@gmail.com> * Re set execution permisions to diff.py Signed-off-by: angie <angheloalf95@gmail.com> * Add graphs/ to gitignore Signed-off-by: angie <angheloalf95@gmail.com> * Add looners flag to graphovl Signed-off-by: angie <angheloalf95@gmail.com> * Parse macros Signed-off-by: angie <angheloalf95@gmail.com> * cleanup Signed-off-by: angie <angheloalf95@gmail.com> * Add enum parser to graphovl Signed-off-by: angie <angheloalf95@gmail.com> * Remove redundant code Signed-off-by: angie <angheloalf95@gmail.com> * cleanup Signed-off-by: angie <angheloalf95@gmail.com> * Custom colors to graphovl! * Select multiples styles for graphovl * Add solarized light style * Add renames of #796 * Add unaccounted warning flag * remove graphovl * git subrepo clone https://github.com/AngheloAlf/graphovl.git tools/graphovl subrepo: subdir: "tools/graphovl" merged: "577e71592" upstream: origin: "https://github.com/AngheloAlf/graphovl.git" branch: "master" commit: "577e71592" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * remove graphovl * Add `graphovl/` to gitignore * Label a bug in Door_Shutter (#810) * comment * Update src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * Update src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * Update src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c Co-authored-by: pixel-stuck <mathmcclintic@gmail.com> * change message * typo * repeated myself * extra space lmao * change wording again * Update src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c * indent Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Co-authored-by: pixel-stuck <mathmcclintic@gmail.com> * en_weather_tag Quick documentation pass (#808) * Quick documentation pass * Fill out the En_Weather_Tag enum * move the enum into the header * implement roman's suggestion * object_sa OK (#789) * object_sa OK * PR fixes (AngheloAlf) * PR fixes (Roman) * Improve z_jpeg documentation (#825) * Improve z_jpeg documentation * JpegWork::data is probably better than address * Rename Jpeg_SendTask to Jpeg_ScheduleDecoderTask * Rename njpegUCode to gJpegUCode * Rename GetU16 to GetUnalignedU16 and improve docs * Decompile a bunch of objects (#603) * Mostly done but shifted * still messed up * Almost OK * OBJECT_JYA_OBJ OK, OBJECT_GR OK * Done * Merge master and format * Cleanup * Cleanup 2 * Start object MB dont merge yet * Object_MB OK * Object_ydan_objects OK * General 'ydan' actor cleanup * Forgot some small things * Object_EC OK * add .gitkeep and run format * Object_sd OK but no textures cause of a zap issue * PR fixes * Fix object_sd * fix ydan * delete .gitkeep files * OBJECT_BOX as far as it can go with current ZAP * Fix undefined_syms * Start child link object * Push progress, dont merge yet * Object_mori_objects OK * Fixed? * Fix conflicts again * Seems like i missed some textures * Extract data for BgBombwall * More field * ZAP YEP 2.0 * Object_Box OK * Object_SD ok. Ready to merge * remove ASM and merge master * remove ASM * remove files wrongfully added to docs/ * Almost done * Change comment in z_player_lib.c * forgot some DLists in player_lib.c * Fix conflict, run format * Same as before but this time with Tex and TLUT * Last few things * fix object_GR and add limbs to object_sd * Nane -> Name * gChildDekuShieldMtx is now a matrix and not a blob * PR fixes (Fig) * add a space for comment in z_player_lib.c * re push and new lines * PR fixes (AngheloAlf) * PR fixes (Roman) * Fix Heishi2 * PR fixes (Fig) * Replace spacing in a file * PR fixes (Roman) * Track XML extraction time (#826) * extracted-assets.json * delete `.extracted-assets.json` in distclean * Move `rm .extracted-assets.json` to `assetclean` * Outname -> OutName for OBJECT_LINK_CHILD (#827) * Outname -> OutName * ANother child fix * TLUT -> tlut * Change nanoseconds to seconds in extract_assets.py (#829) * Match 2 more functions in z_eff_blure.c (#831) * Match ViMode_Configure (z_vimode.c OK) (#830) * warnings fixed (#835) * ZAPD update: libpng, zroom improvements and others (#811) * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "769f5702a" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "769f5702a" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * Add `libpng` to readme * Remove `-ifp` since it doesn't exists anymore in ZAPD * Remove extra print I added * Add UNK_09 macro and other minor fixes * Simplify PNG rules * simplify gitignore * Update README.md Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com> * Update dockerfile * basic instructions for cygwin and mac * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "86160be69" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "86160be69" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * Change nanoseconds to seconds in extract_assets.py Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com> * "Decompile" more objects. (#784) * Object_hakach_objects OK and fix a warning in z_play.c * Object Warp1 OK * Object_spot16_obj OK * object_cs Skeleton and limbs OK * Limbs are broken * Limbs OK * Object_CS OK * Object_jya_door OK * fix errors and add new lines * PR fixes (AngheloAlf) * PR fixes (EllipticEllipsis) * PR fixes (Fig) * Rename Spot16 and Jya * GraveYard -> Graveyard * PR fixes * -s * PR fixes * Object_RU1, Object_MA1, and warp pad objects Decompiled (#828) * Ruto limbs * RutoLimb enum * the enum doesn't go in en_door * Limb DLists * Name almost all textures and clean up EnRu1.c * remove padding * Name all but 1 animation and remove undefined syms * Object MA limbs OK * (MA1)Most textures * Small renames in EnMa1.c * Object MA1 OK * add base object for Mjin * Mjin OK * Update object_ma1.xml * PR fixes (Fig) * PR fixes * Missed one * Update assets/xml/objects/object_ru1.xml Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com> Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com> * En_River_Sound OK (#833) * match en_river_sound * remove asm * some docs * more docs * saria song * review stuff * z_sram OK (#834) * match z_sram * format and remove unused asm, also make some data static * review comments * another change * Match Jpeg_Decode (z_jpeg.c OK) (#839) * Match EnDaiku_UpdateText (En_Daiku OK) (#841) * Match 1 of the 2 remaining functions in Bg_Mizu_Movebg (#840) * Improve Audio_SequencePlayerProcessSequence (#844) Co-authored-by: zelda2774 <zelda2774@invalid> * Fix and rename nes_font_static (#753) * renames * change digits and control pad names * Add codepoints, rename blank char 0x7F * BgGndFiremeiro OK and documented (#850) * OK, data imported * Name everything * Delete asm * Add struct `LegacyLimb` and rename `AnimationHeader2` for `object_human` (#849) * Add LegacyLimb and rename AnimationHeader2 * Simplify SkelAnime_GetFrameDataLegacy * Minor fixes * Move LegacyLimb with the rest of the limbs * EnVali OK and documented, object_vali and object_bl completely analysed and documented (#845) * OK * Some naming * Name more, correct typo in Biri, extract skel * just Draws need names, fix typos in bili and warp1 * Decompile object_vali and add symbols * Few more names * Bari naming done * object_bl completed, symbols added * Label object_bl * Formatter * delete asm * review changes * review changes * review * Interface improvements (#822) * Add symbols, does NOT build OK * parameter OK with syms * Use `static` more and inline arrays * wip docs * Start on Interface_Draw, NOT OK yet * rename variables since interface dev is weird * nonmatching for now * kaleido * Update src/code/z_parameter.c Co-authored-by: louist103 <35883445+louist103@users.noreply.github.com> * Make most texture rectangles use shifts * fix symbols for all interface things * done with interface_draw for now * Update z_parameter.c * format files * fix wrong function calls * fix bss * improvements in matching * remove button enum for now * (void)0 to fix warning * make conditional look nicer * fix * fix wrong combiner * Update src/overlays/actors/ovl_kaleido_scope/z_lmap_mark.c Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com> * format * remove "HUD" naming * review suggestions Co-authored-by: louist103 <35883445+louist103@users.noreply.github.com> Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com> * Migrate .bss for fault drawer and .data for item00 (#823) * Item00 and fault drawer * Test * Test2 * test3 * test4 * remove .data file for item00 * revert hex * WHY * PLEASE * PR fixes (Roman) and run clang-format version 10 * Fault_drawer was swapped ...again) * Decompile and label EnEiyer (#852) * En_Eiyer OK * Label EnEiyer * Style fixes * Rename colCyl -> collider * Use CLAMP_MIN * Format * Review changes * Match Camera_PrintSettings (z_camera OK) (#853) * Match Camera_PrintSettings * rm asm * Match Math3D_LineSegMakePerpLineSeg (#854) * Match Math3D_LineSegMakePerpLineSeg Also renamed to Math3D_LineVsLineClosestTwoPoints * Fix UB * Some actor.c docs (in preparation for en_test) (#820) * renames * format * format functions.h * clean * arg name * remove asm * Decompile obj_bean (magic bean and soft soil). 2 NON_MATCHINGs (#846) * did a bunch * Do a bunch more * all functions in C * Macros for draw and collision part of state flags * Done for now * remove ASM * PR fixes (Elliptic) * all angles are hex and take away bad names * PR fixes (Roman) * PR fixes * PR fixes (Fig) * restore map mark * Fix the other messed with files * Decompile some more objects (#848) * Object_FU limbs and skel OK * limbs OK * Object_FU textures OK * Object_FU face textures OK * Symbols in en_fu.c * en_fu.c limb enum * Remove Object_fu from undefined_syms, move textures to draw, and small cleanup * Object_bird OK * Object_Bird OK, added cutscene for shot sun, and song of storms * Rainbow Bridge CS * Great fairy CS * Cutscene -> Cs * remove '&' from Cutscenes * Cleanup object_bird * Update z_en_fu.c * Update z_en_fu.h * Update z_en_fu.c * Update z_en_fu.h * Update z_en_fu.h * DC intro CS * Zeldas lullaby CS * Nabooru Knuckle CS * Owl Lake Hylia CS * Sun song CS * Undefined sym in Boss Dodongo * Missed a few more * DC tex name * Windmill man limbs * z_En_Ossan and dependencies (#824) * fix colliderinit typo * fix initchain * reloc * progress * progress * Pick off a few easy functions, reduce number of warnings * more tough OKs * Getting closer to all OK, fix en_girla header * some hard OKs, 7 to go * two funcs remaining * func_80AC7094 OK! * Fix warnings, begin documentation * get most of object_ossan documented, document some of en_ossan * improve en_girla function names * more EnOssan documentation * more documentation * en_tana basically complete, en_girla vars all named, en_ossan documentation improvements * delete TIME ITSELF * object_oF1d_map OK * more names, fixed a poition typo * Nearly all en_ossan functions named, all variables named * format.sh * forgot to delete data * implement pr changes * EnOssan OK! implement most of Roman's suggestions * ugh * implement figs suggestions * implement roman's suggestion * Can't tell my left from my other left Co-authored-by: fig02 <fig02srl@gmail.com> * Some progress on z_vr_box.c (#838) * z_vr_box.c progress * Rename dpList to dlistBuf and SKYBOX_CLEAR_SKY to SKYBOX_NORMAL_SKY * Fix * renamed dlistBuf to dListBuf and split large string further * Change PreRenderContext to just be PreRender (#862) * Decompile Fishing and document object_fish (#856) * Start decompiling Fishing * Decompile more functions in Fishing * Decompile a few more functions in Fishing * Decompile func_80B6E9E0 and func_80B7825C (non matching) * Minor Fishing cleanups * Migrate fishing bss to C and match 3 functions * Decompile and match Fishing_Update * Migrate fishing data to C and minor cleanups * Fix the object_fish xml and use its symbols in Fishing * Partially document Fishing and object_fish * Add more documentation/cleanups to Fishing and object_fish * Use object_fish symbols in Demo_Ec and fix naming * Minor fixes to Fishing docs * Apply review suggestions for Fishing * Apply 2 more review suggestions for Fishing * Apply some review suggestions for Fishing * Extract all "place name" title cards (#858) * Forest and shadow temple * fire temple * Water temple * Spirit temple * Deku tree * jabu jabu * DC * Inside Ganons castle * GTG * Castle courtyard * great fairy's fountain * chamber of sages * shooting gallery * Temple of time * market * back alley * kokir shop * goron shop * zora shop * House of skulltula * bazarr * potion shop * gravekeepers hut * lakeside lab * hyrule field * kak * graveyard * zoras river * kokiri forest * lake hylia * zoras domain * zoras fountain * gerudo valley * lost woods * the rest of them * cleanup * final cleanup * PR fixes (Zel) * (Re) fix case * segment 0 * Fix map name static conflict * Comment about ZAPD * number 0 * Update place_title_cards.xml * Update spec * Fix all xmls to explicitly use offsets (#859) * Forest and shadow temple * fire temple * Water temple * Spirit temple * Deku tree * jabu jabu * DC * Inside Ganons castle * GTG * Castle courtyard * great fairy's fountain * chamber of sages * shooting gallery * Temple of time * market * back alley * kokir shop * goron shop * zora shop * House of skulltula * bazarr * potion shop * gravekeepers hut * lakeside lab * hyrule field * kak * graveyard * zoras river * kokiri forest * lake hylia * zoras domain * zoras fountain * gerudo valley * lost woods * the rest of them * cleanup * final cleanup * PR fixes (Zel) * Fra -> FRA and cleanup map_name_static * map_name_static * DONE * SHould be it * Done done done done * vector * remove another pr * ? * EnDekubaba OK and documented, object_dekubaba documented (#864) * 13 functions left, data imported * 2 left * 1 left * OK * Begin naming * sfx rename * spec * Begin naming, add LINK_IS_CHILD to EnDu * Fix spelling of its/it's * Document most of object_dekubaba, import symbols * Document draw functions, begin on actionfuncs * New actor function names, some float constants * Name almost everything * Delete asm * Name size, format * Review changes * Review changes * Brackets, format * Fix Sheik typo (#867) * db_camera (#842) * Decompile shrink_window.c * progress * progress * makefile * progress * match 8 functions * 1 more match * match 2 functions * decompile func_800B9638 * fix flow * migrate .bss * doc * name some stuff * fixes * comment fix * remove scene .c files * old z_camera .s files * revert z_camera change * revert unwanted z_camera change * fixes * remove unused files, run clang-format and fix non-matching * fix clang-format causing non-matching * remove newline + old comment in func_800B3BD4 * make db_camera global variables static * add s prefix to startic variables * change magic constants * rename "unk_50" * Match func_800B3BD4 and Match DbCamera_UpdateDemoControl (-bss) * Lots of progress on update * Mainly cleanup * run format.sh + remove unused asm * replace chevrons with add quotes * remove useless cast + use correct empty argument function declaration Co-authored-by: engineer124 <engineer124engineer124@gmail.com> * Match Interface_Draw (z_parameter OK) (#876) * Interface_Draw down to permuter score = 175 * Fix typo * Matched Interface_Draw! * clean-up * Another touch-up * a little more cleanup * No more direct gGameInfo->data access * Audio WIP (#836) * being code_800EC960 * wip * wip * more audio progress * migrate data in code_800E11F0 * wip * make ok * remove asm * wip * move some variables outside of gAudioContext to the AudioContext structure due to the size used in func_800E3094 * more progress * wip * wip * split code_800E11F0 * migrate rodata in code_800E11F0 * match functions that couldn't because of data issues * move code_800E4FE0 asm files * wip * more wip * fix global functions, and forward declarations * wip * wip * wip * ocarina wip * match a couple functions * some progress * separate some bss * match func_800EDA3C * some matching * more matches * migrate audio rodata * some matches * more matchess * start on synthesis * work on synthesis * fix function declaration * Merge branch 'master' into audio * match a few more functions * wip * wip * more matching, rename Audio_SetBGM to Audio_QueueSeqCmd * name several audio functions, and audiocontext members * more naming, rename code_800E11F0 to audio_load, code_800DAAC0 to audio_synthesis * audio wip * match a few more functions. * wip * add missing NON_MATCHING directive * wip * some matching, data reogranization * match cursed function * wip * wip * formatting * remove prefix from struct memebers * missed function rename * review Co-authored-by: fig02 <fig02srl@gmail.com> * ZAPD update: Gotta go fast! (#877) * copy over the xml * Rename anims * A bunch of renames * minor extract_assets fixes * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "820678b4e" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "820678b4e" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * Change rgb5a1 to rgba16 * eye and eyebrows * some dlists * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "6be9af65d" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "6be9af65d" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * Dancing Couple (ovl_En_Tg) (#866) * Match EnTg_Destroy * Match EnTg_Init * Matching EnTg_Update * Match func_80B18360 Moving both 'return phi;'s into a single return at the end of the function causes the assembly to not match. * Probably equivalent, non-matching func_80B183F8 * Matching EnTg_Draw * Matching update function * Matching func_80B18778 * All functions decompiled * Move data to C code * All functions matched excepted weird switch/case * Last matching function * Remove unused ASM * Name obvious symbols * Clang format * Name text-related functions and variables * Describe actor as Dancing Couple See https://github.com/zeldaret/oot/pull/866#discussion_r664726581 * Use named constants * Name drawing constants * Use THIS macro for void* * Name the function that sets environment color * Add comments to parts of code that aren't clear * Rename timesSpokenTo to nextDialogue, treat isTalking as boolean * z_en_ko OK (#869) * .data OK * Progress * push some old stuff * Finish a chain * Progress * Progress * Run mathfixer.py * Progress * match one more * Up to date * Match func_80A97610 * func_80A96FD0 * most of the way through the mega switch * small formatting thing. still stuck on the switch * start a big switch function * a little closer * done with matching for now starting objects * func_80A97738 OK! * func_80A995CC OK! * func_80A99864 OK! * en_ko OK! * Code clean-up pass * more EnKo cleanups, object_fa and object_kw1 textures documented * complete object_km1, more EnKo documentation * More documentation * delete asm * Clean-up rebase issues * bleh * Implement Dragorn's suggestions * fix spec, implement fig's suggestions * whoops (ill leave it for the docs tho lol) * whoops again * i made an ouchie * smile * last one for real Co-authored-by: Louis <35883445+louist103@users.noreply.github.com> Co-authored-by: fig02 <fig02srl@gmail.com> * z_en_bigokuta OK (#878) * start * Did some more * Progress * More * IDK * Chip away a little * im done * func_809BEBBC OK! * get rid of graphovl * revert random changes * Big Okuta OK! * more clean-ups * implement dragorn's suggestions * implement fig and louist's suggestions Co-authored-by: Louis <35883445+louist103@users.noreply.github.com> * z_obj_mure OK (#875) * almost matching init, matching data * more matchings, some non-matching progress * finishing up SpawnActor, fixing .data types * first decompile pass done, few non matchings * cleanup/update matchings and remove asm * format code * pick up some OKs * 1 non_matching left, some documentation * z_obj_mure OK... but at what cost? * implement suggested changes, some more documentation * Implement Fig's suggestions * review Co-authored-by: Sam Lyon <sam.c.lyon@gmail.com> Co-authored-by: fig02 <fig02srl@gmail.com> * convert remaining RGB5a1 to RGBA16 (#879) * Stalfos (en_test) OK and object_sk2 documented (#868) * fix colliderinit typo * migrate data * init has 1 problem * progress * progress * builds now * progress * progress * lots of funcs matched * many functions, fix warnings * 1 left * done * docs progress * remove graphovl * missed some * change some funcs * some more * another * format * more docs * cleanups1 * limbs, DLs, textures * limbs named (thanks elliptic) * more docs * Name animations, import symbols * Named sections of xml * more docs * rename limbs and use flag macros * name * review1 and use limb enum * review2 * agro -> aggro * review3 * review4 * review5 Co-authored-by: Elliptic Ellipsis <elliptic.ellipsis@gmail.com> * Use a temp symbol for RomStart/RomEnd symbols, makes the map show the right value for actual RomStart/RomEnd symbols (#880) * builds OK * first pass * PR fixes (Louis) * fixes * a little more * format * dragorn's stuff * more cleanup, merge, and format * now with work buffers * forgot sfx * update and draw Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain> Co-authored-by: Louis <35883445+louist103@users.noreply.github.com> Co-authored-by: Parker Burnett <burnettparker@gmail.com> Co-authored-by: fig02 <fig02srl@gmail.com> Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com> Co-authored-by: glankk <glankk@users.noreply.github.com> Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Co-authored-by: zelda2774 <69368340+zelda2774@users.noreply.github.com> Co-authored-by: zelda2774 <zelda2774@invalid> Co-authored-by: mzxrules <mzxrules@gmail.com> Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com> Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com> Co-authored-by: Nicholas Estelami <NEstelami@users.noreply.github.com> Co-authored-by: Jack Walker <7463599+Jack-Walker@users.noreply.github.com> Co-authored-by: Zach Banks <zjbanks@gmail.com> Co-authored-by: Derek Hensley <hensley.derek58@gmail.com> Co-authored-by: Kenix3 <kenixwhisperwind@gmail.com> Co-authored-by: Anghelo Carvajal <anghelo.carvajal.14@sansano.usm.cl> Co-authored-by: pixel-stuck <mathmcclintic@gmail.com> Co-authored-by: Vijfhoek <me@vijf.life> Co-authored-by: Synray <31429825+Synray@users.noreply.github.com> Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> Co-authored-by: Random <28494085+Random06457@users.noreply.github.com> Co-authored-by: engineer124 <engineer124engineer124@gmail.com> Co-authored-by: krimtonz <33664508+krimtonz@users.noreply.github.com> Co-authored-by: Aly Cerruti <aprime2003@gmail.com> Co-authored-by: Sam Lyon <sam.c.lyon@gmail.com> Co-authored-by: Elliptic Ellipsis <elliptic.ellipsis@gmail.com> Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/code/code_800EC960.c2
-rw-r--r--src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c3801
-rw-r--r--src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h123
-rw-r--r--src/overlays/actors/ovl_Boss_Mo/z_boss_mo_colchk.c247
4 files changed, 3900 insertions, 273 deletions
diff --git a/src/code/code_800EC960.c b/src/code/code_800EC960.c
index dfd5fc01b..c52c87e7d 100644
--- a/src/code/code_800EC960.c
+++ b/src/code/code_800EC960.c
@@ -2462,7 +2462,7 @@ void func_800F4A70(void) {
}
}
-void func_800F4B58(Vec3f* arg0, u16 arg1, u8* arg2) {
+void func_800F4B58(Vec3f* arg0, s16 arg1, u8* arg2) {
Audio_PlaySoundGeneral(arg1, arg0, 4, &gNoteFrequencies[arg2[D_801305CC] + 39], &D_801333E0, &D_801333E8);
if (D_801305CC < 15) {
diff --git a/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c
index c57bec444..b851fbc88 100644
--- a/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c
+++ b/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c
@@ -1,15 +1,122 @@
+/*
+ * File: z_boss_mo.c
+ * Overlay: ovl_Boss_Mo
+ * Description: Morpha
+ */
+
#include "z_boss_mo.h"
+#include "objects/object_mo/object_mo.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
+#include "vt.h"
#define FLAGS 0x00000035
#define THIS ((BossMo*)thisx)
+#define MO_WATER_LEVEL(globalCtx) globalCtx->colCtx.colHeader->waterBoxes[0].ySurface
+
+#define HAS_LINK(tent) \
+ ((tent != NULL) && \
+ ((tent->work[MO_TENT_ACTION_STATE] == MO_TENT_GRAB) || (tent->work[MO_TENT_ACTION_STATE] == MO_TENT_SHAKE)))
+
+typedef struct {
+ /* 0x00 */ Vec3f pos;
+ /* 0x0C */ Vec3f vel;
+ /* 0x18 */ Vec3f accel;
+ /* 0x24 */ u8 type;
+ /* 0x25 */ u8 timer;
+ /* 0x26 */ u8 stopTimer;
+ /* 0x28 */ s16 unk_28; // unused?
+ /* 0x2A */ s16 alpha;
+ /* 0x2C */ s16 rippleMode;
+ /* 0x2E */ s16 maxAlpha;
+ /* 0x30 */ f32 scale;
+ /* 0x30 */ f32 fwork[2];
+ /* 0x3C */ Vec3f* targetPos;
+} BossMoEffect; // size = 0x40
+
+#define MO_FX_MAX_SIZE 0
+#define MO_FX_SHIMMER 0
+#define MO_FX_SUCTION 0
+
+#define MO_FX_SPREAD_RATE 1
+#define MO_FX_STRETCH 1
+#define MO_FX_MAX_SCALE 1
+
void BossMo_Init(Actor* thisx, GlobalContext* globalCtx);
void BossMo_Destroy(Actor* thisx, GlobalContext* globalCtx);
-void BossMo_Update(Actor* thisx, GlobalContext* globalCtx);
-void BossMo_Draw(Actor* thisx, GlobalContext* globalCtx);
+void BossMo_UpdateCore(Actor* thisx, GlobalContext* globalCtx);
+void BossMo_UpdateTent(Actor* thisx, GlobalContext* globalCtx);
+void BossMo_DrawCore(Actor* thisx, GlobalContext* globalCtx);
+void BossMo_DrawTent(Actor* thisx, GlobalContext* globalCtx);
+
+void BossMo_UpdateEffects(BossMo* this, GlobalContext* globalCtx);
+void BossMo_DrawEffects(BossMoEffect* effect, GlobalContext* globalCtx);
+
+void BossMo_SetupTentacle(BossMo* this, GlobalContext* globalCtx);
+void BossMo_Tentacle(BossMo* this, GlobalContext* globalCtx);
+
+void BossMo_Unknown(void);
+
+typedef enum {
+ /* 0 */ MO_FX_NONE,
+ /* 1 */ MO_FX_SMALL_RIPPLE,
+ /* 2 */ MO_FX_BIG_RIPPLE,
+ /* 3 */ MO_FX_DROPLET,
+ /* 4 */ MO_FX_SPLASH,
+ /* 5 */ MO_FX_SPLASH_TRAIL,
+ /* 6 */ MO_FX_WET_SPOT,
+ /* 7 */ MO_FX_BUBBLE
+} BossMoEffectType;
+
+typedef enum {
+ /* 0 */ MO_TENT_READY,
+ /* 1 */ MO_TENT_SWING,
+ /* 2 */ MO_TENT_ATTACK,
+ /* 3 */ MO_TENT_CURL,
+ /* 4 */ MO_TENT_GRAB,
+ /* 5 */ MO_TENT_SHAKE,
+ /* 10 */ MO_TENT_WAIT = 10,
+ /* 11 */ MO_TENT_SPAWN,
+ /* 100 */ MO_TENT_CUT = 100,
+ /* 101 */ MO_TENT_RETREAT,
+ /* 102 */ MO_TENT_DESPAWN,
+ /* 200 */ MO_TENT_DEATH_START = 200,
+ /* 201 */ MO_TENT_DEATH_1,
+ /* 202 */ MO_TENT_DEATH_2,
+ /* 203 */ MO_TENT_DEATH_3,
+ /* 205 */ MO_TENT_DEATH_5 = 205,
+ /* 206 */ MO_TENT_DEATH_6
+} BossMoTentState;
+
+typedef enum {
+ /* -11 */ MO_CORE_UNUSED = -11,
+ /* 0 */ MO_CORE_MOVE = 0,
+ /* 1 */ MO_CORE_MAKE_TENT,
+ /* 2 */ MO_CORE_UNDERWATER,
+ /* 5 */ MO_CORE_STUNNED = 5,
+ /* 10 */ MO_CORE_ATTACK = 10,
+ /* 11 */ MO_CORE_RETREAT,
+ /* 20 */ MO_CORE_INTRO_WAIT = 20,
+ /* 21 */ MO_CORE_INTRO_REVEAL
+} BossMoCoreState;
+
+typedef enum {
+ /* 0 */ MO_BATTLE,
+ /* 1 */ MO_INTRO_WAIT,
+ /* 2 */ MO_INTRO_START,
+ /* 3 */ MO_INTRO_SWIM,
+ /* 4 */ MO_INTRO_REVEAL,
+ /* 5 */ MO_INTRO_FINISH,
+ /* 100 */ MO_DEATH_START = 100,
+ /* 101 */ MO_DEATH_DRAIN_WATER_1,
+ /* 102 */ MO_DEATH_DRAIN_WATER_2,
+ /* 103 */ MO_DEATH_CEILING,
+ /* 104 */ MO_DEATH_DROPLET,
+ /* 105 */ MO_DEATH_FINISH,
+ /* 150 */ MO_DEATH_MO_CORE_BURST = 150
+} BossMoCsState;
-/*
const ActorInit Boss_Mo_InitVars = {
ACTOR_BOSS_MO,
ACTORCAT_BOSS,
@@ -18,303 +125,3455 @@ const ActorInit Boss_Mo_InitVars = {
sizeof(BossMo),
(ActorFunc)BossMo_Init,
(ActorFunc)BossMo_Destroy,
- (ActorFunc)BossMo_Update,
- (ActorFunc)BossMo_Draw,
+ (ActorFunc)BossMo_UpdateTent,
+ (ActorFunc)BossMo_DrawTent,
+};
+
+static BossMo* sMorphaCore = NULL;
+static BossMo* sMorphaTent1 = NULL;
+static BossMo* sMorphaTent2 = NULL;
+
+static f32 sFlatWidth[41] = {
+ 15.0f, 12.0f, 9.0f, 6.5f, 4.8f, 4.0f, 3.4f, 3.1f, 3.0f, 3.1f, 3.2f, 3.4f, 3.6f, 3.8f,
+ 4.0f, 4.6f, 5.1f, 5.5f, 6.1f, 6.6f, 7.3f, 7.7f, 8.4f, 8.5f, 8.7f, 8.8f, 8.8f, 8.7f,
+ 8.6f, 8.3f, 8.2f, 8.1f, 7.2f, 6.7f, 5.9f, 4.9f, 2.7f, 0.0f, 0.0f, 0.0f, 0.0f,
+};
+
+#include "z_boss_mo_colchk.c"
+
+static BossMoEffect sEffects[300];
+static s32 sSeed1;
+static s32 sSeed2;
+static s32 sSeed3;
+
+void BossMo_InitRand(s32 seedInit0, s32 seedInit1, s32 seedInit2) {
+ sSeed1 = seedInit0;
+ sSeed2 = seedInit1;
+ sSeed3 = seedInit2;
+}
+
+f32 BossMo_RandZeroOne(void) {
+ // Wichmann-Hill algorithm
+ f32 randFloat;
+
+ sSeed1 = (sSeed1 * 171) % 30269;
+ sSeed2 = (sSeed2 * 172) % 30307;
+ sSeed3 = (sSeed3 * 170) % 30323;
+
+ randFloat = (sSeed1 / 30269.0f) + (sSeed2 / 30307.0f) + (sSeed3 / 30323.0f);
+ while (randFloat >= 1.0f) {
+ randFloat -= 1.0f;
+ }
+ return fabsf(randFloat);
+}
+
+s32 BossMo_NearLand(Vec3f* pos, f32 margin) {
+ if (450.0f - margin <= fabsf(pos->x)) {
+ return true;
+ }
+ if (450.0f - margin <= fabsf(pos->z)) {
+ return true;
+ }
+ if ((fabsf(pos->x - 180.0f) < 90.0f + margin) || (fabsf(pos->x - -180.0f) < 90.0f + margin)) {
+ if (fabsf(pos->z - 180.0f) < 90.0f + margin) {
+ return true;
+ }
+ if (fabsf(pos->z - -180.0f) < 90.0f + margin) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void BossMo_SpawnRipple(BossMoEffect* effect, Vec3f* pos, f32 scale, f32 maxScale, s16 maxAlpha, s16 partLimit,
+ u8 type) {
+ static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
+ s16 i;
+
+ for (i = 0; i < partLimit; i++, effect++) {
+ if (effect->type == MO_FX_NONE) {
+ effect->stopTimer = 0;
+ effect->type = type;
+ effect->pos = *pos;
+ effect->vel = zeroVec;
+ effect->accel = zeroVec;
+ effect->scale = scale * 0.0025f;
+ effect->fwork[MO_FX_MAX_SIZE] = maxScale * 0.0025f;
+ if (scale > 300.0f) {
+ effect->alpha = 0;
+ effect->maxAlpha = maxAlpha;
+ effect->rippleMode = 0;
+ effect->fwork[MO_FX_SPREAD_RATE] = (effect->fwork[MO_FX_MAX_SIZE] - effect->scale) * 0.05f;
+ } else {
+ effect->alpha = maxAlpha;
+ effect->rippleMode = 1;
+ effect->fwork[MO_FX_SPREAD_RATE] = (effect->fwork[MO_FX_MAX_SIZE] - effect->scale) * 0.1f;
+ }
+ break;
+ }
+ }
+}
+
+void BossMo_SpawnDroplet(s16 type, BossMoEffect* effect, Vec3f* pos, Vec3f* vel, f32 scale) {
+ s16 i;
+ Vec3f gravity = { 0.0f, -1.0f, 0.0f };
+
+ for (i = 0; i < 290; i++, effect++) {
+ if (effect->type == MO_FX_NONE) {
+ effect->type = type;
+ effect->pos = *pos;
+ effect->vel = *vel;
+ effect->accel = gravity;
+ if (type == MO_FX_SPLASH_TRAIL) {
+ effect->accel.y = 0.0f;
+ }
+ effect->scale = scale;
+ effect->fwork[MO_FX_SPREAD_RATE] = 1.0f;
+ effect->stopTimer = 0;
+ break;
+ }
+ }
+}
+
+void BossMo_SpawnStillDroplet(BossMoEffect* effect, Vec3f* pos, f32 scale) {
+ s16 i;
+ Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
+
+ for (i = 0; i < 290; i++, effect++) {
+ if (effect->type == MO_FX_NONE) {
+ effect->type = MO_FX_DROPLET;
+ effect->stopTimer = 2;
+ effect->pos = *pos;
+ effect->vel = zeroVec;
+ effect->accel = zeroVec;
+ effect->scale = scale;
+ effect->fwork[MO_FX_SPREAD_RATE] = 1.0f;
+ break;
+ }
+ }
+}
+
+void BossMo_SpawnBubble(BossMoEffect* effect, Vec3f* pos, Vec3f* vel, Vec3f* accel, f32 scale, Vec3f* targetPos) {
+ s16 i;
+
+ for (i = 0; i < 280; i++, effect++) {
+ if (effect->type == MO_FX_NONE) {
+ effect->type = MO_FX_BUBBLE;
+ effect->stopTimer = 0;
+ effect->pos = *pos;
+ effect->vel = *vel;
+ effect->accel = *accel;
+ effect->scale = scale;
+ effect->fwork[MO_FX_SUCTION] = 0.0f;
+ effect->targetPos = targetPos;
+ if (targetPos == NULL) {
+ effect->alpha = 255;
+ } else {
+ effect->alpha = 0;
+ }
+ effect->timer = 0;
+ break;
+ }
+ }
+}
+
+static s16 sCurlRot[41] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 8, 8, 8, 9, 9, 9,
+ 9, 9, 9, 12, 15, 15, 15, 15, 15, 15, 15, 20, 20, 20, 0, 0, 0, 0, 0, 0,
+};
+static s16 sGrabRot[41] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5, -5, -5,
+ 0, 5, 10, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0,
+};
+static s16 sAttackRot[41] = {
+ 0, 5, 6, 7, 8, 8, 7, 6, 6, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
-static ColliderCylinderInit D_8092603C = {
- {
- COLTYPE_HIT3,
- AT_ON | AT_TYPE_ENEMY,
- AC_ON | AC_TYPE_PLAYER,
- OC1_ON | OC1_TYPE_PLAYER,
- OC2_TYPE_1,
- COLSHAPE_CYLINDER,
- },
- {
- ELEMTYPE_UNK0,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFDFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON | BUMP_HOOKABLE,
- OCELEM_ON,
- },
- { 20, 40, -20, { 0, 0, 0 } },
+static InitChainEntry sInitChain[] = {
+ ICHAIN_U8(targetMode, 5, ICHAIN_CONTINUE),
+ ICHAIN_S8(naviEnemyId, 0x25, ICHAIN_CONTINUE),
+ ICHAIN_F32_DIV1000(gravity, 0, ICHAIN_CONTINUE),
+ ICHAIN_F32(targetArrowOffset, 0, ICHAIN_STOP),
};
-static ColliderJntSphElementInit D_80925D80[19] = {
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 0, { { 0, 0, 0 }, 0 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 1, { { 0, 0, 0 }, 0 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 2, { { 0, 0, 0 }, 30 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 3, { { 0, 0, 0 }, 24 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 4, { { 0, 0, 0 }, 22 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 5, { { 0, 0, 0 }, 20 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 6, { { 0, 0, 0 }, 18 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 7, { { 0, 0, 0 }, 16 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 8, { { 0, 0, 0 }, 14 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 9, { { 0, 0, 0 }, 12 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 10, { { 0, 0, 0 }, 10 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 11, { { 0, 0, 0 }, 10 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 12, { { 0, 0, 0 }, 10 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 13, { { 0, 0, 0 }, 10 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 14, { { 0, 0, 0 }, 10 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 15, { { 0, 0, 0 }, 10 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 16, { { 0, 0, 0 }, 10 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 17, { { 0, 0, 0 }, 10 }, 100 },
- },
- {
- {
- ELEMTYPE_UNK4,
- { 0xFFCFFFFF, 0x00, 0x10 },
- { 0xFFCFFFFF, 0x00, 0x00 },
- TOUCH_ON | TOUCH_SFX_NORMAL,
- BUMP_ON,
- OCELEM_ON,
- },
- { 18, { { 0, 0, 0 }, 10 }, 100 },
- },
+static Vec3f sAudioZeroVec = { 0.0f, 0.0f, 0.0f };
+
+static u8 sTentSpawnIndex[21] = { 0, 1, 2, 3, 4, 15, 19, 5, 14, 16, 17, 18, 6, 13, 20, 7, 12, 11, 10, 9, 8 };
+
+static Vec2f sTentSpawnPos[21] = {
+ { -360.0f, -360.0f }, { -180.0f, -360.0f }, { 0.0f, -360.0f }, { 180.0f, -360.0f }, { 360.0f, -360.0f },
+ { -360.0f, -180.0f }, { 0.0f, -180.0f }, { 360.0f, -180.0f }, { -360.0f, 0.0f }, { -180.0f, 0.0f },
+ { 0.0f, 0.0f }, { 180.0f, 0.0f }, { 360.0f, 0.0f }, { -360.0f, 180.0f }, { 0.0f, 180.0f },
+ { 360.0f, 180.0f }, { -360.0f, 360.0f }, { -180.0f, 360.0f }, { 0.0f, 360.0f }, { 180.0f, 360.0f },
+ { 360.0f, 360.0f },
};
-static ColliderJntSphInit D_8092602C = {
- {
- COLTYPE_NONE,
- AT_ON | AT_TYPE_ENEMY,
- AC_ON | AC_TYPE_PLAYER,
- OC1_ON | OC1_TYPE_PLAYER,
- OC2_TYPE_1,
- COLSHAPE_JNTSPH,
- },
- 19,
- D_80925D80,
+static f32 sTentWidth[41] = {
+ 3.56f, 3.25f, 2.96f, 2.69f, 2.44f, 2.21f, 2.0f, 1.81f, 1.64f, 1.49f, 1.36f, 1.25f, 1.16f, 1.09f,
+ 1.04f, 1.01f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f, 0.98f, 0.95f, 0.9f, 0.8f, 0.6f, 1.0f, 1.0f, 1.0f, 1.0f,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091BB00.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091BB1C.s")
+static f32 sDropletWidth[41] = {
+ 0.0f, 2.95804f, 4.123106f, 4.974937f, 5.656854f, 6.22495f, 6.708204f, 7.123903f, 7.483315f,
+ 7.794229f, 8.062258f, 8.291562f, 8.485281f, 8.645808f, 8.774964f, 8.87412f, 8.944272f, 8.9861f,
+ 9.0f, 8.9861f, 8.944272f, 8.87412f, 8.774964f, 8.645808f, 8.485281f, 8.291562f, 8.062258f,
+ 7.794229f, 7.483315f, 7.123903f, 6.708204f, 6.22495f, 5.656854f, 4.974937f, 4.123106f, 2.95804f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+}; // These are sqrt(9^2 - (i/2 - 9)^2), a sphere of radius 9.
+
+void BossMo_Init(Actor* thisx, GlobalContext* globalCtx2) {
+ GlobalContext* globalCtx = globalCtx2;
+ BossMo* this = THIS;
+ u16 i;
+
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
+ if (this->actor.params != BOSSMO_TENTACLE) {
+ Flags_SetSwitch(globalCtx, 0x14);
+ sMorphaCore = this;
+ MO_WATER_LEVEL(globalCtx) = this->waterLevel = MO_WATER_LEVEL(globalCtx);
+ globalCtx->unk_11D30[0] = 0xA0;
+ globalCtx->specialEffects = sEffects;
+ for (i = 0; i < ARRAY_COUNT(sEffects); i++) {
+ sEffects[i].type = MO_FX_NONE;
+ }
+ this->actor.world.pos.x = 200.0f;
+ this->actor.world.pos.y = MO_WATER_LEVEL(globalCtx) + 50.0f;
+ this->fwork[MO_TENT_SWING_SIZE_X] = 5.0f;
+ this->drawActor = true;
+ this->actor.colChkInfo.health = 20;
+ this->actor.colChkInfo.mass = 0;
+ this->actor.params = 0;
+ Actor_SetScale(&this->actor, 0.01f);
+ Collider_InitCylinder(globalCtx, &this->coreCollider);
+ Collider_SetCylinder(globalCtx, &this->coreCollider, &this->actor, &sCylinderInit);
+ if (Flags_GetClear(globalCtx, globalCtx->roomCtx.curRoom.num)) {
+ Actor_Kill(&this->actor);
+ Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_DOOR_WARP1, 0.0f, -280.0f, 0.0f, 0,
+ 0, 0, -1);
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_B_HEART, -200.0f, -280.0f, 0.0f, 0, 0, 0, 0);
+ globalCtx->unk_11D30[0] = 0xFF;
+ MO_WATER_LEVEL(globalCtx) = -500;
+ return;
+ }
+ if (gSaveContext.eventChkInf[7] & 0x10) {
+ Audio_QueueSeqCmd(0x1B);
+ this->tentMaxAngle = 5.0f;
+ this->timers[0] = 50;
+ } else {
+ this->csState = MO_INTRO_WAIT;
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_INTRO_WAIT;
+ this->actor.world.pos.x = 1000.0f;
+ this->timers[0] = 60;
+ }
+ sMorphaTent1 = (BossMo*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_BOSS_MO,
+ this->actor.world.pos.x, this->actor.world.pos.y,
+ this->actor.world.pos.z, 0, 0, 0, BOSSMO_TENTACLE);
+ this->actor.draw = BossMo_DrawCore;
+ this->actor.update = BossMo_UpdateCore;
+ Actor_ChangeCategory(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_BOSS);
+ } else {
+ Actor_SetScale(&this->actor, 0.01f);
+ BossMo_SetupTentacle(this, globalCtx);
+ this->actor.colChkInfo.mass = 0xFF;
+ MO_WATER_LEVEL(globalCtx) = -50;
+ this->waterTexAlpha = 90.0f;
+ this->actor.world.pos.y = MO_WATER_LEVEL(globalCtx);
+ this->actor.prevPos = this->targetPos = this->actor.world.pos;
+ Collider_InitJntSph(globalCtx, &this->tentCollider);
+ Collider_SetJntSph(globalCtx, &this->tentCollider, &this->actor, &sJntSphInit, this->tentElements);
+ this->tentMaxAngle = 1.0f;
+ }
+}
+
+void BossMo_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ BossMo* this = THIS;
+
+ if (this->actor.params >= BOSSMO_TENTACLE) {
+ Collider_DestroyJntSph(globalCtx, &this->tentCollider);
+ } else {
+ Collider_DestroyCylinder(globalCtx, &this->coreCollider);
+ }
+}
+
+void BossMo_SetupTentacle(BossMo* this, GlobalContext* globalCtx) {
+ this->actionFunc = BossMo_Tentacle;
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_WAIT;
+ this->timers[0] = 50 + (s16)Rand_ZeroFloat(20.0f);
+}
+
+void BossMo_Tentacle(BossMo* this, GlobalContext* globalCtx) {
+ // variables marked real are put on the stack and cannot be reordered
+ s16 tentXrot;
+ s16 sp1B4 = 0; // real
+ s32 buttons;
+ Player* player = PLAYER;
+ s16 indS0;
+ s16 indS1;
+ Camera* camera1;
+ Camera* camera2;
+ BossMo* otherTent = (BossMo*)this->otherTent; // real
+ f32 maxSwingRateX; // real
+ f32 maxSwingLagX; // real
+ f32 maxSwingSizeX; // real
+ f32 maxSwingRateZ; // real
+ f32 maxSwingLagZ; // real
+ f32 maxSwingSizeZ; // real
+ f32 swingRateAccel; // real
+ f32 swingSizeAccel; // real
+ s16 rippleCount; // real
+ s16 indT5;
+ Vec3f ripplePos; // real
+ f32 randAngle;
+ f32 randFloat;
+ f32 tempf1;
+ f32 tempf2;
+ f32 sin;
+ f32 cos;
+ f32 temp;
+ f32 dx;
+ f32 dy;
+ f32 dz;
+ Vec3f sp138; // real
+ Vec3f sp12C; // real
+ Vec3f sp120; // real
+ s32 pad11C;
+ s32 pad118;
+ s32 pad114;
+ s32 pad110;
+ s32 pad10C;
+ s32 pad108;
+ Vec3f spFC; // real
+ Vec3f spF0; // real
+ f32 padEC;
+ Vec3f spE0; // real
+ Vec3f spD4; // real
+ Vec3f spC8; // real
+
+ if (this->work[MO_TENT_ACTION_STATE] <= MO_TENT_DEATH_3) {
+ this->actor.world.pos.y = MO_WATER_LEVEL(globalCtx);
+ }
+ if ((this->work[MO_TENT_ACTION_STATE] == MO_TENT_READY) ||
+ (this->work[MO_TENT_ACTION_STATE] >= MO_TENT_DEATH_START) ||
+ (this->work[MO_TENT_ACTION_STATE] == MO_TENT_RETREAT) || (this->work[MO_TENT_ACTION_STATE] == MO_TENT_SWING) ||
+ (this->work[MO_TENT_ACTION_STATE] == MO_TENT_SHAKE)) {
+ if (this->work[MO_TENT_ACTION_STATE] == MO_TENT_READY) {
+ if (sMorphaCore->csState != MO_BATTLE) {
+ maxSwingRateX = 2000.0f;
+ maxSwingLagX = 3000.0f;
+ maxSwingSizeX = 1000.0f;
+ maxSwingRateZ = 1500.0f;
+ maxSwingLagZ = 2500.0f;
+ maxSwingSizeZ = 1000.0f;
+ swingRateAccel = 10.0f;
+ swingSizeAccel = 10.0f;
+ } else {
+ maxSwingRateX = 2000.0f;
+ maxSwingLagX = 3000.0f;
+ maxSwingSizeX = 1000.0f;
+ maxSwingRateZ = 1500.0f;
+ maxSwingLagZ = 2500.0f;
+ maxSwingSizeZ = 1000.0f;
+ swingRateAccel = 20.0f;
+ swingSizeAccel = 30.0f;
+ }
+ } else if (this->work[MO_TENT_ACTION_STATE] == MO_TENT_SWING) {
+ maxSwingRateX = 2500.0f;
+ maxSwingLagX = -1000.0f;
+ maxSwingSizeX = 3000.0f;
+ maxSwingRateZ = 1500.0f;
+ maxSwingLagZ = 2500.0f;
+ maxSwingSizeZ = 0.0;
+ swingRateAccel = 30.0f;
+ swingSizeAccel = 60.0f;
+ if (((this->sfxTimer % 16) == 0) && (this->timers[0] < 30)) {
+ func_800F4B58(&this->tentTipPos, NA_SE_EN_MOFER_WAVE, D_801305D0);
+ }
+ } else if (this->work[MO_TENT_ACTION_STATE] == MO_TENT_SHAKE) {
+ if (this->timers[0] > 40) {
+ maxSwingRateX = 1300.0f;
+ maxSwingLagX = -3200.0f;
+ maxSwingSizeX = 7000.0f;
+ maxSwingRateZ = 800.0f;
+ maxSwingLagZ = 2500.0f;
+ maxSwingSizeZ = 5000.0f;
+ swingRateAccel = 30.0f;
+ swingSizeAccel = 60.0f;
+ if ((this->sfxTimer % 32) == 0) {
+ func_800F4B58(&this->tentTipPos, NA_SE_EN_MOFER_WAVE, D_801305D0);
+ func_800AA000(0, 100, 5, 2);
+ func_8002F7DC(&player->actor, NA_SE_VO_LI_FREEZE + player->ageProperties->unk_92);
+ }
+ } else {
+ maxSwingRateX = 2000.0f;
+ maxSwingLagX = -1000.0f;
+ maxSwingSizeX = 5000.0f;
+ maxSwingRateZ = 1500.0f;
+ maxSwingLagZ = 2500.0f;
+ maxSwingSizeZ = 100.0f;
+ swingRateAccel = 70.0f;
+ swingSizeAccel = 70.0f;
+ if ((this->sfxTimer % 16) == 0) {
+ func_800F4B58(&this->tentTipPos, NA_SE_EN_MOFER_WAVE, D_801305D0);
+ func_800AA000(0, 160, 5, 4);
+ func_8002F7DC(&player->actor, NA_SE_VO_LI_FREEZE + player->ageProperties->unk_92);
+ }
+ }
+ } else if (this->work[MO_TENT_ACTION_STATE] == MO_TENT_RETREAT) {
+ maxSwingRateX = 1300.0f;
+ maxSwingLagX = 3200.0f;
+ maxSwingSizeX = 7000.0f;
+ maxSwingRateZ = 800.0f;
+ maxSwingLagZ = 2500.0f;
+ maxSwingSizeZ = 5000.0f;
+ swingRateAccel = 30.0f;
+ swingSizeAccel = 30.0f;
+ } else if (this->work[MO_TENT_ACTION_STATE] >= MO_TENT_DEATH_START) {
+ maxSwingRateX = -400.0f;
+ maxSwingLagX = -3200.0f;
+ maxSwingSizeX = 0.0f;
+ maxSwingRateZ = 2300.0f;
+ maxSwingLagZ = 3200.0f;
+ maxSwingSizeZ = 1000.0;
+ swingRateAccel = 30.0f;
+ swingSizeAccel = 60.0f;
+ }
+ Math_ApproachF(&this->fwork[MO_TENT_SWING_RATE_X], maxSwingRateX, 1.0f, swingRateAccel);
+ Math_ApproachF(&this->fwork[MO_TENT_SWING_LAG_X], maxSwingLagX, 1.0f, 30.0f);
+ Math_ApproachF(&this->fwork[MO_TENT_SWING_SIZE_X], maxSwingSizeX, 1.0f, swingSizeAccel);
+ Math_ApproachF(&this->fwork[MO_TENT_SWING_RATE_Z], maxSwingRateZ, 1.0f, swingRateAccel);
+ Math_ApproachF(&this->fwork[MO_TENT_SWING_LAG_Z], maxSwingLagZ, 1.0f, 30.0f);
+ Math_ApproachF(&this->fwork[MO_TENT_SWING_SIZE_Z], maxSwingSizeZ, 1.0f, swingSizeAccel);
+ this->xSwing += (s16)this->fwork[MO_TENT_SWING_RATE_X];
+ this->zSwing += (s16)this->fwork[MO_TENT_SWING_RATE_Z];
+ }
+ switch (this->work[MO_TENT_ACTION_STATE]) {
+ case MO_TENT_WAIT:
+ this->actor.flags &= ~1;
+ if (this == sMorphaTent2) {
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_SPAWN;
+ this->timers[0] = 70;
+ this->actor.shape.rot.y = this->actor.yawTowardsPlayer;
+ }
+ break;
+ case MO_TENT_SPAWN:
+ this->drawActor = true;
+ this->baseBubblesTimer = 20;
+ if (this->timers[0] < 20) {
+ Math_ApproachF(&this->tentRippleSize, 0.15f, 0.5f, 0.01);
+ Math_ApproachF(&this->baseAlpha, 150.0f, 1.0f, 5.0f);
+ if (this->baseAlpha >= 150.0f) {
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_READY;
+ this->timers[0] = 60;
+ }
+ }
+ if (this->timers[0] > 50) {
+ rippleCount = 1;
+ } else if (this->timers[0] > 40) {
+ rippleCount = 3;
+ } else if (this->timers[0] > 30) {
+ rippleCount = 5;
+ } else if (this->timers[0] > 20) {
+ rippleCount = 8;
+ } else {
+ rippleCount = 3;
+ }
+ for (indS1 = 0; indS1 < rippleCount; indS1++) {
+ randFloat = Rand_ZeroFloat(50.0f);
+ randAngle = Rand_ZeroFloat(0x10000);
+ ripplePos = this->actor.world.pos;
+ ripplePos.x += sinf(randAngle) * randFloat;
+ ripplePos.z += cosf(randAngle) * randFloat;
+ ripplePos.y = MO_WATER_LEVEL(globalCtx);
+ BossMo_SpawnRipple(globalCtx->specialEffects, &ripplePos, 40.0f, 110.0f, 80, 290, MO_FX_SMALL_RIPPLE);
+ }
+ break;
+ case MO_TENT_READY:
+ case MO_TENT_SWING:
+ if (sMorphaCore->csState == MO_BATTLE) {
+ func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_APPEAR - SFX_FLAG);
+ }
+ Math_ApproachF(&this->waterLevelMod, -5.0f, 0.1f, 0.4f);
+ for (indS1 = 0; indS1 < 41; indS1++) {
+
+ sin = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_X] * indS1) + this->xSwing);
+ tempf1 = this->fwork[MO_TENT_SWING_SIZE_X] * (indS1 * 0.025f * sin);
+
+ cos = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_Z] * indS1) + this->zSwing);
+ tempf2 = this->fwork[MO_TENT_SWING_SIZE_Z] * (indS1 * 0.025f * cos);
+
+ Math_ApproachF(&this->tentStretch[indS1].y, this->fwork[MO_TENT_MAX_STRETCH] * 5.0f, 0.1f, 0.4f);
+ if (indS1 == 28) {
+ sp1B4 = this->tentRot[indS1].x;
+ }
+ Math_ApproachS(&this->tentRot[indS1].x, tempf1, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ Math_ApproachS(&this->tentRot[indS1].z, tempf2, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ }
+ this->targetPos = this->actor.world.pos;
+ Math_ApproachF(&this->actor.speedXZ, 0.75f, 1.0f, 0.04f);
+ if (this->work[MO_TENT_ACTION_STATE] == MO_TENT_SWING) {
+ Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer + this->attackAngleMod, 0xA,
+ 0x1F4);
+ }
+ Math_ApproachF(&this->fwork[MO_TENT_MAX_STRETCH], 1.0f, 0.5f, 0.04);
+ if (sMorphaCore->csState != MO_BATTLE) {
+ Math_ApproachF(&this->tentMaxAngle, 1.0f, 1.0f, 0.001f);
+ Math_ApproachF(&this->tentSpeed, 240.0f, 1.0f, 3.0);
+ } else {
+ Math_ApproachF(&this->tentMaxAngle, 1.0f, 1.0f, 0.002f);
+ Math_ApproachF(&this->tentSpeed, 400.0f, 1.0f, 6.0f);
+ }
+ if (this->work[MO_TENT_ACTION_STATE] == MO_TENT_READY) {
+ if ((this->timers[0] == 0) && !HAS_LINK(otherTent)) {
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_SWING;
+ this->timers[0] = 50;
+ func_800F4BE8();
+ this->attackAngleMod = Rand_CenteredFloat(0x1000);
+ }
+ } else {
+ tentXrot = this->tentRot[28].x;
+ if ((this->timers[0] == 0) && (tentXrot >= 0) && (sp1B4 < 0)) {
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_ATTACK;
+ if (this == sMorphaTent1) {
+ this->timers[0] = 175;
+ } else {
+ this->timers[0] = 55;
+ }
+ }
+ }
+ break;
+ case MO_TENT_ATTACK:
+ this->actor.flags |= 0x1000000;
+ func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_ATTACK - SFX_FLAG);
+ Math_ApproachF(&this->waterLevelMod, -5.0f, 0.1f, 0.4f);
+ for (indS1 = 0; indS1 < 41; indS1++) {
+ Math_ApproachF(&this->tentStretch[indS1].y,
+ this->fwork[MO_TENT_MAX_STRETCH] * ((((40 - indS1) * 25.0f) / 100.0f) + 5.0f), 0.5f,
+ 0.7f);
+ Math_ApproachS(&this->tentRot[indS1].x, sAttackRot[indS1] * 0x100, 1.0f / this->tentMaxAngle,
+ this->tentSpeed);
+ Math_ApproachS(&this->tentRot[indS1].z, 0, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ }
+ this->targetPos = this->actor.world.pos;
+ Math_ApproachF(&this->tentMaxAngle, 0.5f, 1.0f, 0.01);
+ Math_ApproachF(&this->tentSpeed, 160.0f, 1.0f, 50.0f);
+ if ((this->timers[0] == 0) || (this->linkHitTimer != 0)) {
+ dx = this->tentPos[22].x - player->actor.world.pos.x;
+ dy = this->tentPos[22].y - player->actor.world.pos.y;
+ dz = this->tentPos[22].z - player->actor.world.pos.z;
+ if ((fabsf(dy) < 50.0f) && !HAS_LINK(otherTent) && (sqrtf(SQ(dx) + SQ(dy) + SQ(dz)) < 120.0f)) {
+ this->tentMaxAngle = .001f;
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_CURL;
+ this->timers[0] = 40;
+ this->tentSpeed = 0;
+ if ((s16)(this->actor.shape.rot.y - this->actor.yawTowardsPlayer) >= 0) {
+ this->linkToLeft = false;
+ } else {
+ this->linkToLeft = true;
+ }
+ } else {
+ this->tentMaxAngle = .001f;
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_READY;
+ this->tentSpeed = 0;
+ this->fwork[MO_TENT_SWING_RATE_X] = 0;
+ this->fwork[MO_TENT_SWING_RATE_Z] = 0;
+ this->fwork[MO_TENT_SWING_SIZE_X] = 0;
+ this->fwork[MO_TENT_SWING_SIZE_Z] = 0;
+ this->timers[0] = 30;
+ if ((fabsf(player->actor.world.pos.x - this->actor.world.pos.x) > 300.0f) ||
+ (player->actor.world.pos.y < MO_WATER_LEVEL(globalCtx)) || HAS_LINK(otherTent) ||
+ (fabsf(player->actor.world.pos.z - this->actor.world.pos.z) > 300.0f)) {
+
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_RETREAT;
+ this->timers[0] = 75;
+ }
+ }
+ }
+ break;
+ case MO_TENT_CURL:
+ case MO_TENT_GRAB:
+ Math_ApproachF(&this->waterLevelMod, -5.0f, 0.1f, 0.4f);
+ if (this->timers[0] == 125) {
+ this->tentMaxAngle = .001f;
+ this->tentSpeed = 0;
+ }
+ for (indS1 = 0; indS1 < 41; indS1++) {
+ if (this->timers[0] > 25) {
+ if (!this->linkToLeft) {
+ Math_ApproachS(&this->tentRot[indS1].z, sCurlRot[indS1] * 0x100, 1.0f / this->tentMaxAngle,
+ this->tentSpeed);
+ } else {
+ Math_ApproachS(&this->tentRot[indS1].z, sCurlRot[indS1] * -0x100, 1.0f / this->tentMaxAngle,
+ this->tentSpeed);
+ }
+ } else {
+ if (!this->linkToLeft) {
+ Math_ApproachS(&this->tentRot[indS1].z, sGrabRot[indS1] * 0x100, 1.0f / this->tentMaxAngle,
+ this->tentSpeed);
+ } else {
+ Math_ApproachS(&this->tentRot[indS1].z, sGrabRot[indS1] * -0x100, 1.0f / this->tentMaxAngle,
+ this->tentSpeed);
+ }
+ }
+ }
+ Math_ApproachF(&this->tentMaxAngle, 0.1f, 1.0f, 0.01f);
+ Math_ApproachF(&this->tentSpeed, 960.0f, 1.0f, 30.0f);
+ if (this->timers[0] >= 30) {
+ Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0xC8);
+ }
+ if (this->work[MO_TENT_ACTION_STATE] == MO_TENT_CURL) {
+ if ((this->timers[0] >= 5) && (this->linkHitTimer != 0) && (player->actor.parent == NULL)) {
+ if (globalCtx->grabPlayer(globalCtx, player)) {
+ player->actor.parent = &this->actor;
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_GRAB;
+ func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_CATCH);
+ Audio_PlaySoundGeneral(NA_SE_VO_LI_DAMAGE_S, &player->actor.projectedPos, 4, &D_801333E0,
+ &D_801333E0, &D_801333E8);
+ } else {
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_READY;
+ this->tentMaxAngle = .001f;
+ this->tentSpeed = 0;
+ this->fwork[MO_TENT_SWING_SIZE_Z] = 0;
+ this->fwork[MO_TENT_SWING_SIZE_X] = 0;
+ this->fwork[MO_TENT_SWING_RATE_Z] = 0;
+ this->fwork[MO_TENT_SWING_RATE_X] = 0;
+ this->timers[0] = 30;
+ }
+ }
+ if (this->timers[0] == 4) {
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_READY;
+ this->tentMaxAngle = .001f;
+ this->tentSpeed = 0;
+ this->fwork[MO_TENT_SWING_SIZE_Z] = 0;
+ this->fwork[MO_TENT_SWING_SIZE_X] = 0;
+ this->fwork[MO_TENT_SWING_RATE_Z] = 0;
+ this->fwork[MO_TENT_SWING_RATE_X] = 0;
+ this->timers[0] = 30;
+ }
+ }
+ if (this->work[MO_TENT_ACTION_STATE] == MO_TENT_GRAB) {
+ player->unk_850 = 0xA;
+ player->actor.speedXZ = player->actor.velocity.y = 0;
+ Math_ApproachF(&player->actor.world.pos.x, this->grabPosRot.pos.x, 0.5f, 20.0f);
+ Math_ApproachF(&player->actor.world.pos.y, this->grabPosRot.pos.y, 0.5f, 20.0f);
+ Math_ApproachF(&player->actor.world.pos.z, this->grabPosRot.pos.z, 0.5f, 20.0f);
+ Math_ApproachS(&player->actor.shape.rot.x, this->grabPosRot.rot.x, 2, 0x7D0);
+ Math_ApproachS(&player->actor.shape.rot.y, this->grabPosRot.rot.y, 2, 0x7D0);
+ Math_ApproachS(&player->actor.shape.rot.z, this->grabPosRot.rot.z, 2, 0x7D0);
+ if (this->timers[0] == 0) {
+ camera1 = Gameplay_GetCamera(globalCtx, MAIN_CAM);
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_SHAKE;
+ this->tentMaxAngle = .001f;
+ this->fwork[MO_TENT_SWING_RATE_X] = this->fwork[MO_TENT_SWING_RATE_Z] =
+ this->fwork[MO_TENT_SWING_SIZE_X] = this->fwork[MO_TENT_SWING_SIZE_Z] = this->tentSpeed = 0;
+ this->timers[0] = 150;
+ this->mashCounter = 0;
+ this->sfxTimer = 30;
+ func_800F4BE8();
+ func_80064520(globalCtx, &globalCtx->csCtx);
+ this->csCamera = Gameplay_CreateSubCamera(globalCtx);
+ Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT);
+ Gameplay_ChangeCameraStatus(globalCtx, this->csCamera, CAM_STAT_ACTIVE);
+ this->cameraEye = camera1->eye;
+ this->cameraAt = camera1->at;
+ this->cameraYaw = Math_FAtan2F(this->cameraEye.x - this->actor.world.pos.x,
+ this->cameraEye.z - this->actor.world.pos.z);
+ this->cameraYawRate = 0;
+ goto tent_shake;
+ }
+ }
+ break;
+ tent_shake:
+ case MO_TENT_SHAKE:
+ if (this->timers[0] == 138) {
+ ShrinkWindow_SetVal(0);
+ Interface_ChangeAlpha(0xB);
+ }
+ if ((this->timers[0] % 8) == 0) {
+ globalCtx->damagePlayer(globalCtx, -1);
+ }
+ Math_ApproachF(&this->waterLevelMod, -5.0f, 0.1f, 0.4f);
+ sp1B4 = this->tentRot[15].x;
+ buttons = globalCtx->state.input[0].press.button;
+ if (CHECK_BTN_ALL(buttons, BTN_A) || CHECK_BTN_ALL(buttons, BTN_B)) {
+ this->mashCounter++;
+ }
+ for (indS1 = 0; indS1 < 41; indS1++) {
+ if (indS1 < 20) {
+ sin = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_X] * indS1) + this->xSwing);
+ tempf1 = this->fwork[MO_TENT_SWING_SIZE_X] * (indS1 * 0.025f * sin);
+ cos = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_Z] * indS1) + this->zSwing);
+ tempf2 = this->fwork[MO_TENT_SWING_SIZE_Z] * (indS1 * 0.025f * cos);
+ temp = ((((40 - indS1) * 25.0f) / 100.0f) + 5.0f);
+ Math_ApproachF(&this->tentStretch[indS1].y, this->fwork[MO_TENT_MAX_STRETCH] * temp, 0.1f, 0.1f);
+ Math_ApproachS(&this->tentRot[indS1].x, tempf1, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ Math_ApproachS(&this->tentRot[indS1].z, tempf2, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ }
+ }
+ player->unk_850 = 0xA;
+ player->actor.world.pos.x = this->grabPosRot.pos.x;
+ player->actor.world.pos.y = this->grabPosRot.pos.y;
+ player->actor.world.pos.z = this->grabPosRot.pos.z;
+ player->actor.world.rot.x = player->actor.shape.rot.x = this->grabPosRot.rot.x;
+ player->actor.world.rot.y = player->actor.shape.rot.y = this->grabPosRot.rot.y;
+ player->actor.world.rot.z = player->actor.shape.rot.z = this->grabPosRot.rot.z;
+ player->actor.velocity.y = 0;
+ player->actor.speedXZ = 0;
+ Math_ApproachF(&this->fwork[MO_TENT_MAX_STRETCH], 1.0f, 0.5f, 0.01);
+ Math_ApproachF(&this->tentMaxAngle, 0.5f, 1.0f, 0.005f);
+ Math_ApproachF(&this->tentSpeed, 480.0f, 1.0f, 10.0f);
+ Math_ApproachF(&this->tentPulse, 0.3f, 0.5f, 0.03f);
+ if ((this->mashCounter >= 40) || (this->timers[0] == 0)) {
+ tentXrot = this->tentRot[15].x;
+ if ((tentXrot < 0) && (sp1B4 >= 0)) {
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_RETREAT;
+ this->work[MO_TENT_INVINC_TIMER] = 50;
+ if (&this->actor == player->actor.parent) {
+ player->unk_850 = 0x65;
+ player->actor.parent = NULL;
+ player->csMode = 0;
+ if (this->timers[0] == 0) {
+ func_8002F6D4(globalCtx, &this->actor, 20.0f, this->actor.shape.rot.y + 0x8000, 10.0f, 0);
+ }
+ }
+ this->timers[0] = 75;
+ }
+ }
+ if (this->csCamera != 0) {
+ sp138.x = 0;
+ sp138.y = 100.0f;
+ sp138.z = 200.0f;
+ this->cameraYaw -= this->cameraYawRate;
+ Math_ApproachF(&this->cameraYawRate, 0.01, 1.0f, 0.002f);
+ Matrix_RotateY(this->cameraYaw, MTXMODE_NEW);
+ Matrix_MultVec3f(&sp138, &sp12C);
+ Math_ApproachF(&this->cameraEye.x, this->actor.world.pos.x + sp12C.x, 0.1f, 10.0f);
+ Math_ApproachF(&this->cameraEye.y, this->actor.world.pos.y + sp12C.y, 0.1f, 10.0f);
+ Math_ApproachF(&this->cameraEye.z, this->actor.world.pos.z + sp12C.z, 0.1f, 10.0f);
+ Math_ApproachF(&this->cameraAt.x, player->actor.world.pos.x, 0.5f, 50.0f);
+ Math_ApproachF(&this->cameraAt.y, player->actor.world.pos.y, 0.5f, 50.0f);
+ Math_ApproachF(&this->cameraAt.z, player->actor.world.pos.z, 0.5f, 50.0f);
+ Gameplay_CameraSetAtEye(globalCtx, this->csCamera, &this->cameraAt, &this->cameraEye);
+ }
+ break;
+ case MO_TENT_CUT:
+ func_80078914(&this->tentTipPos, NA_SE_EV_WATER_WALL - SFX_FLAG);
+ if (&this->actor == player->actor.parent) {
+ player->unk_850 = 0x65;
+ player->actor.parent = NULL;
+ player->csMode = 0;
+ }
+ Math_ApproachF(&this->tentRippleSize, 0.15f, 0.5f, 0.01);
+ if (this->meltIndex < 41) {
+ for (indS0 = 0; indS0 < 10; indS0++) {
+ sp120 = this->tentPos[this->meltIndex];
+ sp120.x += Rand_CenteredFloat(30.0f);
+ sp120.y += Rand_CenteredFloat(30.0f);
+ sp120.z += Rand_CenteredFloat(30.0f);
+ BossMo_SpawnStillDroplet(globalCtx->specialEffects, &sp120, Rand_ZeroFloat(0.1f) + .2f);
+ }
+ this->meltIndex++;
+ }
+ Math_ApproachF(&this->cutScale, 0.0, 1.0f, 0.2f);
+ if ((this->meltIndex >= 41) || (this->timers[0] == 0)) {
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_RETREAT;
+ this->timers[0] = 75;
+ this->tentMaxAngle = 0.005f;
+ this->tentSpeed = 50.0f;
+ this->fwork[MO_TENT_SWING_SIZE_X] = 7000.0f;
+ this->fwork[MO_TENT_SWING_SIZE_Z] = 5000.0f;
+ }
+ break;
+ case MO_TENT_RETREAT:
+ if (this->csCamera != 0) {
+ Math_ApproachF(&this->cameraAt.x, player->actor.world.pos.x, 0.5f, 50.0f);
+ Math_ApproachF(&this->cameraAt.y, player->actor.world.pos.y, 0.5f, 50.0f);
+ Math_ApproachF(&this->cameraAt.z, player->actor.world.pos.z, 0.5f, 50.0f);
+ Gameplay_CameraSetAtEye(globalCtx, this->csCamera, &this->cameraAt, &this->cameraEye);
+ if (player->actor.world.pos.y <= 42.0f) {
+ camera2 = Gameplay_GetCamera(globalCtx, MAIN_CAM);
+ camera2->eye = this->cameraEye;
+ camera2->eyeNext = this->cameraEye;
+ camera2->at = this->cameraAt;
+ func_800C08AC(globalCtx, this->csCamera, 0);
+ this->csCamera = 0;
+ func_80064534(globalCtx, &globalCtx->csCtx);
+ }
+ }
+ for (indS1 = 0; indS1 < 41; indS1++) {
+ sin = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_X] * indS1) + this->xSwing);
+ tempf1 = (indS1 * 0.025f * sin * this->fwork[MO_TENT_SWING_SIZE_X]) * this->fwork[MO_TENT_MAX_STRETCH];
+ cos = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_Z] * indS1) + this->zSwing);
+ tempf2 = (indS1 * 0.025f * cos * this->fwork[MO_TENT_SWING_SIZE_Z]) * this->fwork[MO_TENT_MAX_STRETCH];
+ Math_ApproachF(&this->tentStretch[indS1].y, this->fwork[MO_TENT_MAX_STRETCH] * 5.0f, 0.5f, 0.2f);
+ Math_ApproachS(&this->tentRot[indS1].x, tempf1, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ Math_ApproachS(&this->tentRot[indS1].z, tempf2, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ }
+ Math_ApproachF(&this->fwork[MO_TENT_MAX_STRETCH], 0, 0.5f, 0.02f);
+ Math_ApproachF(&this->tentMaxAngle, 0.5f, 1.0f, 0.01);
+ Math_ApproachF(&this->tentSpeed, 320.0f, 1.0f, 50.0f);
+ if (this->timers[0] == 0) {
+ this->actor.flags &= ~1;
+ Math_ApproachF(&this->baseAlpha, 0.0, 1.0f, 5.0f);
+ for (indS1 = 0; indS1 < 40; indS1++) {
+ if (sMorphaTent2->tentSpawnPos) {}
+ indT5 = Rand_ZeroFloat(20.9f);
+ indS0 = sTentSpawnIndex[indT5];
+ spFC.x = 0;
+ spFC.y = 0;
+ spFC.z = 0;
+ Matrix_RotateY((player->actor.world.rot.y / (f32)0x8000) * M_PI, MTXMODE_NEW);
+ Matrix_MultVec3f(&spFC, &spF0);
+ spF0.x = player->actor.world.pos.x + spF0.x;
+ spF0.z = player->actor.world.pos.z + spF0.z;
+ if ((fabsf(spF0.x - sTentSpawnPos[indS0].x) <= 320) &&
+ (fabsf(spF0.z - sTentSpawnPos[indS0].y) <= 320) &&
+ ((sMorphaTent2 == NULL) || (sMorphaTent2->tentSpawnPos != indS0))) {
+ this->targetPos.x = sTentSpawnPos[indS0].x;
+ this->targetPos.z = sTentSpawnPos[indS0].y;
+ this->tentSpawnPos = indS0;
+ this->timers[0] = (s16)Rand_ZeroFloat(20.0f) + 30;
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_DESPAWN;
+ break;
+ }
+ }
+ }
+ if ((this == sMorphaTent1) && (sMorphaCore->hitCount >= 3) && (sMorphaTent2 == NULL)) {
+ sMorphaTent2 =
+ (BossMo*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_BOSS_MO, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, BOSSMO_TENTACLE);
+
+ sMorphaTent2->tentSpawnPos = this->tentSpawnPos;
+ if (sMorphaTent2->tentSpawnPos > 10) {
+ sMorphaTent2->tentSpawnPos--;
+ } else {
+ sMorphaTent2->tentSpawnPos++;
+ }
+ sMorphaTent2->targetPos.x = sTentSpawnPos[sMorphaTent2->tentSpawnPos].x;
+ sMorphaTent2->targetPos.z = sTentSpawnPos[sMorphaTent2->tentSpawnPos].y;
+ sMorphaTent2->timers[0] = 100;
+ sMorphaTent2->work[MO_TENT_ACTION_STATE] = MO_TENT_DESPAWN;
+ sMorphaTent2->otherTent = &sMorphaTent1->actor;
+ sMorphaTent1->otherTent = &sMorphaTent2->actor;
+ }
+ break;
+ case MO_TENT_DESPAWN:
+ this->actor.flags &= ~1;
+ Math_ApproachF(&this->baseAlpha, 0, 1.0f, 5.0f);
+ if ((this->baseAlpha <= 0.5f) && (this->timers[0] == 0)) {
+ this->meltIndex = 0;
+ this->actor.world.pos.x = this->targetPos.x;
+ this->actor.world.pos.z = this->targetPos.z;
+ this->actor.prevPos = this->actor.world.pos;
+ this->cutScale = 1.0f;
+ this->cutIndex = this->meltIndex;
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_WAIT;
+ this->timers[0] = (s16)Rand_ZeroFloat(20.0f) + 10;
+
+ this->tentSpeed = 0;
+ this->fwork[MO_TENT_SWING_RATE_X] = 0;
+ this->fwork[MO_TENT_SWING_RATE_Z] = 0;
+ this->fwork[MO_TENT_SWING_SIZE_X] = 0;
+ this->fwork[MO_TENT_SWING_SIZE_Z] = 0;
+
+ this->tentMaxAngle = .001f;
+ }
+ break;
+ case MO_TENT_DEATH_START:
+ this->actor.shape.rot.y = 0x4000;
+ break;
+ case MO_TENT_DEATH_3:
+ this->baseBubblesTimer = 20;
+ Math_ApproachF(&sMorphaCore->waterLevel, -300.0f, 0.1f, 0.8f);
+ this->actor.flags &= ~1;
+ for (indS1 = 0; indS1 < 41; indS1++) {
+ sin = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_X] * indS1) + this->xSwing);
+ tempf1 = this->fwork[MO_TENT_SWING_SIZE_X] * (indS1 * 0.025f * sin);
+ cos = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_Z] * indS1) + this->zSwing);
+ tempf2 = this->fwork[MO_TENT_SWING_SIZE_Z] * (indS1 * 0.025f * cos);
+ Math_ApproachF(&this->tentStretch[indS1].y, this->fwork[MO_TENT_MAX_STRETCH] * 5.0f, 0.1f, 0.4f);
+ Math_ApproachS(&this->tentRot[indS1].x, tempf1, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ Math_ApproachS(&this->tentRot[indS1].z, tempf2, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ }
+ this->actor.speedXZ = 0.0;
+ Math_ApproachF(&this->fwork[MO_TENT_MAX_STRETCH], 4.3f, 0.5f, 0.04);
+ Math_ApproachF(&this->tentPulse, 1.3f, 0.5f, 0.05f);
+ break;
+ case MO_TENT_DEATH_1:
+ this->baseBubblesTimer = 20;
+ this->actor.shape.rot.y = 0x4000;
+ this->actor.shape.rot.x = -0x8000;
+ this->actor.world.pos.y = sMorphaCore->waterLevel + 650.0f;
+ Math_ApproachF(&sMorphaCore->waterLevel, -300.0f, 0.1f, 1.3f);
+ for (indS1 = 0; indS1 < 41; indS1++) {
+ sin = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_X] * indS1) + this->xSwing);
+ tempf1 = this->fwork[MO_TENT_SWING_SIZE_X] * (indS1 * 0.025f * sin);
+ cos = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_Z] * indS1) + this->zSwing);
+ tempf2 = this->fwork[MO_TENT_SWING_SIZE_Z] * (indS1 * 0.025f * cos);
+ Math_ApproachF(&this->tentStretch[indS1].y, this->fwork[MO_TENT_MAX_STRETCH] * 5.0f, 0.1f, 0.4f);
+ Math_ApproachS(&this->tentRot[indS1].x, tempf1, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ Math_ApproachS(&this->tentRot[indS1].z, tempf2, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ }
+ this->actor.speedXZ = 0.0;
+ Math_ApproachF(&this->tentPulse, 1.3f, 0.5f, 0.05f);
+ break;
+ case MO_TENT_DEATH_2:
+ this->baseBubblesTimer = 20;
+ Math_ApproachF(&sMorphaCore->waterLevel, -295.0f, 0.1f, 1.3f);
+ this->actor.world.pos.y = sMorphaCore->waterLevel + 650.0f;
+ for (indS1 = 0; indS1 < 41; indS1++) {
+ sin = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_X] * indS1) + this->xSwing);
+ tempf1 = this->fwork[MO_TENT_SWING_SIZE_X] * (indS1 * 0.025f * sin);
+ cos = Math_SinS(((s16)this->fwork[MO_TENT_SWING_LAG_Z] * indS1) + this->zSwing);
+ tempf2 = this->fwork[MO_TENT_SWING_SIZE_Z] * (indS1 * 0.025f * cos);
+ Math_ApproachF(&this->tentStretch[indS1].y, this->fwork[MO_TENT_MAX_STRETCH] * 5.0f, 0.1f, 0.4f);
+ Math_ApproachS(&this->tentRot[indS1].x, tempf1, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ Math_ApproachS(&this->tentRot[indS1].z, tempf2, 1.0f / this->tentMaxAngle, this->tentSpeed);
+ }
+ this->actor.speedXZ = 0.0;
+ this->noBubbles--;
+ Math_ApproachF(&this->fwork[MO_TENT_MAX_STRETCH], 0.1f, 0.1f, 0.03);
+ Math_ApproachF(&this->tentPulse, 0.02f, 0.5f, 0.015f);
+ if ((this->timers[0] > 0) && (this->timers[0] < 40)) {
+ Math_ApproachF(&this->actor.scale.x, 0.035f, 0.05f, this->flattenRate);
+ if (this->timers[0] == 1) {
+ this->flattenRate = 0.0;
+ }
+ } else if (this->timers[0] == 0) {
+ Math_ApproachF(&this->actor.scale.x, .001f, 0.05f, this->flattenRate);
+ }
+ Math_ApproachF(&this->flattenRate, 0.00045f, 0.1f, 0.00001f);
+ break;
+ case MO_TENT_DEATH_5:
+ for (indS1 = 0; indS1 < 41; indS1++) {
+ if (this->timers[0] != 0) {
+ Math_ApproachF(&this->tentStretch[indS1].y, this->fwork[MO_TENT_MAX_STRETCH] * 5.0f, 0.05f,
+ this->tentSpeed);
+ } else {
+ Math_ApproachF(&this->tentStretch[indS1].y, this->fwork[MO_TENT_MAX_STRETCH] * 5.0f, 0.3f, 100.0f);
+ }
+ this->tentRot[indS1].x = this->tentRot[indS1].z = 0;
+ }
+ this->tentPulse = 0.0;
+ if (this->timers[0] != 0) {
+ this->actor.world.pos.y = sMorphaCore->waterLevel + 650.0f;
+ this->fwork[MO_TENT_MAX_STRETCH] = 0.5f;
+ Math_ApproachF(&this->actor.scale.x, 0.0015f, 0.05f, this->tentMaxAngle);
+ Math_ApproachF(&this->tentMaxAngle, 0.00035f, 1.0f, 0.0000175f);
+ Math_ApproachF(&this->tentSpeed, 0.1f, 1.0f, 0.005f);
+ this->actor.velocity.y = 0.0;
+ } else {
+ this->fwork[MO_TENT_MAX_STRETCH] = 0.2f;
+ this->fwork[MO_TENT_MAX_STRETCH] += Math_SinS(this->work[MO_TENT_MOVE_TIMER] * 0x2000) * 0.05f;
+ padEC = Math_CosS(this->work[MO_TENT_MOVE_TIMER] * 0x2000) * 0.0005f;
+ Math_ApproachF(&this->actor.scale.x, 0.002f + padEC, 0.5f, 0.0005f);
+ this->actor.world.pos.y += this->actor.velocity.y;
+ this->actor.velocity.y -= 1.0f;
+ if (this->actor.world.pos.y < -250.0f) {
+ this->actor.world.pos.y = -250.0f;
+ this->actor.velocity.y = 0.0;
+ this->drawActor = false;
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_DEATH_6;
+ this->timers[0] = 60;
+ func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_CORE_JUMP);
+ for (indS1 = 0; indS1 < 300; indS1++) {
+ spC8.x = 0.0;
+ spC8.y = 0.0;
+ spC8.z = indS1 * 0.03f;
+ Matrix_RotateY(indS1 * 0.23f, MTXMODE_NEW);
+ Matrix_MultVec3f(&spC8, &spE0);
+ spE0.y = Rand_ZeroFloat(7.0f) + 4.0f;
+ spD4 = this->actor.world.pos;
+ spD4.x += spE0.x * 3.0f;
+ spD4.y += (spE0.y * 3.0f) - 30.0f;
+ if (spD4.y < -280.0f) {
+ spD4.y = -280.0f;
+ }
+ spD4.z += spE0.z * 3.0f;
+ BossMo_SpawnDroplet(MO_FX_DROPLET, (BossMoEffect*)globalCtx->specialEffects, &spD4, &spE0,
+ ((300 - indS1) * .0015f) + 0.13f);
+ }
+ Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_DOOR_WARP1,
+ this->actor.world.pos.x, -280.0f, this->actor.world.pos.z, 0, 0, 0, -1);
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_B_HEART, this->actor.world.pos.x + 200.0f,
+ -280.0f, this->actor.world.pos.z, 0, 0, 0, 0);
+ Audio_QueueSeqCmd(0x21);
+ Flags_SetClear(globalCtx, globalCtx->roomCtx.curRoom.num);
+ }
+ }
+ break;
+ case MO_TENT_DEATH_6:
+ break;
+ }
+ this->actor.scale.y = this->actor.scale.z = this->actor.scale.x;
+ if (((this->work[MO_TENT_ACTION_STATE] == MO_TENT_ATTACK) ||
+ (this->work[MO_TENT_ACTION_STATE] == MO_TENT_DEATH_2) || (this->work[MO_TENT_ACTION_STATE] == MO_TENT_CURL) ||
+ (this->work[MO_TENT_ACTION_STATE] == MO_TENT_GRAB)) &&
+ (Rand_ZeroOne() < 0.8f) && (this->actor.scale.x > 0.001f)) {
+ Vec3f pos; // real
+ Vec3f velocity = { 0.0f, 0.0f, 0.0f }; // real
+ f32 scale;
+ f32 temp;
+
+ if (this->work[MO_TENT_ACTION_STATE] >= MO_TENT_DEATH_2) {
+ indS1 = 38;
+ scale = Rand_ZeroFloat(0.1f) + 0.1f;
+ pos.y = this->tentPos[indS1].y;
+ } else {
+ indS1 = (s16)Rand_ZeroFloat(20.0f) + 18;
+ scale = Rand_ZeroFloat(0.02f) + .05f;
+ pos.y = this->tentPos[indS1].y - 10.0f;
+ }
+ temp = (this->actor.scale.x * 100.0f) * 20.0f;
+ pos.x = this->tentPos[indS1].x + Rand_CenteredFloat(temp);
+ pos.z = this->tentPos[indS1].z + Rand_CenteredFloat(temp);
+ BossMo_SpawnDroplet(MO_FX_DROPLET, (BossMoEffect*)globalCtx->specialEffects, &pos, &velocity, scale);
+ }
+}
+
+void BossMo_TentCollisionCheck(BossMo* this, GlobalContext* globalCtx) {
+ s16 i1;
+
+ for (i1 = 0; i1 < ARRAY_COUNT(this->tentElements); i1++) {
+ if (this->tentCollider.elements[i1].info.bumperFlags & BUMP_HIT) {
+ s16 i2;
+ ColliderInfo* hurtbox;
+
+ for (i2 = 0; i2 < 19; i2++) {
+ this->tentCollider.elements[i2].info.bumperFlags &= ~BUMP_HIT;
+ this->tentCollider.elements[i2].info.toucherFlags &= ~TOUCH_HIT;
+ }
+ hurtbox = this->tentCollider.elements[i1].info.acHitInfo;
+ this->work[MO_TENT_INVINC_TIMER] = 5;
+ if (hurtbox->toucher.dmgFlags & 0x00020000) {
+ func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_CUT);
+ this->cutIndex = 15;
+ this->meltIndex = this->cutIndex + 1;
+ this->work[MO_TENT_ACTION_STATE] = MO_TENT_CUT;
+ this->timers[0] = 40;
+ this->cutScale = 1.0f;
+ } else if (hurtbox->toucher.dmgFlags & 0x0D800600) {
+ this->linkHitTimer = 5;
+ }
+ this->tentRippleSize = 0.2f;
+ for (i2 = 0; i2 < 10; i2++) {
+ Vec3f pos;
+ Vec3f velocity;
+
+ velocity.x = Rand_CenteredFloat(8.0f);
+ velocity.y = Rand_ZeroFloat(7.0f) + 4.0f;
+ velocity.z = Rand_CenteredFloat(8.0f);
+ pos = this->tentPos[2 * i1];
+ pos.x += velocity.x * 3.0f;
+ pos.z += velocity.z * 3.0f;
+ BossMo_SpawnDroplet(MO_FX_DROPLET, (BossMoEffect*)globalCtx->specialEffects, &pos, &velocity,
+ Rand_ZeroFloat(0.08f) + 0.13f);
+ }
+ break;
+ } else if (this->tentCollider.elements[i1].info.toucherFlags & TOUCH_HIT) {
+ this->tentCollider.elements[i1].info.toucherFlags &= ~TOUCH_HIT;
+ this->linkHitTimer = 5;
+ break;
+ }
+ }
+}
+
+void BossMo_IntroCs(BossMo* this, GlobalContext* globalCtx) {
+ static Vec3f cutsceneTargets[6] = {
+ { -360.0f, -190.0f, 0.0f }, { 250.0f, -190.0f, 0.0f }, { 300.0f, -120.0f, -278.0f },
+ { 180.0f, -80.0f, -340.0f }, { 180.0f, 0.0f, -340.0f }, { 180.0f, 60.0f, -230.0f },
+ };
+ u8 sp9F = 0;
+ f32 dx;
+ f32 dy;
+ f32 dz;
+ f32 tempX;
+ f32 tempY;
+ s32 pad84;
+ f32 sp80;
+ f32 sp7C;
+ f32 sp78;
+ Player* player = PLAYER;
+ Camera* camera = Gameplay_GetCamera(globalCtx, MAIN_CAM);
+ Vec3f bubblePos;
+ Vec3f bubblePos2;
+ Camera* camera2;
+ f32 pad50;
+ f32 pad4C;
+ f32 pad48;
+
+ if (this->csState < MO_INTRO_REVEAL) {
+ this->cameraZoom = 80.0f;
+ }
+ switch (this->csState) {
+ case MO_INTRO_WAIT:
+ if (this->timers[0] == 1) {
+ func_8010B680(globalCtx, 0x403F, NULL);
+ }
+ if (((fabsf(player->actor.world.pos.z - 180.0f) < 40.0f) &&
+ (fabsf(player->actor.world.pos.x - 180.0f) < 40.0f)) ||
+ ((fabsf(player->actor.world.pos.z - -180.0f) < 40.0f) &&
+ (fabsf(player->actor.world.pos.x - 180.0f) < 40.0f)) ||
+ ((fabsf(player->actor.world.pos.z - 180.0f) < 40.0f) &&
+ (fabsf(player->actor.world.pos.x - -180.0f) < 40.0f)) ||
+ ((fabsf(player->actor.world.pos.z - -180.0f) < 40.0f) &&
+ (fabsf(player->actor.world.pos.x - -180.0f) < 40.0f))) {
+ // checks if Link is on one of the four platforms
+ func_80064520(globalCtx, &globalCtx->csCtx);
+ func_8002DF54(globalCtx, &this->actor, 8);
+ this->csCamera = Gameplay_CreateSubCamera(globalCtx);
+ Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT);
+ Gameplay_ChangeCameraStatus(globalCtx, this->csCamera, CAM_STAT_ACTIVE);
+ this->actor.speedXZ = 0.0f;
+ this->csState = MO_INTRO_START;
+ this->timers[2] = 50;
+ this->work[MO_TENT_VAR_TIMER] = this->work[MO_TENT_MOVE_TIMER] = 0;
+ this->actor.world.rot.y = 0x721A;
+ sMorphaTent1->work[MO_TENT_ACTION_STATE] = MO_TENT_READY;
+ sMorphaTent1->timers[0] = 30000;
+ Audio_QueueSeqCmd(0x103200FF);
+ func_80106CCC(globalCtx);
+ } else {
+ break;
+ }
+ case MO_INTRO_START:
+ player->actor.world.pos.x = 180.0f;
+ player->actor.world.pos.z = -130.0f;
+ player->actor.shape.rot.y = player->actor.world.rot.y = 0;
+ player->actor.speedXZ = 0.0f;
+ this->cameraEye.x = -424.0f;
+ this->cameraEye.y = -190.0f;
+ this->cameraEye.z = 180.0f;
+ this->cameraAt.x = player->actor.world.pos.x;
+ this->cameraAt.y = -330.0f;
+ this->cameraAt.z = 0.0f;
+ if (this->timers[2] == 0) {
+ this->csState = MO_INTRO_SWIM;
+ this->work[MO_TENT_MOVE_TIMER] = 0;
+ } else if (this->timers[2] < 50) {
+ bubblePos.x = (this->cameraEye.x + 20.0f) + 10.0f;
+ bubblePos.y = -250.0f;
+ bubblePos.z = this->cameraEye.z;
+ EffectSsBubble_Spawn(globalCtx, &bubblePos, 0.0f, 10.0f, 50.0f, Rand_ZeroFloat(0.05f) + 0.13f);
+ }
+ if (this->timers[2] == 40) {
+ func_80078914(&sAudioZeroVec, NA_SE_EN_MOFER_BUBLE_DEMO);
+ }
+ break;
+ case MO_INTRO_SWIM:
+ Math_ApproachF(&this->cameraYawShake, 0.1f, 1.0f, 0.002f);
+ this->targetPos = cutsceneTargets[this->targetIndex];
+ if (this->targetIndex == 5) {
+ tempY = Math_SinS(this->work[MO_TENT_MOVE_TIMER] * 0x500) * 20.0f;
+ } else {
+ tempY = Math_SinS(this->work[MO_TENT_MOVE_TIMER] * 0x500) * 5.0f;
+ }
+ dx = this->targetPos.x - this->cameraEye.x;
+ dy = this->targetPos.y - this->cameraEye.y + tempY;
+ dz = this->targetPos.z - this->cameraEye.z;
+ tempY = Math_FAtan2F(dx, dz);
+ tempX = Math_FAtan2F(dy, sqrtf(SQ(dx) + SQ(dz)));
+ Math_ApproachS(&this->actor.world.rot.y, tempY * (0x8000 / M_PI), 5, this->cameraYawRate);
+ Math_ApproachS(&this->actor.world.rot.x, tempX * (0x8000 / M_PI), 5, this->cameraYawRate);
+ if (this->work[MO_TENT_MOVE_TIMER] == 150) {
+ this->cameraAtVel.x = fabsf(this->cameraAt.x - player->actor.world.pos.x);
+ this->cameraAtVel.y = fabsf(this->cameraAt.y - player->actor.world.pos.y);
+ this->cameraAtVel.z = fabsf(this->cameraAt.z - player->actor.world.pos.z);
+ }
+ if (this->work[MO_TENT_MOVE_TIMER] >= 150) {
+ Math_ApproachF(&this->cameraAt.x, player->actor.world.pos.x, 0.1f,
+ this->cameraAtVel.x * this->cameraSpeedMod);
+ Math_ApproachF(&this->cameraAt.y, player->actor.world.pos.y + 50.0f, 0.1f,
+ this->cameraAtVel.y * this->cameraSpeedMod);
+ Math_ApproachF(&this->cameraAt.z, player->actor.world.pos.z, 0.1f,
+ this->cameraAtVel.z * this->cameraSpeedMod);
+ Math_ApproachF(&this->cameraSpeedMod, 0.02f, 1.0f, 0.001f);
+ }
+ if (this->work[MO_TENT_MOVE_TIMER] == 190) {
+ func_80078914(&sAudioZeroVec, NA_SE_EN_MOFER_BUBLE_DEMO);
+ }
+ if ((this->work[MO_TENT_MOVE_TIMER] > 150) && (this->work[MO_TENT_MOVE_TIMER] < 180)) {
+ bubblePos2.x = (this->cameraEye.x + 20.0f) + 10.0f;
+ bubblePos2.y = -250.0f;
+ bubblePos2.z = this->cameraEye.z;
+ EffectSsBubble_Spawn(globalCtx, &bubblePos2, 0.0f, 10.0f, 50.0f, Rand_ZeroFloat(0.05f) + 0.13f);
+ }
+ sp7C = (f32)0x1000;
+ sp78 = 0.1f;
+ if ((this->work[MO_TENT_MOVE_TIMER] > 100) && (this->work[MO_TENT_MOVE_TIMER] < 220)) {
+ sp80 = 0.0f;
+ } else if (this->work[MO_TENT_MOVE_TIMER] > 350) {
+ sp80 = 2.0f;
+ sp78 = 0.4f;
+ } else if (this->work[MO_TENT_MOVE_TIMER] > 220) {
+ sp80 = 7.0f;
+ sp78 = 0.3f;
+ sp7C = (f32)0x2000;
+ } else {
+ sp80 = 4.0f;
+ }
+
+ if (this->work[MO_TENT_MOVE_TIMER] > 250) {
+ Math_ApproachF(&this->fwork[MO_CORE_INTRO_WATER_ALPHA], 100.0f, 1.0f, 1.0f);
+ }
+ if (this->targetIndex < 5) {
+ if (sqrtf(SQ(dx) + SQ(dz) + SQ(dy)) < 40.0f) {
+ this->targetIndex++;
+ this->cameraYawRate = 0.0f;
+ }
+ } else {
+ sp80 = 1.5f;
+ sp7C = (f32)0x600;
+ }
+ Math_ApproachF(&this->actor.speedXZ, sp80, 1.0f, sp78);
+ Math_ApproachF(&this->cameraYawRate, sp7C, 1.0f, 128.0f);
+ if (this->work[MO_TENT_MOVE_TIMER] == 525) {
+ func_8002DF54(globalCtx, &this->actor, 2);
+ }
+ if (this->work[MO_TENT_MOVE_TIMER] > 540) {
+ this->csState = MO_INTRO_REVEAL;
+ func_8002DF54(globalCtx, &this->actor, 1);
+ sMorphaTent1->drawActor = true;
+ player->actor.world.pos.x = 180.0f;
+ player->actor.world.pos.z = -210.0f;
+ player->actor.world.rot.y = -0x8000;
+ player->actor.shape.rot.y = player->actor.world.rot.y;
+ this->cameraYawShake = 0.0f;
+ sMorphaTent1->baseAlpha = 150.0;
+ this->actor.speedXZ = 0.0f;
+ this->timers[2] = 200;
+ this->cameraZoom = 60.0f;
+ this->actor.world.pos = sMorphaTent1->actor.world.pos;
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_INTRO_REVEAL;
+ this->actor.flags &= ~1;
+ sMorphaTent1->actor.flags |= 1;
+ } else {
+ sMorphaTent1->xSwing = 0xCEC;
+ sMorphaTent1->fwork[MO_TENT_SWING_RATE_X] = 0.0f;
+ sMorphaTent1->fwork[MO_TENT_SWING_LAG_X] = 1000.0f;
+ sMorphaTent1->fwork[MO_TENT_SWING_SIZE_X] = 2500.0f;
+ break;
+ }
+ case MO_INTRO_REVEAL:
+ if (this->timers[2] >= 160) {
+ this->cameraEye.x = 150.0f;
+ this->cameraEye.y = 60.0f;
+ this->cameraEye.z = -230.0f;
+ this->cameraAt.x = 170.0f;
+ this->cameraAt.y = 40.0;
+ this->cameraAt.z = -280.0f;
+ sMorphaTent1->xSwing = 0xCEC;
+ sMorphaTent1->fwork[MO_TENT_SWING_RATE_X] = 0.0f;
+ sMorphaTent1->fwork[MO_TENT_SWING_LAG_X] = 1000.0f;
+ sMorphaTent1->fwork[MO_TENT_SWING_SIZE_X] = 2500.0f;
+ if (this->timers[2] == 160) {
+ this->cameraNextAt.y = 65.0f;
+ this->cameraNextAt.z = -280.0f;
+ this->cameraEyeVel.x = fabsf(this->cameraEye.x - 150.0f) * 0.1f;
+ this->cameraEyeVel.y = fabsf(this->cameraEye.y - 60.0f) * 0.1f;
+ this->cameraEyeVel.z = fabsf(this->cameraEye.z - -260.0f) * 0.1f;
+ this->cameraNextEye.x = 150.0f;
+ this->cameraNextEye.y = 60.0f;
+ this->cameraNextEye.z = -260.0f;
+ this->cameraNextAt.x = 155.0f;
+ this->cameraAtMaxVel.x = this->cameraAtMaxVel.y = this->cameraAtMaxVel.z = 0.1f;
+ this->cameraAtVel.x = fabsf(this->cameraAt.x - this->cameraNextAt.x) * 0.1f;
+ this->cameraAtVel.y = fabsf(this->cameraAt.y - this->cameraNextAt.y) * 0.1f;
+ this->cameraAtVel.z = fabsf(this->cameraAt.z - this->cameraNextAt.z) * 0.1f;
+ this->cameraEyeMaxVel.x = this->cameraEyeMaxVel.y = this->cameraEyeMaxVel.z = 0.1f;
+ this->cameraSpeedMod = 0.0f;
+ this->cameraAccel = 0.01f;
+ this->tentMaxAngle = 0.001f;
+ this->tentSpeed = 0.0f;
+ sp9F = 1;
+ }
+ } else {
+ sp9F = 1;
+ }
+ if (this->timers[2] == 50) {
+ this->cameraNextAt.x = 160.0f;
+ this->cameraNextAt.y = 58.0f;
+ this->cameraNextAt.z = -247.0f;
+ this->cameraEyeVel.x = fabsf(this->cameraEye.x - 111.0f) * 0.1f;
+ this->cameraEyeVel.y = fabsf(this->cameraEye.y - 133.0f) * 0.1f;
+ this->cameraEyeVel.z = fabsf(this->cameraEye.z - -191.0f) * 0.1f;
+ if (1) {}
+ this->csState = MO_INTRO_FINISH;
+ this->timers[2] = 110;
+ this->cameraNextEye.x = 111.0f;
+ this->cameraNextEye.y = 133.0f;
+ this->cameraNextEye.z = -191.0f;
+ this->cameraAtVel.x = fabsf(this->cameraAt.x - this->cameraNextAt.x) * 0.1f;
+ this->cameraAtVel.y = fabsf(this->cameraAt.y - this->cameraNextAt.y) * 0.1f;
+ this->cameraAtVel.z = fabsf(this->cameraAt.z - this->cameraNextAt.z) * 0.1f;
+ this->cameraEyeMaxVel.y = 0.03f;
+ this->cameraAtMaxVel.y = 0.03f;
+ this->cameraSpeedMod = 0.0f;
+ this->cameraAccel = 0.01f;
+ }
+ if (this->timers[2] == 150) {
+ Audio_QueueSeqCmd(0x1B);
+ }
+ if (this->timers[2] == 130) {
+ TitleCard_InitBossName(globalCtx, &globalCtx->actorCtx.titleCtx,
+ SEGMENTED_TO_VIRTUAL(gMorphaTitleCardTex), 0xA0, 0xB4, 0x80, 0x28);
+ gSaveContext.eventChkInf[7] |= 0x10;
+ }
+ break;
+ case MO_INTRO_FINISH:
+ sp9F = 1;
+ this->cameraNextEye.x = 111.0f;
+ this->cameraNextEye.y = 133.0f;
+ this->cameraNextEye.z = -191.0f;
+ this->cameraNextAt.x = 160.0f;
+ this->cameraNextAt.y = 58.0f;
+ this->cameraNextAt.z = -247.0f;
+ if (this->timers[2] == 100) {
+ sMorphaTent1->work[MO_TENT_ACTION_STATE] = MO_TENT_RETREAT;
+ sMorphaTent1->timers[0] = 50;
+ }
+ if (this->timers[2] == 20) {
+ camera2 = Gameplay_GetCamera(globalCtx, MAIN_CAM);
+ camera2->eye = this->cameraEye;
+ camera2->eyeNext = this->cameraEye;
+ camera2->at = this->cameraAt;
+ func_800C08AC(globalCtx, this->csCamera, 0);
+ this->csState = this->csCamera = MO_BATTLE;
+ func_80064534(globalCtx, &globalCtx->csCtx);
+ func_8002DF54(globalCtx, &this->actor, 7);
+ }
+ break;
+ }
+ if (sMorphaTent1->work[MO_TENT_ACTION_STATE] == MO_TENT_READY) {
+ sMorphaTent1->actor.world.pos.x = 180.0f;
+ sMorphaTent1->actor.world.pos.z = -360.0f;
+ sMorphaTent1->actor.prevPos = sMorphaTent1->actor.world.pos;
+ sMorphaTent1->actor.speedXZ = 0.0f;
+ sMorphaTent1->actor.shape.rot.y = sMorphaTent1->actor.yawTowardsPlayer;
+ }
+ if (this->csCamera != 0) {
+ if (sp9F) {
+ Math_ApproachF(&this->cameraEye.x, this->cameraNextEye.x, this->cameraEyeMaxVel.x,
+ this->cameraEyeVel.x * this->cameraSpeedMod);
+ Math_ApproachF(&this->cameraEye.y, this->cameraNextEye.y, this->cameraEyeMaxVel.y,
+ this->cameraEyeVel.y * this->cameraSpeedMod);
+ Math_ApproachF(&this->cameraEye.z, this->cameraNextEye.z, this->cameraEyeMaxVel.z,
+ this->cameraEyeVel.z * this->cameraSpeedMod);
+ Math_ApproachF(&this->cameraAt.x, this->cameraNextAt.x, this->cameraAtMaxVel.x,
+ this->cameraAtVel.x * this->cameraSpeedMod);
+ Math_ApproachF(&this->cameraAt.y, this->cameraNextAt.y, this->cameraAtMaxVel.y,
+ this->cameraAtVel.y * this->cameraSpeedMod);
+ Math_ApproachF(&this->cameraAt.z, this->cameraNextAt.z, this->cameraAtMaxVel.z,
+ this->cameraAtVel.z * this->cameraSpeedMod);
+ Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, this->cameraAccel);
+ } else if (this->csState < MO_INTRO_REVEAL) {
+ func_8002D908(&this->actor);
+ this->cameraEye.x += this->actor.velocity.x;
+ this->cameraEye.y += this->actor.velocity.y;
+ this->cameraEye.z += this->actor.velocity.z;
+ }
+ this->cameraUp.x = this->cameraUp.z =
+ sinf(this->work[MO_TENT_VAR_TIMER] * 0.03f) * this->cameraYawShake * (-2.0f);
+ this->cameraUp.y = 1.0f;
+ Gameplay_CameraSetAtEyeUp(globalCtx, this->csCamera, &this->cameraAt, &this->cameraEye, &this->cameraUp);
+ camera->eye = this->cameraEye;
+ camera->eyeNext = this->cameraEye;
+ camera->at = this->cameraAt;
+ Gameplay_CameraSetFov(globalCtx, this->csCamera, this->cameraZoom);
+ }
+
+ if ((this->csState > MO_INTRO_START) && (this->work[MO_TENT_MOVE_TIMER] > 540)) {
+ func_80078914(&sMorphaTent1->tentTipPos, NA_SE_EN_MOFER_APPEAR - SFX_FLAG);
+ } else if (this->csState >= MO_INTRO_START) {
+ func_80078914(&sAudioZeroVec, NA_SE_EN_MOFER_MOVE_DEMO - SFX_FLAG);
+ }
+}
+
+void BossMo_DeathCs(BossMo* this, GlobalContext* globalCtx) {
+ s16 i;
+ s16 one;
+ f32 dx;
+ f32 dz;
+ f32 sp80;
+ f32 sp7C;
+ Vec3f sp70;
+ Vec3f sp64;
+ Camera* camera = Gameplay_GetCamera(globalCtx, MAIN_CAM);
+ Vec3f velocity;
+ Vec3f pos;
+
+ switch (this->csState) {
+ case MO_DEATH_START:
+ func_80064520(globalCtx, &globalCtx->csCtx);
+ func_8002DF54(globalCtx, &this->actor, 8);
+ this->csCamera = Gameplay_CreateSubCamera(globalCtx);
+ Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT);
+ Gameplay_ChangeCameraStatus(globalCtx, this->csCamera, CAM_STAT_ACTIVE);
+ this->csState = MO_DEATH_MO_CORE_BURST;
+ this->cameraEye = camera->eye;
+ this->timers[0] = 90;
+ dx = this->actor.world.pos.x - this->cameraEye.x;
+ dz = this->actor.world.pos.z - this->cameraEye.z;
+ this->cameraYaw = Math_FAtan2F(dx, dz);
+ this->cameraDist = sqrtf(SQ(dx) + SQ(dz));
+ this->cameraYawRate = 0.0f;
+ case MO_DEATH_MO_CORE_BURST:
+ this->baseAlpha = 0.0f;
+ if (this->timers[0] & 4) {
+ sp80 = 0.005f;
+ sp7C = 0.015f;
+ } else {
+ sp80 = 0.015f;
+ sp7C = 0.005f;
+ }
+ Math_ApproachF(&this->actor.scale.x, sp80, 0.5f, 0.002f);
+ this->actor.scale.z = this->actor.scale.x;
+ Math_ApproachF(&this->actor.scale.y, sp7C, 0.5f, 0.002f);
+ this->cameraYaw += this->cameraYawRate;
+ if (this->timers[0] >= 30) {
+ Math_ApproachF(&this->cameraYawRate, 0.05f, 1.0f, 0.002f);
+ } else {
+ Math_ApproachF(&this->cameraYawRate, 0.0f, 1.0f, 0.002f);
+ }
+ Math_ApproachF(&this->actor.world.pos.y, 150.0f, 0.05f, 5.0f);
+ Math_ApproachF(&this->cameraEye.y, 100.0f, 0.05f, 2.0f);
+ this->cameraAt = this->cameraNextAt = this->actor.world.pos;
+ if (this->timers[0] > 20) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOFER_DEAD - SFX_FLAG);
+ }
+ if (this->timers[0] == 20) {
+ for (i = 0; i < 300; i++) {
+ velocity.x = Rand_CenteredFloat(10.0f);
+ velocity.y = Rand_CenteredFloat(10.0f);
+ velocity.z = Rand_CenteredFloat(10.0f);
+ pos = this->actor.world.pos;
+ pos.x += 2.0f * velocity.x;
+ pos.y += 2.0f * velocity.y;
+ pos.z += 2.0f * velocity.z;
+ BossMo_SpawnDroplet(MO_FX_DROPLET, (BossMoEffect*)globalCtx->specialEffects, &pos, &velocity,
+ Rand_ZeroFloat(0.08f) + 0.13f);
+ }
+ this->drawActor = false;
+ this->actor.flags &= ~1;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOFER_CORE_JUMP);
+ Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 70, NA_SE_EN_MOFER_LASTVOICE);
+ }
+ if (this->timers[0] == 0) {
+ this->csState = MO_DEATH_DRAIN_WATER_1;
+ this->cameraDist = 490.0f;
+ this->actor.world.pos.y = -1000.0f;
+ this->fwork[MO_TENT_SWING_SIZE_X] = 15.0f;
+ this->cameraYaw = 0.0f;
+ this->cameraEye.x = 490.0f;
+ this->cameraEye.y = 50.0f;
+ this->cameraEye.z = 0.0f;
+ this->cameraAt.x = 0;
+ this->cameraAt.y = -100.0f;
+ this->cameraAt.z = 0.0f;
+ this->work[MO_TENT_VAR_TIMER] = this->work[MO_TENT_MOVE_TIMER] = 0;
+ this->cameraAtMaxVel.y = 0.05f;
+ this->cameraAtVel.y = 4.0f;
+ this->cameraSpeedMod = 0.0f;
+ this->cameraAccel = 0.02f;
+ this->cameraNextAt.y = 320.0f;
+ if (1) {}
+ this->timers[0] = 100;
+ sMorphaTent1->drawActor = true;
+ sMorphaTent1->work[MO_TENT_ACTION_STATE] = MO_TENT_DEATH_3;
+ sMorphaTent1->actor.shape.rot.x = 0;
+ sMorphaTent1->actor.world.pos.x = 0.0f;
+ sMorphaTent1->actor.world.pos.y = -50.0f;
+ sMorphaTent1->actor.world.pos.z = 0.0f;
+ sMorphaTent1->fwork[MO_TENT_MAX_STRETCH] = 1.0f;
+ sMorphaTent1->tentPulse = 0.2f;
+ sMorphaCore->waterLevel = -50.0f;
+ sMorphaTent1->flattenRate = 0.0f;
+ sMorphaTent1->noBubbles = 0;
+ for (i = 0; i < 41; i++) {
+ sMorphaTent1->tentStretch[i].y = 5.0f;
+ }
+ sMorphaTent1->fwork[MO_TENT_SWING_RATE_X] = -400.0f;
+ sMorphaTent1->fwork[MO_TENT_SWING_LAG_X] = -3200.0f;
+ sMorphaTent1->fwork[MO_TENT_SWING_SIZE_X] = .0f;
+ sMorphaTent1->fwork[MO_TENT_SWING_RATE_Z] = 3000.0f;
+ sMorphaTent1->fwork[MO_TENT_SWING_LAG_Z] = 2500.0f;
+ sMorphaTent1->fwork[MO_TENT_SWING_SIZE_Z] = 4000.0f;
+ sMorphaTent1->tentMaxAngle = 1.0f;
+ sMorphaTent1->tentSpeed = 20480.0f;
+ sMorphaTent1->baseAlpha = 150.0f;
+ sMorphaTent1->cutIndex = sMorphaTent1->meltIndex = 0;
+ sMorphaTent1->cutScale = 1.0f;
+ Actor_SetScale(&sMorphaTent1->actor, 0.01f);
+ }
+ break;
+ case MO_DEATH_DRAIN_WATER_1:
+ if (this->timers[0] == 0) {
+ this->csState = MO_DEATH_DRAIN_WATER_2;
+ this->cameraAt.y = -200.0f;
+ this->cameraNextAt.y = 320.0f;
+ this->cameraAtMaxVel.y = 0.05f;
+ this->cameraAtVel.y = 4.0f;
+ this->cameraSpeedMod = 0.0f;
+ this->cameraAccel = 0.0f;
+ sMorphaTent1->work[MO_TENT_ACTION_STATE] = MO_TENT_DEATH_1;
+ this->timers[0] = 125;
+ sMorphaTent1->fwork[MO_TENT_MAX_STRETCH] = 3.7000003f;
+ this->cameraYaw = 0.5f;
+ this->cameraDist = 200.0f;
+ return;
+ }
+ break;
+ case MO_DEATH_DRAIN_WATER_2:
+ if (this->timers[0] == 0) {
+ this->cameraAccel = 0.02f;
+ sMorphaTent1->work[MO_TENT_ACTION_STATE] = MO_TENT_DEATH_2;
+ this->csState = MO_DEATH_CEILING;
+ sMorphaTent1->timers[0] = 120;
+ this->timers[0] = 150;
+ }
+ case MO_DEATH_CEILING:
+ Math_ApproachF(&this->cameraYaw, 0.0f, 0.05f, 0.0029999996f);
+ Math_ApproachF(&this->cameraDist, 490.0f, 0.1f, 1.0f);
+ if (this->timers[0] == 0) {
+ this->csState = MO_DEATH_DROPLET;
+ this->timers[0] = 140;
+ this->cameraYawRate = 0.0f;
+ this->cameraSpeed = 0.0f;
+ }
+ break;
+ case MO_DEATH_DROPLET:
+ if (this->timers[0] == 30) {
+ sMorphaTent1->work[MO_TENT_ACTION_STATE] = MO_TENT_DEATH_5;
+ sMorphaTent1->timers[0] = 30;
+ sMorphaTent1->tentMaxAngle = 0.0f;
+ sMorphaTent1->tentSpeed = sMorphaTent1->tentMaxAngle;
+ }
+ if (this->timers[0] == 0) {
+ if (-100.0f < this->cameraEye.y) {
+ Math_ApproachF(&this->cameraEye.y, sMorphaTent1->actor.world.pos.y - 100.0f, 0.1f, 2000.0f);
+ } else {
+ Math_ApproachF(&this->cameraEye.y, -200.0f, 0.1f, 2000.0f);
+ }
+
+ Math_ApproachF(&this->cameraAt.y, (sMorphaTent1->actor.world.pos.y - 50.0f) + 30.0f, 0.5f, 2000.0f);
+ this->cameraNextAt.y = this->cameraAt.y;
+ } else {
+ Math_ApproachF(&this->cameraEye.y, 300.0f, 0.05f, this->cameraSpeed);
+ }
+ Math_ApproachF(&this->cameraYaw, -M_PI / 2.0f, 0.05f, this->cameraYawRate);
+ Math_ApproachF(&this->cameraSpeed, 3.0f, 1.0f, 0.05f);
+ Math_ApproachF(&this->cameraYawRate, 0.012999999f, 1.0f, 0.0005f);
+ if (sMorphaTent1->work[MO_TENT_ACTION_STATE] == MO_TENT_DEATH_6) {
+ Math_ApproachF(&this->cameraDist, 200.0f, 0.02f, this->cameraSpeed);
+ if (sMorphaTent1->timers[0] == 0) {
+ this->csState = MO_DEATH_FINISH;
+ camera->eye = this->cameraEye;
+ camera->eyeNext = this->cameraEye;
+ camera->at = this->cameraAt;
+ func_800C08AC(globalCtx, this->csCamera, 0);
+ this->csCamera = 0;
+ func_80064534(globalCtx, &globalCtx->csCtx);
+ func_8002DF54(globalCtx, &this->actor, 7);
+ sMorphaTent1->actor.world.pos.y = -1000.0f;
+ }
+ } else {
+ Math_ApproachF(&this->cameraDist, 150.0f, 0.05f, this->cameraSpeed);
+ }
+ break;
+ case MO_DEATH_FINISH:
+ break;
+ }
+ if ((this->csState > MO_DEATH_START) && (this->csState < MO_DEATH_FINISH)) {
+ if (this->work[MO_TENT_MOVE_TIMER] < 500) {
+ func_80078914(&sAudioZeroVec, NA_SE_EN_MOFER_APPEAR - SFX_FLAG);
+ }
+ if ((this->work[MO_TENT_MOVE_TIMER] < 490) && (this->work[MO_TENT_MOVE_TIMER] > 230)) {
+ func_80078914(&sAudioZeroVec, NA_SE_EV_DROP_FALL - SFX_FLAG);
+ }
+ if (this->work[MO_TENT_MOVE_TIMER] < 220) {
+ func_80078914(&sAudioZeroVec, NA_SE_EV_SCOOPUP_WATER - SFX_FLAG);
+ }
+ }
+ if (sMorphaCore->waterLevel < -200.0f) {
+ globalCtx->unk_11D30[0]++;
+ if (globalCtx->unk_11D30[0] >= 0xFF) {
+ globalCtx->unk_11D30[0] = 0xFF;
+ }
+ }
+ if (sMorphaCore->waterLevel < -250.0f) {
+ Math_ApproachF(&sMorphaTent1->waterTexAlpha, 0.0f, 1.0f, 3.0f);
+ }
+ Math_ApproachF(&this->fwork[MO_TENT_SWING_SIZE_X], 0.0f, 0.1f, 0.05f);
+
+ sp70.x = this->cameraDist;
+ sp70.y = 0.0f;
+ sp70.z = 0.0f;
+ Matrix_RotateY(this->cameraYaw, MTXMODE_NEW);
+ Matrix_MultVec3f(&sp70, &sp64);
+ this->cameraEye.x = sp64.x + this->cameraAt.x;
+ this->cameraEye.z = sp64.z + this->cameraAt.z;
+ one = 1; // Super fake, but it works
+ if (this->csCamera != 0) {
+ if (one) {
+ Math_ApproachF(&this->cameraAt.y, this->cameraNextAt.y, this->cameraAtMaxVel.y,
+ this->cameraAtVel.y * this->cameraSpeedMod);
+ Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, this->cameraAccel);
+ }
+ Gameplay_CameraSetAtEye(globalCtx, this->csCamera, &this->cameraAt, &this->cameraEye);
+ }
+}
+
+void BossMo_CoreCollisionCheck(BossMo* this, GlobalContext* globalCtx) {
+ s16 i;
+ Player* player = PLAYER;
+
+ osSyncPrintf(VT_FGCOL(YELLOW));
+ osSyncPrintf("Core_Damage_check START\n");
+ if (this->coreCollider.base.atFlags & AT_HIT) {
+ this->coreCollider.base.atFlags &= ~AT_HIT;
+ if (this->work[MO_TENT_ACTION_STATE] == MO_CORE_UNDERWATER) {
+ this->work[MO_CORE_WAIT_IN_WATER] = true;
+ this->timers[0] = 150;
+ }
+ }
+ if (this->coreCollider.base.acFlags & AC_HIT) {
+ ColliderInfo* hurtbox = this->coreCollider.info.acHitInfo;
+ // hit!!
+ osSyncPrintf("Core_Damage_check 当り!!\n");
+ this->coreCollider.base.acFlags &= ~AC_HIT;
+ if ((hurtbox->toucher.dmgFlags & 0x00020000) && (this->work[MO_TENT_ACTION_STATE] == MO_CORE_ATTACK)) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_RETREAT;
+ }
+ // hit 2 !!
+ osSyncPrintf("Core_Damage_check 当り 2 !!\n");
+ if ((this->work[MO_TENT_ACTION_STATE] != MO_CORE_UNDERWATER) && (this->work[MO_TENT_INVINC_TIMER] == 0)) {
+ u8 damage = CollisionCheck_GetSwordDamage(hurtbox->toucher.dmgFlags);
+
+ if ((damage != 0) && (this->work[MO_TENT_ACTION_STATE] < MO_CORE_ATTACK)) {
+ // sword hit !!
+ osSyncPrintf("Core_Damage_check 剣 当り!!\n");
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_STUNNED;
+ this->timers[0] = 25;
+
+ this->actor.speedXZ = 15.0f;
+
+ this->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x8000;
+ this->work[MO_CORE_DMG_FLASH_TIMER] = 15;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOFER_CORE_DAMAGE);
+ this->actor.colChkInfo.health -= damage;
+ this->hitCount++;
+ if ((s8)this->actor.colChkInfo.health <= 0) {
+ if (((sMorphaTent1->csCamera == 0) && (sMorphaTent2 == NULL)) ||
+ ((sMorphaTent1->csCamera == 0) && (sMorphaTent2 != NULL) && (sMorphaTent2->csCamera == 0))) {
+ Enemy_StartFinishingBlow(globalCtx, &this->actor);
+ Audio_QueueSeqCmd(0x100100FF);
+ this->csState = MO_DEATH_START;
+ sMorphaTent1->drawActor = false;
+ sMorphaTent1->work[MO_TENT_ACTION_STATE] = MO_TENT_DEATH_START;
+ sMorphaTent1->baseAlpha = 0.0f;
+ if (sMorphaTent2 != NULL) {
+ sMorphaTent2->tent2KillTimer = 1;
+ }
+ if (player->actor.parent != NULL) {
+ player->unk_850 = 0x65;
+ player->actor.parent = NULL;
+ player->csMode = 0;
+ }
+ } else {
+ this->actor.colChkInfo.health = 1;
+ }
+ }
+ this->work[MO_TENT_INVINC_TIMER] = 10;
+ } else if (!(hurtbox->toucher.dmgFlags & 0x00100000) && (hurtbox->toucher.dmgFlags & 0x80)) {
+ if (this->work[MO_TENT_ACTION_STATE] >= MO_CORE_ATTACK) {
+ func_80078914(&sMorphaTent1->tentTipPos, NA_SE_EN_MOFER_CUT);
+ sMorphaTent1->cutIndex = this->work[MO_CORE_POS_IN_TENT];
+ sMorphaTent1->meltIndex = sMorphaTent1->cutIndex + 1;
+ sMorphaTent1->cutScale = 1.0f;
+ sMorphaTent1->work[MO_TENT_ACTION_STATE] = MO_TENT_CUT;
+ sMorphaTent1->timers[0] = 40;
+ sMorphaTent1->actor.flags &= ~1;
+ if (player->actor.parent == &sMorphaTent1->actor) {
+ player->unk_850 = 0x65;
+ player->actor.parent = NULL;
+ player->csMode = 0;
+ }
+ }
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_STUNNED;
+ this->timers[0] = 30;
+ this->work[MO_TENT_INVINC_TIMER] = 10;
+ this->actor.speedXZ = 0.0f;
+ }
+ for (i = 0; i < 10; i++) {
+ Vec3f pos;
+ Vec3f velocity;
+
+ velocity.x = Rand_CenteredFloat(4.0f);
+ velocity.y = Rand_ZeroFloat(2.0f) + 3.0f;
+ velocity.z = Rand_CenteredFloat(4.0f);
+ pos = this->actor.world.pos;
+ pos.x += (velocity.x * 3.0f);
+ pos.z += (velocity.z * 3.0f);
+ BossMo_SpawnDroplet(MO_FX_DROPLET, (BossMoEffect*)globalCtx->specialEffects, &pos, &velocity,
+ Rand_ZeroFloat(0.08f) + 0.13f);
+ }
+ }
+ }
+ // end !!
+ osSyncPrintf("Core_Damage_check 終わり !!\n");
+ osSyncPrintf(VT_RST);
+}
+
+void BossMo_Core(BossMo* this, GlobalContext* globalCtx) {
+ static f32 coreBulge[11] = {
+ 0.1f, 0.15f, 0.2f, 0.3f, 0.4f, 0.43f, 0.4f, 0.3f, 0.2f, 0.15f, 0.1f,
+ };
+ u8 nearLand;
+ s16 i; // not on stack
+ Player* player = PLAYER; // not on stack
+ f32 spDC;
+ f32 spD8;
+ f32 spD4;
+ f32 spD0;
+ f32 spCC;
+ s32 padC8;
+ s32 temp; // not on stack
+ f32 xScaleTarget; // not on stack
+ f32 yScaleTarget;
+ Vec3f effectPos;
+ Vec3f effectVelocity;
+ Vec3f effectAccel;
+ s32 pad94;
+ s32 pad90;
+ s16 j;
+ s16 index; // not on stack
+ f32 sp88;
+ s32 pad84;
+ f32 sp80;
+ f32 sp7C;
+ Vec3f sp70;
+ Vec3f sp64;
+ f32 sp60;
+ f32 sp5C;
+ f32 sp58;
+
+ this->waterTex1x += -1.0f;
+ this->waterTex1y += -1.0f;
+ this->waterTex2x = this->waterTex2x;
+ this->waterTex2y++;
+
+ Math_ApproachF(&this->baseAlpha, 255.0f, 1.0f, 10.0f);
+ if ((this->csState != MO_BATTLE) && (this->csState < MO_DEATH_START)) {
+ BossMo_IntroCs(this, globalCtx);
+ if (this->work[MO_TENT_ACTION_STATE] == MO_CORE_INTRO_WAIT) {
+ this->actor.flags &= ~1;
+ return;
+ }
+ } else if (this->csState >= MO_DEATH_START) {
+ BossMo_DeathCs(this, globalCtx);
+ return;
+ }
+ if ((this->work[MO_TENT_ACTION_STATE] < MO_CORE_ATTACK) && (this->work[MO_TENT_ACTION_STATE] >= MO_CORE_MOVE) &&
+ (this->actor.world.pos.y > MO_WATER_LEVEL(globalCtx))) {
+ if (this->actor.velocity.y > 0.0f) {
+ xScaleTarget = 0.005f;
+ yScaleTarget = 0.015f;
+ } else {
+ xScaleTarget = 0.015f;
+ yScaleTarget = 0.005f;
+ }
+ } else {
+ xScaleTarget = yScaleTarget = 0.008f;
+ }
+ Math_ApproachF(&this->actor.scale.x, xScaleTarget, 0.2f, 0.001f);
+ this->actor.scale.z = this->actor.scale.x;
+ Math_ApproachF(&this->actor.scale.y, yScaleTarget, 0.2f, 0.001f);
+ this->work[MO_CORE_DRAW_SHADOW] = BossMo_NearLand(&this->actor.world.pos, 15.0f);
+ nearLand = BossMo_NearLand(&this->actor.world.pos, 0.0f);
+ if ((player->actor.world.pos.y < (MO_WATER_LEVEL(globalCtx) - 50.0f)) &&
+ ((this->work[MO_TENT_ACTION_STATE] == MO_CORE_MOVE) ||
+ (this->work[MO_TENT_ACTION_STATE] == MO_CORE_MAKE_TENT))) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_UNDERWATER;
+ this->actor.speedXZ = 0.0f;
+ this->work[MO_CORE_WAIT_IN_WATER] = 0;
+ }
+ switch (this->work[MO_TENT_ACTION_STATE]) {
+ case MO_CORE_MOVE:
+ this->actor.flags |= 1;
+ if ((this->timers[0] == 0) &&
+ ((sMorphaTent1->work[MO_TENT_ACTION_STATE] == MO_TENT_WAIT) ||
+ (sMorphaTent1->work[MO_TENT_ACTION_STATE] == MO_TENT_READY)) &&
+ (this->actor.world.pos.y < MO_WATER_LEVEL(globalCtx))) {
+ this->actor.speedXZ = 0.0f;
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_MAKE_TENT;
+ if (sMorphaTent1->work[MO_TENT_ACTION_STATE] == MO_TENT_WAIT) {
+ sMorphaTent1->work[MO_TENT_ACTION_STATE] = MO_TENT_SPAWN;
+ sMorphaTent1->timers[0] = 70;
+ sMorphaTent1->actor.shape.rot.y = sMorphaTent1->actor.yawTowardsPlayer;
+ }
+ }
+ break;
+ case MO_CORE_MAKE_TENT:
+ if ((sMorphaTent1->work[MO_TENT_ACTION_STATE] == MO_TENT_DESPAWN) ||
+ (sMorphaTent1->work[MO_TENT_ACTION_STATE] == MO_TENT_WAIT)) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_MOVE;
+ this->timers[0] = 70;
+ }
+ if (sMorphaTent1->work[MO_TENT_ACTION_STATE] == MO_TENT_CUT) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_ATTACK;
+ this->work[MO_CORE_POS_IN_TENT] = 0;
+ this->timers[0] = 0;
+ }
+ if (sMorphaTent1->work[MO_TENT_ACTION_STATE] == MO_TENT_ATTACK) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_ATTACK;
+ this->work[MO_CORE_POS_IN_TENT] = 0;
+ this->timers[0] = 0;
+ this->actor.speedXZ = 0.0f;
+ }
+ break;
+ case MO_CORE_UNDERWATER:
+ if (player->actor.world.pos.y >= MO_WATER_LEVEL(globalCtx)) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_MOVE;
+ this->actor.speedXZ = 0.0f;
+ }
+ break;
+ case MO_CORE_STUNNED:
+ this->actor.flags |= 1;
+ if (this->timers[0] == 0) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_MOVE;
+ this->timers[0] = 30;
+ }
+ if (this->actor.world.pos.y < MO_WATER_LEVEL(globalCtx)) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_MAKE_TENT;
+ this->timers[0] = 50;
+ this->actor.speedXZ = 0.0f;
+ }
+ break;
+ case MO_CORE_UNUSED:
+ break;
+ }
+ if (this->timers[0] == 0) {
+ switch (this->work[MO_TENT_ACTION_STATE]) {
+ case MO_CORE_ATTACK:
+ this->actor.flags |= 1;
+ this->work[MO_CORE_POS_IN_TENT]++;
+ if (sMorphaTent1->work[MO_TENT_ACTION_STATE] == MO_TENT_ATTACK) {
+ temp = (s16)(Math_SinS(this->work[MO_TENT_MOVE_TIMER] * 0x300) * 10.0f) + 15;
+ if (this->work[MO_CORE_POS_IN_TENT] >= temp) {
+ this->work[MO_CORE_POS_IN_TENT] = temp;
+ }
+ }
+ if ((sMorphaTent1->work[MO_TENT_ACTION_STATE] != MO_TENT_ATTACK) &&
+ (sMorphaTent1->work[MO_TENT_ACTION_STATE] != MO_TENT_CUT)) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_RETREAT;
+ this->timers[0] = 0;
+ }
+ break;
+ case MO_CORE_RETREAT:
+ this->work[MO_CORE_POS_IN_TENT]--;
+ if (this->work[MO_CORE_POS_IN_TENT] <= 0) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_MAKE_TENT;
+ this->timers[0] = 100;
+ this->tentSpeed = 0.0f;
+ this->actor.speedXZ = 0.0f;
+ }
+ this->timers[0] = 0;
+ break;
+ case MO_CORE_INTRO_REVEAL:
+ this->actor.flags &= ~1;
+ this->work[MO_CORE_POS_IN_TENT]++;
+ temp = (s16)(Math_SinS(this->work[MO_TENT_MOVE_TIMER] * 0x500) * 10.0f) + 15;
+ if (this->work[MO_CORE_POS_IN_TENT] >= temp) {
+ this->work[MO_CORE_POS_IN_TENT] = temp;
+ }
+ if (sMorphaTent1->work[MO_TENT_ACTION_STATE] != MO_TENT_READY) {
+ this->work[MO_TENT_ACTION_STATE] = MO_CORE_RETREAT;
+ this->timers[0] = 0;
+ }
+ break;
+ }
+ }
+ if (this->work[MO_TENT_ACTION_STATE] >= MO_CORE_ATTACK) {
+ if (this->work[MO_CORE_POS_IN_TENT] < 0) {
+ this->work[MO_CORE_POS_IN_TENT] = 0;
+ } else if (this->work[MO_CORE_POS_IN_TENT] >= 41) {
+ this->work[MO_CORE_POS_IN_TENT] = 40;
+ }
+ index = (300 - (this->work[MO_CORE_POS_IN_TENT] * 2) + sMorphaTent1->widthIndex) % 300;
+ sp88 = sMorphaTent1->tentWidth[index] * sTentWidth[this->work[MO_CORE_POS_IN_TENT]];
+ for (j = -5; j < 6; j++) {
+ index = (this->work[MO_CORE_POS_IN_TENT] + j) - 2;
+ if ((0 <= index) && (index < 41)) {
+ Math_ApproachF(&sMorphaTent1->tentScale[index].x, ((coreBulge[j + 5] * 300.0f) / 100.0f) + sp88, 0.75f,
+ 5.0f);
+ }
+ }
+ this->targetPos.x = sMorphaTent1->tentPos[this->work[MO_CORE_POS_IN_TENT]].x;
+ this->targetPos.y = sMorphaTent1->tentPos[this->work[MO_CORE_POS_IN_TENT]].y;
+ this->targetPos.z = sMorphaTent1->tentPos[this->work[MO_CORE_POS_IN_TENT]].z;
+ if (this->work[MO_CORE_POS_IN_TENT] <= 1) {
+ this->targetPos.y -= 20.0f;
+ }
+ Math_ApproachF(&this->actor.world.pos.x, this->targetPos.x, 0.5f, this->actor.speedXZ);
+ Math_ApproachF(&this->actor.world.pos.y, this->targetPos.y, 0.5f, this->actor.speedXZ);
+ Math_ApproachF(&this->actor.world.pos.z, this->targetPos.z, 0.5f, this->actor.speedXZ);
+ Math_ApproachF(&this->actor.speedXZ, 30.0f, 1.0f, 1.0f);
+ } else {
+ switch (this->work[MO_TENT_ACTION_STATE]) {
+ case MO_CORE_MOVE:
+ sp80 = Math_SinS(this->work[MO_TENT_VAR_TIMER] * 0x800) * 100.0f;
+ sp7C = Math_CosS(this->work[MO_TENT_VAR_TIMER] * 0x800) * 100.0f;
+ Math_ApproachF(&this->actor.world.pos.x, sMorphaTent1->targetPos.x + sp80, 0.05f, this->actor.speedXZ);
+ Math_ApproachF(&this->actor.world.pos.z, sMorphaTent1->targetPos.z + sp7C, 0.05f, this->actor.speedXZ);
+ Math_ApproachF(&this->actor.speedXZ, 10.0f, 1.0f, 0.5f);
+ break;
+ case MO_CORE_STUNNED:
+ this->actor.velocity.x = Math_SinS(this->actor.world.rot.y) * this->actor.speedXZ;
+ this->actor.velocity.z = Math_CosS(this->actor.world.rot.y) * this->actor.speedXZ;
+ this->actor.world.pos.x += this->actor.velocity.x;
+ this->actor.world.pos.z += this->actor.velocity.z;
+ break;
+ }
+ if ((this->work[MO_TENT_ACTION_STATE] == MO_CORE_MOVE) ||
+ (this->work[MO_TENT_ACTION_STATE] == MO_CORE_STUNNED)) {
+ this->actor.world.pos.y += this->actor.velocity.y;
+ this->actor.velocity.y -= 1.0f;
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 20.0f, 100.0f, 1);
+ effectVelocity.x = effectVelocity.y = effectVelocity.z = 0.0f;
+ for (i = 0; i < 1; i++) {
+ effectPos.x = Rand_CenteredFloat(20.0f) + this->actor.world.pos.x;
+ effectPos.y = Rand_CenteredFloat(20.0f) + this->actor.world.pos.y;
+ effectPos.z = Rand_CenteredFloat(20.0f) + this->actor.world.pos.z;
+ BossMo_SpawnDroplet(MO_FX_DROPLET, (BossMoEffect*)globalCtx->specialEffects, &effectPos,
+ &effectVelocity, Rand_ZeroFloat(0.02f) + 0.05f);
+ };
+
+ if (nearLand) {
+ if (this->actor.world.pos.y <= 10) {
+ this->actor.world.pos.y = 10;
+ this->actor.velocity.y = -0.01f;
+ if (this->timers[1] != 0) {
+ if (this->timers[1] == 1) {
+ this->actor.velocity.y = 6.0f;
+ }
+ } else {
+ this->timers[1] = 2;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOFER_CORE_LAND);
+ for (i = 0; i < 10; i++) {
+ effectVelocity.x = Rand_CenteredFloat(4.0f);
+ effectVelocity.y = Rand_ZeroFloat(2.0f) + 3.0f;
+ effectVelocity.z = Rand_CenteredFloat(4.0f);
+ effectPos = this->actor.world.pos;
+ effectPos.x += effectVelocity.x;
+ effectPos.z += effectVelocity.z;
+ BossMo_SpawnDroplet(MO_FX_DROPLET, (BossMoEffect*)globalCtx->specialEffects, &effectPos,
+ &effectVelocity, Rand_ZeroFloat(0.08f) + 0.13f);
+ }
+ effectVelocity.x = effectVelocity.y = effectVelocity.z = 0.0f;
+ effectPos = this->actor.world.pos;
+ effectPos.y = 0.0f;
+ BossMo_SpawnDroplet(MO_FX_DROPLET, (BossMoEffect*)globalCtx->specialEffects, &effectPos,
+ &effectVelocity, 0.4f);
+ }
+ }
+ } else if (this->actor.world.pos.y < MO_WATER_LEVEL(globalCtx)) {
+ this->actor.velocity.y = BossMo_NearLand(&this->actor.world.pos, 40.0f) ? 15.0f : 6.0f;
+ if ((this->actor.world.pos.y + 15.0f) >= MO_WATER_LEVEL(globalCtx)) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOFER_CORE_JUMP);
+ }
+ }
+ } else if (this->work[MO_TENT_ACTION_STATE] >= MO_CORE_MOVE) {
+ if (this->actor.world.pos.y < MO_WATER_LEVEL(globalCtx)) {
+ if (this->work[MO_TENT_ACTION_STATE] == MO_CORE_MAKE_TENT) {
+ this->targetPos.x = sMorphaTent1->targetPos.x;
+ this->targetPos.y = sMorphaTent1->actor.world.pos.y - 40.0f;
+ this->targetPos.z = sMorphaTent1->targetPos.z;
+ Math_ApproachF(&this->actor.speedXZ, 10.0f, 1.0f, 0.5f);
+ } else if (this->work[MO_TENT_ACTION_STATE] == MO_CORE_UNDERWATER) {
+ switch (this->work[MO_CORE_WAIT_IN_WATER]) {
+ case false:
+ this->targetPos = player->actor.world.pos;
+ this->targetPos.y += 30.0f;
+ sp70.x = 0.0f;
+ sp70.y = 0.0f;
+ sp70.z = 100.0f;
+ Matrix_RotateY((player->actor.world.rot.y / (f32)0x8000) * M_PI, MTXMODE_NEW);
+ Matrix_MultVec3f(&sp70, &sp64);
+ this->targetPos.x = player->actor.world.pos.x + sp64.x;
+ this->targetPos.y = player->actor.world.pos.y + 30.0f;
+ this->targetPos.z = player->actor.world.pos.z + sp64.z;
+ Math_ApproachF(&this->actor.speedXZ, 10.0f, 1.0f, 1.0f);
+ if (this->timers[0] == 0) {
+ this->work[MO_CORE_WAIT_IN_WATER] = true;
+ this->timers[0] = (s16)Rand_ZeroFloat(50.0f) + 50;
+ }
+ break;
+ case true:
+ Math_ApproachF(&this->actor.speedXZ, 1.0f, 1.0f, 0.5f);
+ if (this->timers[0] == 0) {
+ this->work[MO_CORE_WAIT_IN_WATER] = false;
+ this->timers[0] = (s16)Rand_ZeroFloat(20.0f) + 20;
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOFER_CORE_MOVE_WT);
+ }
+ break;
+ }
+ }
+ this->targetPos.x += Math_SinS(this->work[MO_TENT_MOVE_TIMER] * 3096.0f) * 30.0f;
+ this->targetPos.y += Math_SinS(this->work[MO_TENT_MOVE_TIMER] * 2096.0f) * 30.0f;
+ this->targetPos.z += Math_SinS(this->work[MO_TENT_MOVE_TIMER] * 2796.0f) * 30.0f;
+ this->tentMaxAngle = 5.0f;
+ this->tentSpeed = 4000.0f;
+ spDC = this->targetPos.x - this->actor.world.pos.x;
+ spD8 = this->targetPos.y - this->actor.world.pos.y;
+ spD4 = this->targetPos.z - this->actor.world.pos.z;
+ spCC = (s16)(Math_FAtan2F(spDC, spD4) * (0x8000 / M_PI));
+ spD0 = (s16)(Math_FAtan2F(spD8, sqrtf(SQ(spDC) + SQ(spD4))) * (0x8000 / M_PI));
+ Math_ApproachS(&this->actor.world.rot.y, spCC, this->tentMaxAngle, this->tentSpeed);
+ Math_ApproachS(&this->actor.world.rot.x, spD0, this->tentMaxAngle, this->tentSpeed);
+ func_8002D908(&this->actor);
+ } else {
+ this->actor.world.pos.y += this->actor.velocity.y;
+ this->actor.velocity.y -= 1.0f;
+ }
+ func_8002D7EC(&this->actor);
+ temp = (this->actor.world.pos.y < -200.0f) ? 5 : 1;
+ this->actor.world.pos.y -= 20.0f;
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 20.0f, 100.0f, temp);
+ this->actor.world.pos.y += 20.0f;
+ }
+ }
+ if ((this->actor.world.pos.y < MO_WATER_LEVEL(globalCtx)) && (MO_WATER_LEVEL(globalCtx) <= this->actor.prevPos.y)) {
+ if (this->actor.velocity.y < -5.0f) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOFER_CORE_JUMP);
+ } else {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOFER_CORE_SMJUMP);
+ }
+ if ((this->timers[3] != 0) || ((sMorphaTent1->fwork[MO_TENT_MAX_STRETCH] > 0.2f) &&
+ (fabsf(this->actor.world.pos.x - sMorphaTent1->actor.world.pos.x) < 30.0f) &&
+ (fabsf(this->actor.world.pos.z - sMorphaTent1->actor.world.pos.z) < 30.0f))) {
+ // This space intentionally left blank.
+ } else {
+ this->timers[3] = 8;
+ for (i = 0; i < 10; i++) {
+ sp5C = Rand_ZeroFloat(3.14f);
+ sp60 = Rand_ZeroFloat(0.6f) + 1.6f;
+ effectVelocity.x = Math_SinS(((i * (f32)0x10000) / 10.0f) + sp5C) * sp60;
+ effectVelocity.z = Math_CosS(((i * (f32)0x10000) / 10.0f) + sp5C) * sp60;
+ effectVelocity.y = Rand_ZeroFloat(0.3f) + 3.0f;
+
+ effectPos = this->actor.world.pos;
+ effectPos.x += effectVelocity.x * 3.0f;
+ effectPos.y = MO_WATER_LEVEL(globalCtx);
+ effectPos.z += effectVelocity.z * 3.0f;
+ BossMo_SpawnDroplet(MO_FX_SPLASH, (BossMoEffect*)globalCtx->specialEffects, &effectPos, &effectVelocity,
+ Rand_ZeroFloat(0.075f) + 0.15f);
+ }
+ effectPos = this->actor.world.pos;
+ effectPos.y = MO_WATER_LEVEL(globalCtx);
+ BossMo_SpawnRipple(globalCtx->specialEffects, &effectPos, 100.0f, 800.0f, 100, 290, MO_FX_SMALL_RIPPLE);
+ BossMo_SpawnRipple(globalCtx->specialEffects, &effectPos, 50.0f, 600.0f, 70, 290, MO_FX_SMALL_RIPPLE);
+ BossMo_SpawnRipple(globalCtx->specialEffects, &effectPos, 0, 400.0f, 50, 290, MO_FX_SMALL_RIPPLE);
+ }
+ }
+ if ((this->actor.world.pos.y < MO_WATER_LEVEL(globalCtx)) || (this->work[MO_TENT_ACTION_STATE] >= MO_CORE_ATTACK)) {
+ for (i = 0; i < 3; i++) {
+ effectAccel.x = effectAccel.z = 0.0f;
+ effectVelocity.x = effectVelocity.y = effectVelocity.z = 0.0f;
+ if (this->work[MO_TENT_ACTION_STATE] >= MO_CORE_ATTACK) {
+ effectAccel.y = 0.0f;
+ sp58 = 10.0f;
+ } else {
+ effectAccel.y = 0.1f;
+ sp58 = 20.0f;
+ }
+ effectPos.x = Rand_CenteredFloat(sp58) + this->actor.world.pos.x;
+ effectPos.y = Rand_CenteredFloat(sp58) + this->actor.world.pos.y;
+ effectPos.z = Rand_CenteredFloat(sp58) + this->actor.world.pos.z;
+ BossMo_SpawnBubble(globalCtx->specialEffects, &effectPos, &effectVelocity, &effectAccel,
+ Rand_ZeroFloat(0.05f) + 0.1f, NULL);
+ }
+ }
+ BossMo_CoreCollisionCheck(this, globalCtx);
+}
+
+void BossMo_UpdateCore(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ BossMo* this = THIS;
+ s16 i;
+ Player* player = PLAYER;
+
+ osSyncPrintf("CORE mode = <%d>\n", this->work[MO_TENT_ACTION_STATE]);
+ if (sMorphaTent2 == NULL) {
+ MO_WATER_LEVEL(globalCtx) = sMorphaTent1->waterLevelMod + (s16)this->waterLevel;
+ } else {
+ MO_WATER_LEVEL(globalCtx) = sMorphaTent2->waterLevelMod + ((s16)this->waterLevel + sMorphaTent1->waterLevelMod);
+ }
+ this->actor.flags |= 0x200;
+ this->actor.focus.pos = this->actor.world.pos;
+ this->work[MO_TENT_VAR_TIMER]++;
+
+ if (this->work[MO_CORE_DMG_FLASH_TIMER] != 0) {
+ this->work[MO_CORE_DMG_FLASH_TIMER]--;
+ }
+ if (this->work[MO_TENT_INVINC_TIMER] != 0) {
+ this->work[MO_TENT_INVINC_TIMER]--;
+ }
+ this->work[MO_TENT_MOVE_TIMER]++;
+
+ for (i = 0; i < ARRAY_COUNT(this->timers); i++) {
+ if (this->timers[i] != 0) {
+ this->timers[i]--;
+ }
+ }
+
+ BossMo_Core(this, globalCtx);
+ Collider_UpdateCylinder(&this->actor, &this->coreCollider);
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->coreCollider.base);
+ if ((this->work[MO_TENT_ACTION_STATE] != MO_CORE_STUNNED) ||
+ (this->actor.world.pos.y < MO_WATER_LEVEL(globalCtx))) {
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->coreCollider.base);
+ } else {
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->coreCollider.base);
+ }
+ BossMo_UpdateEffects(this, globalCtx);
+ if (player->actor.parent != NULL) {
+ this->actor.flags &= ~1;
+ }
+ BossMo_Unknown();
+}
+
+void BossMo_UpdateTent(Actor* thisx, GlobalContext* globalCtx) {
+ s16 i;
+ s16 index;
+ s32 pad;
+ BossMo* this = THIS;
+ Player* player = PLAYER;
+ f32 phi_f0;
+
+ if ((this == sMorphaTent2) && (this->tent2KillTimer != 0)) {
+ this->tent2KillTimer++;
+ this->actor.draw = NULL;
+ if (this->tent2KillTimer > 20) {
+ Actor_Kill(&this->actor);
+ func_800F89E8(&this->tentTipPos);
+ sMorphaTent2 = NULL;
+ }
+ return;
+ }
+
+ SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->mf_11D60, &this->tentPos[40], &this->tentTipPos, &this->actor.projectedW);
+ osSyncPrintf("MO : Move mode = <%d>\n", this->work[MO_TENT_ACTION_STATE]);
+ Math_ApproachS(&player->actor.shape.rot.x, 0, 5, 0x3E8);
+ Math_ApproachS(&player->actor.shape.rot.z, 0, 5, 0x3E8);
+ this->work[MO_TENT_VAR_TIMER]++;
+ this->sfxTimer++;
+ this->work[MO_TENT_MOVE_TIMER]++;
+ this->widthIndex++;
+ if (this->widthIndex >= 300) {
+ this->widthIndex = 0;
+ }
+ this->pulsePhase -= 3000;
+ index = this->widthIndex;
+ this->tentWidth[index] = (Math_SinS(this->pulsePhase) * this->tentPulse) + (1.0f + this->tentPulse);
+ for (i = 0; i < 41; i++) {
+ if (this->work[MO_TENT_ACTION_STATE] >= MO_TENT_DEATH_START) {
+ if (this->work[MO_TENT_ACTION_STATE] >= MO_TENT_DEATH_1) {
+ if (this->work[MO_TENT_ACTION_STATE] == MO_TENT_DEATH_5) {
+ phi_f0 = (this->timers[0] != 0) ? sFlatWidth[i] : sDropletWidth[i];
+ Math_ApproachF(&this->tentScale[i].x, phi_f0, 0.5f, 100.0f);
+ } else {
+ index = ((this->widthIndex + (i * 2)) + 220) % 300;
+ phi_f0 = this->tentWidth[index] + SQ(sTentWidth[i]);
+ Math_ApproachF(&this->tentScale[i].x, phi_f0, 0.5f, 0.3f);
+ }
+ } else {
+ index = ((this->widthIndex - (i * 2)) + 300) % 300;
+ phi_f0 = this->tentWidth[index] * sTentWidth[i];
+ this->tentScale[i].x = phi_f0;
+ }
+ } else {
+ index = ((this->widthIndex - (i * 2)) + 300) % 300;
+ phi_f0 = this->tentWidth[index] * sTentWidth[i];
+ Math_ApproachF(&this->tentScale[i].x, phi_f0, 0.5f, 0.3f);
+ }
+ phi_f0 = Math_SinS((this->work[MO_TENT_VAR_TIMER] * 12000.0f) + (i * 20000.0f));
+ this->tentRipple[i].x = (1.0f * phi_f0) * this->tentRippleSize;
+ this->tentScale[i].y = this->tentScale[i].z = this->tentScale[i].x;
+ this->tentRipple[i].y = this->tentRipple[i].z = this->tentRipple[i].x;
+ }
+
+ Math_ApproachF(&this->tentRippleSize, 0.0f, 0.1f, 0.005f);
+ Math_ApproachF(&this->tentPulse, 0.2f, 0.5f, 0.01f);
+ this->actionFunc(this, globalCtx);
+ for (i = 0; i < ARRAY_COUNT(this->timers); i++) {
+ if (this->timers[i] != 0) {
+ this->timers[i]--;
+ }
+ }
+ Math_ApproachS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0xA, 0xC8);
+ Actor_MoveForward(&this->actor);
+ Math_ApproachF(&this->actor.speedXZ, 0.0, 1.0f, 0.02f);
+
+ if (BossMo_NearLand(&this->actor.world.pos, 40)) {
+ this->actor.world.pos = this->actor.prevPos;
+ }
+ if ((this->work[MO_TENT_VAR_TIMER] % 8) == 0) {
+ f32 rippleScale;
+ Vec3f pos = this->actor.world.pos;
+
+ if (this->work[MO_TENT_ACTION_STATE] < MO_TENT_DEATH_START) {
+ rippleScale = 400.0f;
+ } else {
+ rippleScale = 0.0;
+ if (this->work[MO_TENT_ACTION_STATE] >= MO_TENT_DEATH_1) {
+ pos = this->tentPos[38];
+ }
+ }
+ BossMo_SpawnRipple(globalCtx->specialEffects, &pos, rippleScale, rippleScale * 3.0f, this->baseAlpha * 0.6666f,
+ 300, MO_FX_BIG_RIPPLE);
+ }
+ if (this->baseBubblesTimer != 0) {
+ Vec3f sp88;
+ Vec3f sp7C;
+ Vec3f bubblePos;
+ Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
+ s32 pad;
+
+ this->baseBubblesTimer--;
+ sp88.x = 0.0;
+ sp88.y = 0.0;
+ sp88.z = 100.0f;
+ Matrix_RotateY(Rand_ZeroFloat(2.0f * M_PI), MTXMODE_NEW);
+ Matrix_MultVec3f(&sp88, &sp7C);
+ if ((this->work[MO_TENT_ACTION_STATE] >= MO_TENT_DEATH_1) &&
+ (this->work[MO_TENT_ACTION_STATE] != MO_TENT_DEATH_3)) {
+ i = 38;
+ } else {
+ i = 0;
+ if (this->work[MO_TENT_ACTION_STATE] < MO_TENT_CUT) {
+ func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_CORE_ROLL - SFX_FLAG);
+ }
+ }
+ bubblePos.x = this->tentPos[i].x + sp7C.x;
+ bubblePos.y = (MO_WATER_LEVEL(globalCtx) - 40.0f) + Rand_ZeroFloat(20.0f);
+ bubblePos.z = this->tentPos[i].z + sp7C.z;
+ BossMo_SpawnBubble(globalCtx->specialEffects, &bubblePos, &zeroVec, &zeroVec, Rand_ZeroFloat(0.05f) + 0.2f,
+ &this->tentPos[i]);
+ }
+
+ if (this->work[MO_CORE_DMG_FLASH_TIMER] != 0) {
+ this->work[MO_CORE_DMG_FLASH_TIMER]--;
+ }
+ if (this->work[MO_TENT_INVINC_TIMER] != 0) {
+ this->work[MO_TENT_INVINC_TIMER]--;
+ }
+ if (this->linkHitTimer != 0) {
+ this->linkHitTimer--;
+ }
+
+ if (this->drawActor) {
+ BossMo_TentCollisionCheck(this, globalCtx);
+ if ((this->work[MO_TENT_INVINC_TIMER] == 0) && (this->work[MO_TENT_ACTION_STATE] != MO_TENT_GRAB) &&
+ (this->work[MO_TENT_ACTION_STATE] != MO_TENT_SHAKE)) {
+ BossMo* otherTent = (BossMo*)this->otherTent;
+
+ if (!HAS_LINK(otherTent) && (this->cutIndex == 0)) {
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->tentCollider.base);
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->tentCollider.base);
+ }
+ }
+ if (this->cutIndex == 0) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->tentCollider.base);
+ }
+ }
+ this->work[MO_TENT_BASE_TEX1_X]++;
+ this->work[MO_TENT_BASE_TEX1_Y]++;
+ this->work[MO_TENT_BASE_TEX2_X] -= 3;
+ this->work[MO_TENT_BASE_TEX2_Y]++;
+ Math_ApproachZeroF(&this->waterLevelMod, 0.1f, 0.2f);
+}
+
+void BossMo_UpdateTentColliders(BossMo* this, s32 item, ColliderJntSph* tentCollider, Vec3f* center) {
+ tentCollider->elements[item].dim.worldSphere.center.x = center->x;
+ tentCollider->elements[item].dim.worldSphere.center.y = center->y;
+ tentCollider->elements[item].dim.worldSphere.center.z = center->z;
+ if (this->work[MO_TENT_ACTION_STATE] <= MO_TENT_SHAKE) {
+ tentCollider->elements[item].dim.worldSphere.radius =
+ tentCollider->elements[item].dim.modelSphere.radius * tentCollider->elements[item].dim.scale;
+ } else {
+ tentCollider->elements[item].dim.worldSphere.radius = 0;
+ }
+}
+
+static Gfx* sTentDLists[41] = {
+ gMorphaTentaclePart0DL, gMorphaTentaclePart1DL, gMorphaTentaclePart2DL, gMorphaTentaclePart3DL,
+ gMorphaTentaclePart4DL, gMorphaTentaclePart5DL, gMorphaTentaclePart6DL, gMorphaTentaclePart7DL,
+ gMorphaTentaclePart8DL, gMorphaTentaclePart9DL, gMorphaTentaclePart10DL, gMorphaTentaclePart11DL,
+ gMorphaTentaclePart12DL, gMorphaTentaclePart13DL, gMorphaTentaclePart14DL, gMorphaTentaclePart15DL,
+ gMorphaTentaclePart16DL, gMorphaTentaclePart17DL, gMorphaTentaclePart18DL, gMorphaTentaclePart19DL,
+ gMorphaTentaclePart20DL, gMorphaTentaclePart21DL, gMorphaTentaclePart22DL, gMorphaTentaclePart23DL,
+ gMorphaTentaclePart24DL, gMorphaTentaclePart25DL, gMorphaTentaclePart26DL, gMorphaTentaclePart27DL,
+ gMorphaTentaclePart28DL, gMorphaTentaclePart29DL, gMorphaTentaclePart30DL, gMorphaTentaclePart31DL,
+ gMorphaTentaclePart32DL, gMorphaTentaclePart33DL, gMorphaTentaclePart34DL, gMorphaTentaclePart35DL,
+ gMorphaTentaclePart36DL, gMorphaTentaclePart37DL, gMorphaTentaclePart38DL, gMorphaTentaclePart39DL,
+ gMorphaTentaclePart40DL,
+};
+
+void BossMo_DrawTentacle(BossMo* this, GlobalContext* globalCtx) {
+ static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
+ s16 i;
+ s16 notCut;
+ s16 index;
+ Mtx* matrix = Graph_Alloc(globalCtx->state.gfxCtx, 41 * sizeof(Mtx));
+ f32 phi_f20;
+ f32 phi_f22;
+ Vec3f sp110;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6366);
+
+ sp110.x = globalCtx->envCtx.unk_2A;
+ sp110.y = globalCtx->envCtx.unk_2B;
+ sp110.z = globalCtx->envCtx.unk_2C;
+
+ Matrix_Push();
+
+ gDPPipeSync(POLY_XLU_DISP++);
+
+ gSPSegment(POLY_XLU_DISP++, 0x0C, matrix);
+
+ Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW);
+ Matrix_RotateY((this->actor.shape.rot.y / (f32)0x8000) * M_PI, MTXMODE_APPLY);
+ Matrix_RotateX((this->actor.shape.rot.x / (f32)0x8000) * M_PI, MTXMODE_APPLY);
+
+ BossMo_InitRand(1, 29100, 9786);
+
+ for (i = 0; i < 41; i++, matrix++) {
+ s32 pad;
+ s32 pad2;
+
+ if (i < 2) {
+ Matrix_Push();
+ Matrix_Scale(0.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ notCut = true;
+ } else {
+ if (i >= 3) {
+ Matrix_Translate(0.0f, this->tentStretch[i - 2].y, 0.0f, MTXMODE_APPLY);
+ Matrix_RotateX((this->tentRot[i - 2].x / (f32)0x8000) * M_PI, MTXMODE_APPLY);
+ Matrix_RotateZ((this->tentRot[i - 2].z / (f32)0x8000) * M_PI, MTXMODE_APPLY);
+ }
+ Matrix_Push();
+ Matrix_Scale((this->tentScale[i - 2].x + this->tentRipple[i - 2].x) * this->actor.scale.x,
+ (this->tentScale[i - 2].y + this->tentRipple[i - 2].y) * this->actor.scale.y,
+ (this->tentScale[i - 2].z + this->tentRipple[i - 2].z) * this->actor.scale.z, MTXMODE_APPLY);
+ notCut = true;
+ if ((i >= this->cutIndex) && (this->meltIndex >= i)) {
+ Matrix_Scale(this->cutScale, this->cutScale, this->cutScale, MTXMODE_APPLY);
+ notCut = false;
+ }
+ }
+
+ index = ((this->widthIndex - (i * 2)) + 300) % 300;
+ if (this->work[MO_TENT_ACTION_STATE] < MO_TENT_DEATH_START) {
+ Matrix_RotateY((((this->tentWidth[index] - 1.0f - this->tentPulse) * 1000) / 1000.0f) *
+ this->fwork[MO_TENT_MAX_STRETCH],
+ MTXMODE_APPLY);
+ }
+ Matrix_RotateX(M_PI / 2.0f, MTXMODE_APPLY);
+ Matrix_ToMtx(matrix, "../z_boss_mo.c", 6452);
+
+ gSPMatrix(POLY_XLU_DISP++, matrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ if (i == 0) {
+ func_8002EB44(&this->tentPos[i], &globalCtx->view.eye, &sp110, globalCtx->state.gfxCtx);
+ }
+
+ if (i == 0) {
+ gSPDisplayList(POLY_XLU_DISP++, gMorphaTentacleBaseDL);
+ } else {
+ gSPDisplayList(POLY_XLU_DISP++, sTentDLists[i]);
+ }
+
+ Matrix_Pop();
+
+ if ((i >= 2) && notCut && (i < (this->noBubbles + 38))) {
+ if ((this->work[MO_TENT_ACTION_STATE] == MO_TENT_DEATH_1) ||
+ (this->work[MO_TENT_ACTION_STATE] == MO_TENT_DEATH_2)) {
+ phi_f20 = this->work[MO_TENT_MOVE_TIMER] & 3;
+ phi_f20 *= -15.0f;
+ phi_f22 = ((0.18f + BossMo_RandZeroOne() * 0.1f) * this->actor.scale.x) * 100.0f;
+ } else {
+ phi_f20 = 0.0f;
+ phi_f22 = (((BossMo_RandZeroOne() * (0.08f)) + .08f) * this->actor.scale.x) * 100.0f;
+ }
+ Matrix_Push();
+ Matrix_Translate(((BossMo_RandZeroOne() - 0.5f) * 10.0f) * this->tentScale[i - 2].x,
+ ((BossMo_RandZeroOne() - 0.5f) * 3.0f) + phi_f20,
+ ((BossMo_RandZeroOne() - 0.5f) * 10.0f) * this->tentScale[i - 2].z, MTXMODE_APPLY);
+ func_800D1FD4(&globalCtx->mf_11DA0);
+ Matrix_Scale(phi_f22, phi_f22, 1.0f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6511),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_OPA_DISP++, gMorphaBubbleDL);
+
+ Matrix_Pop();
+ }
+
+ Matrix_MultVec3f(&zeroVec, &this->tentPos[i]);
+ if (i == 36) {
+ Matrix_MultVec3f(&zeroVec, &this->actor.focus.pos);
+ }
+ if (i == 24) {
+ MtxF sp98;
+ Vec3f sp8C = { -16.0f, 13.0f, 30.0f };
+ Vec3s sp84;
+
+ Matrix_Push();
+ if (this->linkToLeft) {
+ sp8C.x *= -1.0f;
+ }
+ Matrix_MultVec3f(&sp8C, &this->grabPosRot.pos);
+ Matrix_RotateX(-35 * M_PI / 64, MTXMODE_APPLY);
+ Matrix_Get(&sp98);
+ func_800D20CC(&sp98, &sp84, 0);
+ this->grabPosRot.rot.x = sp84.x;
+ this->grabPosRot.rot.y = sp84.y;
+ this->grabPosRot.rot.z = sp84.z;
+ Matrix_Pop();
+ }
+ if ((i < 38) && ((i & 1) == 1)) {
+ BossMo_UpdateTentColliders(this, i / 2, &this->tentCollider, &this->tentPos[i]);
+ }
+ }
+
+ Matrix_Pop();
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6571);
+}
+
+void BossMo_DrawWater(BossMo* this, GlobalContext* globalCtx) {
+ s32 pad;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6582);
+ if (1) {}
+
+ Matrix_Push();
+ func_80093D84(globalCtx->state.gfxCtx);
+ Matrix_Translate(0.0f, MO_WATER_LEVEL(globalCtx), 0.0f, MTXMODE_NEW);
+
+ gSPSegment(POLY_XLU_DISP++, 0x0D,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (s16)this->waterTex1x, (s16)this->waterTex1y, 32, 32, 1,
+ (s16)this->waterTex2x, (s16)this->waterTex2y, 32, 32));
+
+ gDPPipeSync(POLY_XLU_DISP++);
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0xFF, 0xFF, 200, 255, 255, (s8)sMorphaTent1->waterTexAlpha);
+
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 100, 255, 80);
+
+ Matrix_Scale(0.5f, 1.0f, 0.5f, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6675),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_XLU_DISP++, gMorphaWaterDL);
+
+ Matrix_Pop();
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6680);
+}
+
+void BossMo_DrawCore(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ BossMo* this = THIS;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6688);
+ if (this->actor.world.pos.y > MO_WATER_LEVEL(globalCtx)) {
+ BossMo_DrawWater(this, globalCtx);
+ }
+ if (this->drawActor) {
+ func_80093D84(globalCtx->state.gfxCtx);
+
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, sMorphaTent1->work[MO_TENT_VAR_TIMER] * 3,
+ sMorphaTent1->work[MO_TENT_VAR_TIMER] * 3, 32, 32, 1,
+ sMorphaTent1->work[MO_TENT_VAR_TIMER] * -3,
+ sMorphaTent1->work[MO_TENT_VAR_TIMER] * -3, 32, 32));
+ gSPSegment(POLY_XLU_DISP++, 0x09,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, sMorphaTent1->work[MO_TENT_VAR_TIMER] * 5, 0, 32, 32, 1,
+ 0, sMorphaTent1->work[MO_TENT_VAR_TIMER] * -10, 32, 32));
+
+ Matrix_RotateX(this->work[MO_TENT_MOVE_TIMER] * 0.5f, MTXMODE_APPLY);
+ Matrix_RotateZ(this->work[MO_TENT_MOVE_TIMER] * 0.8f, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6735),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 255, (s8)this->baseAlpha);
+
+ func_8002ED80(&this->actor, globalCtx, 0);
+
+ gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gMorphaCoreMembraneDL));
+
+ gDPPipeSync(POLY_XLU_DISP++);
+
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 220, 255, 128);
+ if ((this->work[MO_CORE_DMG_FLASH_TIMER] % 2) != 0) {
+ gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 60, 0, 255);
+ } else {
+ gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 255, 255);
+ }
+ gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gMorphaCoreNucleusDL));
+
+ if ((this->work[MO_CORE_DRAW_SHADOW] && (this->actor.world.pos.y >= 0.0f)) ||
+ (this->actor.world.pos.y < MO_WATER_LEVEL(globalCtx))) {
+ f32 groundLevel;
+ s16 shadowAlpha;
+
+ if (this->actor.world.pos.y < MO_WATER_LEVEL(globalCtx)) {
+ groundLevel = -280.0f;
+ shadowAlpha = 100;
+ } else {
+ groundLevel = 0.0f;
+ shadowAlpha = 160;
+ }
+
+ func_80094044(globalCtx->state.gfxCtx);
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, shadowAlpha);
+
+ Matrix_Translate(this->actor.world.pos.x, groundLevel, this->actor.world.pos.z, MTXMODE_NEW);
+ Matrix_Scale(0.23f, 1.0f, 0.23f, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6820),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gCircleShadowDL));
+ }
+ }
+
+ if (this->actor.world.pos.y < MO_WATER_LEVEL(globalCtx)) {
+ BossMo_DrawWater(this, globalCtx);
+ }
+
+ if ((this->csCamera != 0) && (this->csState < MO_INTRO_REVEAL)) {
+ f32 sp8C;
+ f32 sp88;
+ f32 sp84;
+ f32 temp;
+ f32 sp7C;
+ f32 sp78;
+ Vec3f sp6C;
+ Vec3f sp60;
+
+ func_80093D84(globalCtx->state.gfxCtx);
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0xFF, 0xFF, 200, 255, 255, (s8)this->fwork[MO_CORE_INTRO_WATER_ALPHA]);
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 100, 255, (s8)this->fwork[MO_CORE_INTRO_WATER_ALPHA]);
+
+ gSPSegment(POLY_XLU_DISP++, 0x0D,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (s16)sMorphaTent1->waterTex1x,
+ (s16)sMorphaTent1->waterTex1y, 32, 32, 1, (s16)sMorphaTent1->waterTex2x,
+ (s16)sMorphaTent1->waterTex2y, 32, 32));
+
+ sp8C = this->cameraAt.x - this->cameraEye.x;
+ sp88 = this->cameraAt.y - this->cameraEye.y;
+ sp84 = this->cameraAt.z - this->cameraEye.z;
+ temp = SQ(sp8C) + SQ(sp84);
+ sp7C = Math_FAtan2F(sp8C, sp84);
+ sp78 = -Math_FAtan2F(sp88, sqrtf(temp));
+
+ sp6C.x = 0.0f;
+ sp6C.y = 0.0f;
+ sp6C.z = 10.0f;
+
+ Matrix_RotateY(sp7C, MTXMODE_NEW);
+ Matrix_RotateX(sp78, MTXMODE_APPLY);
+ Matrix_MultVec3f(&sp6C, &sp60);
+ sp8C = sp60.x + this->cameraEye.x;
+ sp88 = sp60.y + this->cameraEye.y;
+ sp84 = sp60.z + this->cameraEye.z;
+ Matrix_Translate(sp8C, sp88, sp84, MTXMODE_NEW);
+ Matrix_RotateY(sp7C, MTXMODE_APPLY);
+ Matrix_RotateX(sp78, MTXMODE_APPLY);
+ Matrix_RotateZ(-(0.01f * this->work[MO_TENT_VAR_TIMER]), MTXMODE_APPLY);
+ Matrix_RotateZ(0.1f * this->work[MO_TENT_VAR_TIMER], MTXMODE_APPLY);
+ Matrix_Scale(0.825f, 1.175f, 0.825f, MTXMODE_APPLY);
+ Matrix_RotateZ(-(this->work[MO_TENT_VAR_TIMER] * 0.1f), MTXMODE_APPLY);
+ Matrix_RotateX(M_PI / 2.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.05f, 1.0f, 0.05f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6941),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_XLU_DISP++, gMorphaWaterDL);
+ }
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6945);
+
+ BossMo_DrawEffects(globalCtx->specialEffects, globalCtx);
+}
+
+void BossMo_DrawTent(Actor* thisx, GlobalContext* globalCtx) {
+ s32 pad;
+ BossMo* this = THIS;
+ u16 scroll;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_boss_mo.c", 6958);
+ if (1) {}
+ func_80093D18(globalCtx->state.gfxCtx);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, (s8)(this->baseAlpha * 1.5f));
+ gDPSetEnvColor(POLY_OPA_DISP++, 150, 150, 150, 0);
+
+ func_80093D84(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, this->work[MO_TENT_BASE_TEX1_X],
+ this->work[MO_TENT_BASE_TEX1_Y], 32, 32, 1, this->work[MO_TENT_BASE_TEX2_X],
+ this->work[MO_TENT_BASE_TEX2_Y], 32, 32));
+ gDPSetPrimColor(POLY_XLU_DISP++, 0xFF, 0xFF, 200, 255, 255, (s8)((this->baseAlpha * 12.0f) / 10.0f));
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 100, 255, (s8)this->baseAlpha);
+ scroll = (s16)(Math_SinS(this->work[MO_TENT_VAR_TIMER] * 0xB00) * 30.0f) + 350;
+ gSPTexture(POLY_XLU_DISP++, scroll, scroll, 0, G_TX_RENDERTILE, G_ON);
+
+ if (this->drawActor) {
+ BossMo_DrawTentacle(this, globalCtx);
+ }
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_boss_mo.c", 7023);
+}
+
+void BossMo_UpdateEffects(BossMo* this, GlobalContext* globalCtx) {
+ BossMoEffect* effect = globalCtx->specialEffects;
+ s16 i;
+ Vec3f* targetPos;
+ f32 dx;
+ f32 dz;
+ Vec3f bubbleSpeed = { 0.0f, 0.0f, 0.0f };
+ Vec3f bubbleVel;
+
+ for (i = 0; i < ARRAY_COUNT(sEffects); i++, effect++) {
+ if (effect->type != MO_FX_NONE) {
+ effect->timer++;
+ if (effect->stopTimer == 0) {
+ effect->pos.x += effect->vel.x;
+ effect->pos.y += effect->vel.y;
+ effect->pos.z += effect->vel.z;
+ effect->vel.x += effect->accel.x;
+ effect->vel.y += effect->accel.y;
+ effect->vel.z += effect->accel.z;
+ } else {
+ effect->stopTimer--;
+ }
+ if (effect->type <= MO_FX_BIG_RIPPLE) {
+ if (this->csState >= MO_DEATH_START) {
+ effect->pos.y = MO_WATER_LEVEL(globalCtx);
+ }
+ Math_ApproachF(&effect->scale, effect->fwork[MO_FX_MAX_SIZE], 0.2f, effect->fwork[MO_FX_SPREAD_RATE]);
+ if (effect->rippleMode == 0) {
+ effect->alpha += 15;
+ if (effect->alpha >= effect->maxAlpha) {
+ effect->alpha = effect->maxAlpha;
+ effect->rippleMode++;
+ }
+ } else {
+ effect->alpha -= 5;
+ if (effect->alpha <= 0) {
+ effect->alpha = 0;
+ effect->type = MO_FX_NONE;
+ }
+ }
+ } else if (effect->type == MO_FX_BUBBLE) {
+ if (effect->targetPos == NULL) {
+ if ((effect->accel.y > 0.0f) && (effect->pos.y >= MO_WATER_LEVEL(globalCtx))) {
+ effect->type = MO_FX_NONE;
+ } else {
+ if (effect->vel.y > 2.0f) {
+ effect->vel.y = 2.0f;
+ }
+ effect->alpha -= 20;
+ if (effect->alpha <= 0) {
+ effect->alpha = 0;
+ effect->type = MO_FX_NONE;
+ }
+ }
+ } else {
+ if ((effect->timer % 4) == 0) {
+ targetPos = effect->targetPos;
+ dx = targetPos->x - effect->pos.x;
+ dz = targetPos->z - effect->pos.z;
+ bubbleSpeed.z = effect->fwork[MO_FX_SUCTION];
+ Matrix_RotateY(Math_FAtan2F(dx, dz), MTXMODE_NEW);
+ Matrix_MultVec3f(&bubbleSpeed, &bubbleVel);
+ effect->vel.x = bubbleVel.x;
+ effect->vel.z = bubbleVel.z;
+ }
+ Math_ApproachF(&effect->fwork[MO_FX_SUCTION], 5.0f, 1.0f, 0.5f);
+ if (effect->timer > 20) {
+ effect->alpha -= 30;
+ effect->accel.y = 1.5f;
+ if ((effect->alpha <= 0) || (effect->pos.y >= MO_WATER_LEVEL(globalCtx))) {
+ effect->alpha = 0;
+ effect->type = MO_FX_NONE;
+ }
+ } else {
+ effect->alpha += 30;
+ if (effect->alpha >= 255) {
+ effect->alpha = 255;
+ }
+ }
+ }
+ } else if ((effect->type == MO_FX_DROPLET) || (effect->type == MO_FX_SPLASH) ||
+ (effect->type == MO_FX_SPLASH_TRAIL) || (effect->type == MO_FX_WET_SPOT)) {
+ f32 shimmer = (effect->timer & 6) ? 80.0f : 200.0f;
+
+ Math_ApproachF(&effect->fwork[MO_FX_SHIMMER], shimmer, 1.0f, 80.0f);
+ if (effect->type == MO_FX_WET_SPOT) {
+ Math_ApproachF(&effect->scale, effect->fwork[MO_FX_MAX_SCALE], 0.1f, 0.6f);
+ effect->alpha -= 15;
+ if (effect->alpha <= 0) {
+ effect->alpha = 0;
+ effect->type = MO_FX_NONE;
+ }
+ } else {
+ effect->alpha = effect->fwork[MO_FX_SHIMMER];
+ if (effect->type == MO_FX_SPLASH_TRAIL) {
+ Math_ApproachF(&effect->scale, 0.0f, 1.0f, 0.02f);
+ if (effect->scale <= 0.0f) {
+ effect->type = MO_FX_NONE;
+ }
+ } else {
+ if (effect->type == MO_FX_SPLASH) {
+ Vec3f velocity = { 0.0f, 0.0f, 0.0f };
+
+ BossMo_SpawnDroplet(MO_FX_SPLASH_TRAIL, (BossMoEffect*)globalCtx->specialEffects,
+ &effect->pos, &velocity, effect->scale);
+ }
+ if (effect->vel.y < -20.0f) {
+ effect->vel.y = -20.0f;
+ effect->accel.y = 0.0f;
+ }
+ if (effect->stopTimer == 0) {
+ if (effect->vel.y < -5.0f) {
+ Math_ApproachF(&effect->fwork[MO_FX_STRETCH], 5.0f, 0.1f, 0.15f);
+ }
+ } else if (effect->stopTimer == 1) {
+ effect->vel.x = Rand_CenteredFloat(3.0f);
+ effect->vel.z = Rand_CenteredFloat(3.0f);
+ effect->accel.y = -1.0f;
+ }
+ if ((effect->pos.y <= -280.0f) || ((1.0f >= effect->pos.y) && (effect->pos.y >= -20.0f) &&
+ BossMo_NearLand(&effect->pos, 0.0f))) {
+ effect->accel.y = 0.0f;
+ effect->vel.z = 0.0f;
+ effect->vel.y = 0.0f;
+ effect->vel.x = 0.0f;
+ if (effect->pos.y <= -280.0f) {
+ effect->pos.y = -280.0f;
+ } else {
+ effect->pos.y = 0.0f;
+ }
+ effect->type = MO_FX_WET_SPOT;
+ effect->alpha = 150;
+ effect->fwork[MO_FX_STRETCH] = (effect->scale * 15.0f) * 0.15f;
+ } else if (effect->pos.y <= MO_WATER_LEVEL(globalCtx)) {
+ Vec3f pos = effect->pos;
+
+ pos.y = MO_WATER_LEVEL(globalCtx);
+ if (effect->type == MO_FX_SPLASH) {
+ BossMo_SpawnRipple(globalCtx->specialEffects, &pos, 60.0f, 160.0f, 80, 290,
+ MO_FX_SMALL_RIPPLE);
+ } else {
+ BossMo_SpawnRipple(globalCtx->specialEffects, &pos, 40.0f, 110.0f, 80, 290,
+ MO_FX_SMALL_RIPPLE);
+ }
+ effect->type = MO_FX_NONE;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void BossMo_DrawEffects(BossMoEffect* effect, GlobalContext* globalCtx) {
+ u8 flag = 0;
+ s16 i;
+ s32 pad;
+ GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
+ BossMoEffect* effectHead = effect;
+
+ OPEN_DISPS(gfxCtx, "../z_boss_mo.c", 7264);
+ Matrix_Push();
+
+ for (i = 0; i < ARRAY_COUNT(sEffects); i++, effect++) {
+ if (effect->type == MO_FX_BIG_RIPPLE) {
+ if (flag == 0) {
+ func_80094BC4(gfxCtx);
+
+ gDPSetEnvColor(POLY_XLU_DISP++, 155, 155, 255, 0);
+
+ flag++;
+ }
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, effect->alpha);
+
+ Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_Scale(effect->scale, 1.0f, effect->scale, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_boss_mo.c", 7294),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_XLU_DISP++, gEffWaterRippleDL);
+ }
+ }
+
+ effect = effectHead;
+ flag = 0;
+ for (i = 0; i < ARRAY_COUNT(sEffects); i++, effect++) {
+ if (effect->type == MO_FX_SMALL_RIPPLE) {
+ if (flag == 0) {
+ func_80093D84(globalCtx->state.gfxCtx);
+
+ gDPSetEnvColor(POLY_XLU_DISP++, 155, 155, 255, 0);
+
+ flag++;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091BC40.s")
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, effect->alpha);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091BD38.s")
+ Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_Scale(effect->scale, 1.0f, effect->scale, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_boss_mo.c", 7330),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091BE5C.s")
+ gSPDisplayList(POLY_XLU_DISP++, gEffShockwaveDL);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091BF38.s")
+ effect = effectHead;
+ flag = 0;
+ for (i = 0; i < ARRAY_COUNT(sEffects); i++, effect++) {
+ if (((effect->type == MO_FX_DROPLET) || (effect->type == MO_FX_SPLASH)) ||
+ (effect->type == MO_FX_SPLASH_TRAIL)) {
+ if (flag == 0) {
+ POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091BFFC.s")
+ gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(gDust1Tex));
+ gSPDisplayList(POLY_XLU_DISP++, gMorphaDropletSetupDL);
+ gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/BossMo_Init.s")
+ flag++;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/BossMo_Destroy.s")
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (s16)effect->fwork[MO_FX_SHIMMER], (s16)effect->fwork[MO_FX_SHIMMER],
+ 255, effect->alpha);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091C4E0.s")
+ Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ func_800D1FD4(&globalCtx->mf_11DA0);
+ Matrix_Scale(effect->scale / effect->fwork[MO_FX_STRETCH], effect->fwork[MO_FX_STRETCH] * effect->scale,
+ 1.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_boss_mo.c", 7373),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091C538.s")
+ gSPDisplayList(POLY_XLU_DISP++, gMorphaDropletVtxDL);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091F2FC.s")
+ effect = effectHead;
+ flag = 0;
+ for (i = 0; i < ARRAY_COUNT(sEffects); i++, effect++) {
+ if (effect->type == MO_FX_WET_SPOT) {
+ if (flag == 0) {
+ func_80094044(gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_8091F5A8.s")
+ gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(gDust1Tex));
+ gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0);
+ gSPDisplayList(POLY_XLU_DISP++, gMorphaDropletSetupDL);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_809206C4.s")
+ flag++;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_80921280.s")
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (s16)effect->fwork[MO_FX_SHIMMER], (s16)effect->fwork[MO_FX_SHIMMER],
+ 0xFF, effect->alpha);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_809216D0.s")
+ Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ Matrix_Scale(effect->scale, 1.0f, effect->scale, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_boss_mo.c", 7441),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_80922D30.s")
+ gSPDisplayList(POLY_XLU_DISP++, gMorphaWetSpotVtxDL);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/BossMo_Update.s")
+ effect = effectHead;
+ flag = 0;
+ for (i = 0; i < ARRAY_COUNT(sEffects); i++, effect++) {
+ if (effect->type == MO_FX_BUBBLE) {
+ if (flag == 0) {
+ func_80093D18(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_809237C4.s")
+ gDPSetEnvColor(POLY_OPA_DISP++, 150, 150, 150, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_80923870.s")
+ flag++;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_80923FDC.s")
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, effect->alpha);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_80924228.s")
+ Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
+ func_800D1FD4(&globalCtx->mf_11DA0);
+ Matrix_Scale(effect->scale, effect->scale, 1.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx, "../z_boss_mo.c", 7476),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/BossMo_Draw.s")
+ gSPDisplayList(POLY_OPA_DISP++, gMorphaBubbleDL);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_80924D70.s")
+ Matrix_Pop();
+ CLOSE_DISPS(gfxCtx, "../z_boss_mo.c", 7482);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_80925480.s")
+void BossMo_Unknown(void) {
+ // Appears to be a test function for sound effects.
+ static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
+ static u16 unkSfx[] = {
+ NA_SE_PL_WALK_GROUND,
+ NA_SE_PL_WALK_GROUND,
+ NA_SE_PL_WALK_GROUND,
+ NA_SE_PL_WALK_SAND,
+ NA_SE_PL_WALK_CONCRETE,
+ NA_SE_PL_WALK_DIRT,
+ NA_SE_PL_WALK_WATER0,
+ NA_SE_PL_WALK_WATER1,
+ NA_SE_PL_WALK_WATER2,
+ NA_SE_PL_WALK_MAGMA,
+ NA_SE_PL_WALK_GRASS,
+ NA_SE_PL_WALK_GLASS,
+ NA_SE_PL_WALK_LADDER,
+ NA_SE_PL_WALK_GLASS,
+ NA_SE_PL_WALK_WALL,
+ NA_SE_PL_WALK_HEAVYBOOTS,
+ NA_SE_PL_WALK_ICE,
+ NA_SE_PL_JUMP,
+ NA_SE_PL_JUMP,
+ NA_SE_PL_JUMP_SAND,
+ NA_SE_PL_JUMP_CONCRETE,
+ NA_SE_PL_JUMP_DIRT,
+ NA_SE_PL_JUMP_WATER0,
+ NA_SE_PL_JUMP_WATER1,
+ NA_SE_PL_JUMP_WATER2,
+ NA_SE_PL_JUMP_MAGMA,
+ NA_SE_PL_JUMP_GRASS,
+ NA_SE_PL_JUMP_GLASS,
+ NA_SE_PL_JUMP_LADDER,
+ NA_SE_PL_JUMP_GLASS,
+ NA_SE_PL_JUMP_HEAVYBOOTS,
+ NA_SE_PL_JUMP_ICE,
+ NA_SE_PL_LAND,
+ NA_SE_PL_LAND,
+ NA_SE_PL_LAND_SAND,
+ NA_SE_PL_LAND_CONCRETE,
+ NA_SE_PL_LAND_DIRT,
+ NA_SE_PL_LAND_WATER0,
+ NA_SE_PL_LAND_WATER1,
+ NA_SE_PL_LAND_WATER2,
+ NA_SE_PL_LAND_MAGMA,
+ NA_SE_PL_LAND_GRASS,
+ NA_SE_PL_LAND_GLASS,
+ NA_SE_PL_LAND_LADDER,
+ NA_SE_PL_LAND_GLASS,
+ NA_SE_PL_LAND_HEAVYBOOTS,
+ NA_SE_PL_LAND_ICE,
+ NA_SE_PL_SLIPDOWN,
+ NA_SE_PL_CLIMB_CLIFF,
+ NA_SE_PL_CLIMB_CLIFF,
+ NA_SE_PL_SIT_ON_HORSE,
+ NA_SE_PL_GET_OFF_HORSE,
+ NA_SE_PL_TAKE_OUT_SHIELD,
+ NA_SE_PL_TAKE_OUT_SHIELD,
+ NA_SE_PL_TAKE_OUT_SHIELD,
+ NA_SE_PL_TAKE_OUT_SHIELD,
+ NA_SE_PL_TAKE_OUT_SHIELD,
+ NA_SE_PL_TAKE_OUT_SHIELD,
+ NA_SE_PL_CHANGE_ARMS,
+ NA_SE_PL_CHANGE_ARMS,
+ NA_SE_PL_CHANGE_ARMS,
+ NA_SE_PL_CHANGE_ARMS,
+ NA_SE_PL_CHANGE_ARMS,
+ NA_SE_PL_CHANGE_ARMS,
+ NA_SE_PL_CATCH_BOOMERANG,
+ NA_SE_EV_DIVE_INTO_WATER,
+ NA_SE_EV_JUMP_OUT_WATER,
+ NA_SE_PL_SWIM,
+ NA_SE_PL_THROW,
+ NA_SE_PL_BODY_BOUND,
+ NA_SE_PL_ROLL,
+ NA_SE_PL_SKIP,
+ NA_SE_PL_BODY_HIT,
+ NA_SE_PL_DAMAGE,
+ NA_SE_PL_SLIP,
+ NA_SE_PL_SLIP,
+ NA_SE_PL_SLIP,
+ NA_SE_PL_SLIP_SAND,
+ NA_SE_PL_SLIP_CONCRETE,
+ NA_SE_PL_SLIP_DIRT,
+ NA_SE_PL_SLIP_WATER0,
+ NA_SE_PL_SLIP_WATER1,
+ NA_SE_PL_SLIP_WATER2,
+ NA_SE_PL_SLIP_MAGMA,
+ NA_SE_PL_SLIP_GRASS,
+ NA_SE_PL_SLIP_GLASS,
+ NA_SE_PL_SLIP_LADDER,
+ NA_SE_PL_SLIP_GLASS,
+ NA_SE_PL_SLIP_HEAVYBOOTS,
+ NA_SE_PL_SLIP_ICE,
+ NA_SE_PL_BOUND,
+ NA_SE_PL_BOUND,
+ NA_SE_PL_BOUND_SAND,
+ NA_SE_PL_BOUND_CONCRETE,
+ NA_SE_PL_BOUND_DIRT,
+ NA_SE_PL_BOUND_WATER0,
+ NA_SE_PL_BOUND_WATER1,
+ NA_SE_PL_BOUND_WATER2,
+ NA_SE_PL_BOUND_MAGMA,
+ NA_SE_PL_BOUND_GRASS,
+ NA_SE_PL_BOUND_WOOD,
+ NA_SE_PL_BOUND_LADDER,
+ NA_SE_PL_BOUND_WOOD,
+ NA_SE_PL_BOUND_HEAVYBOOTS,
+ NA_SE_PL_BOUND_ICE,
+ NA_SE_PL_FACE_UP,
+ NA_SE_PL_DIVE_BUBBLE,
+ NA_SE_PL_MOVE_BUBBLE,
+ NA_SE_PL_METALEFFECT_KID,
+ NA_SE_PL_METALEFFECT_ADULT,
+ NA_SE_PL_SPARK - SFX_FLAG,
+ NA_SE_IT_SWORD_IMPACT,
+ NA_SE_IT_SWORD_SWING,
+ NA_SE_IT_SWORD_PUTAWAY,
+ NA_SE_IT_SWORD_PICKOUT,
+ NA_SE_IT_ARROW_SHOT,
+ NA_SE_IT_BOOMERANG_THROW,
+ NA_SE_IT_SHIELD_BOUND,
+ NA_SE_IT_SHIELD_BOUND,
+ NA_SE_IT_BOW_DRAW,
+ NA_SE_IT_SHIELD_REFLECT_SW,
+ NA_SE_IT_ARROW_STICK_HRAD,
+ NA_SE_IT_HAMMER_HIT,
+ NA_SE_IT_HOOKSHOT_CHAIN - SFX_FLAG,
+ NA_SE_IT_SHIELD_REFLECT_MG,
+ NA_SE_IT_BOMB_IGNIT - SFX_FLAG,
+ NA_SE_IT_BOMB_EXPLOSION,
+ NA_SE_IT_BOMB_UNEXPLOSION,
+ NA_SE_IT_BOOMERANG_FLY - SFX_FLAG,
+ NA_SE_IT_SWORD_STRIKE,
+ NA_SE_IT_HAMMER_SWING,
+ NA_SE_IT_HOOKSHOT_REFLECT,
+ NA_SE_IT_ARROW_STICK_CRE,
+ NA_SE_IT_ARROW_STICK_CRE,
+ NA_SE_IT_ARROW_STICK_OBJ,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_IT_SWORD_SWING_HARD,
+ NA_SE_IT_WALL_HIT_HARD,
+ NA_SE_IT_WALL_HIT_SOFT,
+ NA_SE_IT_WALL_HIT_SOFT,
+ NA_SE_IT_STONE_HIT,
+ NA_SE_IT_WOODSTICK_BROKEN,
+ NA_SE_IT_LASH,
+ NA_SE_IT_SHIELD_POSTURE,
+ NA_SE_IT_SLING_SHOT,
+ NA_SE_IT_SLING_DRAW,
+ NA_SE_IT_SWORD_CHARGE - SFX_FLAG,
+ NA_SE_IT_ROLLING_CUT,
+ NA_SE_IT_SWORD_STRIKE_HARD,
+ NA_SE_IT_SLING_REFLECT,
+ NA_SE_IT_SHIELD_REMOVE,
+ NA_SE_IT_HOOKSHOT_READY,
+ NA_SE_IT_HOOKSHOT_RECEIVE,
+ NA_SE_IT_HOOKSHOT_STICK_OBJ,
+ NA_SE_IT_SWORD_REFLECT_MG,
+ NA_SE_IT_DEKU,
+ NA_SE_IT_BOW_FLICK,
+ NA_SE_IT_BOW_FLICK,
+ NA_SE_IT_BOW_FLICK,
+ NA_SE_IT_BOMBCHU_MOVE,
+ NA_SE_IT_SHIELD_CHARGE_LV1,
+ NA_SE_IT_SHIELD_CHARGE_LV2,
+ NA_SE_IT_SHIELD_CHARGE_LV3,
+ NA_SE_IT_SLING_FLICK,
+ NA_SE_IT_SWORD_STICK_STN,
+ NA_SE_IT_REFLECTION_WOOD,
+ NA_SE_IT_SHIELD_REFLECT_MG2,
+ NA_SE_IT_MAGIC_ARROW_SHOT,
+ NA_SE_IT_EXPLOSION_FRAME,
+ NA_SE_IT_EXPLOSION_ICE,
+ NA_SE_IT_YOBI19 - SFX_FLAG,
+ NA_SE_FISHING_REEL_SLOW2 - SFX_FLAG,
+ NA_SE_OC_DOOR_OPEN,
+ NA_SE_EV_DOOR_CLOSE,
+ NA_SE_EV_EXPLOSION,
+ NA_SE_EV_HORSE_WALK,
+ NA_SE_EV_HORSE_RUN,
+ NA_SE_EV_HORSE_NEIGH,
+ NA_SE_EV_RIVER_STREAM - SFX_FLAG,
+ NA_SE_EV_WATER_WALL_BIG - SFX_FLAG,
+ NA_SE_EV_DIVE_WATER,
+ NA_SE_EV_OUT_OF_WATER,
+ NA_SE_EV_ROCK_SLIDE - SFX_FLAG,
+ NA_SE_EV_MAGMA_LEVEL - SFX_FLAG,
+ NA_SE_EV_MAGMA_LEVEL - SFX_FLAG,
+ NA_SE_EV_BRIDGE_OPEN - SFX_FLAG,
+ NA_SE_EV_BRIDGE_CLOSE - SFX_FLAG,
+ NA_SE_EV_BRIDGE_OPEN_STOP,
+ NA_SE_EV_BRIDGE_CLOSE_STOP,
+ NA_SE_EV_WALL_BROKEN,
+ NA_SE_EV_CHICKEN_CRY_N,
+ NA_SE_EV_CHICKEN_CRY_A,
+ NA_SE_EV_CHICKEN_CRY_M,
+ NA_SE_EV_SLIDE_DOOR_OPEN,
+ NA_SE_EV_FOOT_SWITCH,
+ NA_SE_EV_HORSE_GROAN,
+ NA_SE_EV_BOMB_DROP_WATER,
+ NA_SE_EV_BOMB_DROP_WATER,
+ NA_SE_EV_HORSE_JUMP,
+ NA_SE_EV_HORSE_LAND,
+ NA_SE_EV_HORSE_SLIP,
+ NA_SE_EV_FAIRY_DASH,
+ NA_SE_EV_SLIDE_DOOR_CLOSE,
+ NA_SE_EV_STONE_BOUND,
+ NA_SE_EV_STONE_STATUE_OPEN - SFX_FLAG,
+ NA_SE_EV_TBOX_UNLOCK,
+ NA_SE_EV_TBOX_OPEN,
+ NA_SE_SY_TIMER - SFX_FLAG,
+ NA_SE_EV_FLAME_IGNITION,
+ NA_SE_EV_SPEAR_HIT,
+ NA_SE_EV_ELEVATOR_MOVE - SFX_FLAG,
+ NA_SE_EV_WARP_HOLE - SFX_FLAG,
+ NA_SE_EV_LINK_WARP,
+ NA_SE_EV_PILLAR_SINK - SFX_FLAG,
+ NA_SE_EV_WATER_WALL - SFX_FLAG,
+ NA_SE_EV_RIVER_STREAM_S - SFX_FLAG,
+ NA_SE_EV_RIVER_STREAM_F - SFX_FLAG,
+ NA_SE_EV_HORSE_LAND2,
+ NA_SE_EV_HORSE_SANDDUST,
+ NA_SE_EV_BOMB_BOUND,
+ NA_SE_EV_BOMB_BOUND,
+ NA_SE_EV_WATERDROP - SFX_FLAG,
+ NA_SE_EV_TORCH - SFX_FLAG,
+ NA_SE_EV_MAGMA_LEVEL_M - SFX_FLAG,
+ NA_SE_EV_FIRE_PILLAR - SFX_FLAG,
+ NA_SE_EV_FIRE_PLATE - SFX_FLAG,
+ NA_SE_EV_BLOCK_BOUND,
+ NA_SE_EV_METALDOOR_SLIDE - SFX_FLAG,
+ NA_SE_EV_METALDOOR_STOP,
+ NA_SE_EV_BLOCK_SHAKE,
+ NA_SE_EV_BOX_BREAK,
+ NA_SE_EV_HAMMER_SWITCH,
+ NA_SE_EV_MAGMA_LEVEL_L - SFX_FLAG,
+ NA_SE_EV_SPEAR_FENCE,
+ NA_SE_EV_GANON_HORSE_NEIGH,
+ NA_SE_EV_GANON_HORSE_GROAN,
+ NA_SE_EV_FANTOM_WARP_S,
+ NA_SE_EV_FANTOM_WARP_L - SFX_FLAG,
+ NA_SE_EV_FOUNTAIN - SFX_FLAG,
+ NA_SE_EV_KID_HORSE_WALK,
+ NA_SE_EV_KID_HORSE_RUN,
+ NA_SE_EV_KID_HORSE_NEIGH,
+ NA_SE_EV_KID_HORSE_GROAN,
+ NA_SE_EV_WHITE_OUT,
+ NA_SE_EV_LIGHT_GATHER - SFX_FLAG,
+ NA_SE_EV_TREE_CUT,
+ NA_SE_EV_WATERDROP,
+ NA_SE_EV_TORCH,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_EN_DODO_J_WALK,
+ NA_SE_EN_DODO_J_CRY,
+ NA_SE_EN_DODO_J_FIRE - SFX_FLAG,
+ NA_SE_EN_DODO_J_DAMAGE,
+ NA_SE_EN_DODO_J_DEAD,
+ NA_SE_EN_DODO_K_CRY,
+ NA_SE_EN_DODO_K_DAMAGE,
+ NA_SE_EN_DODO_K_DEAD,
+ NA_SE_EN_DODO_K_WALK,
+ NA_SE_EN_DODO_K_FIRE - SFX_FLAG,
+ NA_SE_EN_GOMA_WALK,
+ NA_SE_EN_GOMA_HIGH,
+ NA_SE_EN_GOMA_CLIM,
+ NA_SE_EN_GOMA_DOWN,
+ NA_SE_EN_GOMA_CRY1,
+ NA_SE_EN_GOMA_CRY2,
+ NA_SE_EN_GOMA_DAM1,
+ NA_SE_EN_GOMA_DAM2,
+ NA_SE_EN_GOMA_DEAD,
+ NA_SE_EN_GOMA_UNARI,
+ NA_SE_EN_GOMA_EGG1,
+ NA_SE_EN_GOMA_EGG2,
+ NA_SE_EN_GOMA_JR_WALK,
+ NA_SE_EN_GOMA_JR_CRY,
+ NA_SE_EN_GOMA_JR_DAM1,
+ NA_SE_EN_GOMA_JR_DAM2,
+ NA_SE_EN_GOMA_JR_DEAD,
+ NA_SE_EN_GOMA_DEMO_EYE,
+ NA_SE_EN_GOMA_LAST - SFX_FLAG,
+ NA_SE_EN_GOMA_UNARI2,
+ NA_SE_EN_DODO_M_CRY,
+ NA_SE_EN_DODO_M_DEAD,
+ NA_SE_EN_DODO_M_MOVE,
+ NA_SE_EN_DODO_M_DOWN,
+ NA_SE_EN_DODO_M_UP,
+ NA_SE_EN_DODO_M_GND,
+ NA_SE_EN_RIZA_CRY,
+ NA_SE_EN_RIZA_ATTACK,
+ NA_SE_EN_RIZA_DAMAGE,
+ NA_SE_EN_RIZA_WARAU,
+ NA_SE_EN_RIZA_DEAD,
+ NA_SE_EN_RIZA_WALK,
+ NA_SE_EN_RIZA_JUMP,
+ NA_SE_EN_RIZA_ONGND,
+ NA_SE_EN_RIZA_DOWN,
+ NA_SE_EN_STAL_WARAU,
+ NA_SE_EN_STAL_SAKEBI,
+ NA_SE_EN_STAL_DAMAGE,
+ NA_SE_EN_STAL_DEAD,
+ NA_SE_EN_STAL_JUMP,
+ NA_SE_EN_STAL_WALK,
+ NA_SE_EN_RIZA_DOWN,
+ NA_SE_EN_FFLY_ATTACK,
+ NA_SE_EN_FFLY_FLY,
+ NA_SE_EN_FFLY_DEAD,
+ NA_SE_EN_AMOS_WALK,
+ NA_SE_EN_AMOS_WAVE,
+ NA_SE_EN_AMOS_DEAD,
+ NA_SE_EN_AMOS_DAMAGE,
+ NA_SE_EN_AMOS_VOICE,
+ NA_SE_EN_DODO_K_COLI,
+ NA_SE_EN_DODO_K_COLI2,
+ NA_SE_EN_DODO_K_ROLL - SFX_FLAG,
+ NA_SE_EN_DODO_K_BREATH - SFX_FLAG,
+ NA_SE_EN_DODO_K_DRINK,
+ NA_SE_EN_DODO_K_DOWN - SFX_FLAG,
+ NA_SE_EN_DODO_K_OTAKEBI,
+ NA_SE_EN_DODO_K_END,
+ NA_SE_EN_DODO_K_LAST - SFX_FLAG,
+ NA_SE_EN_DODO_K_LAVA,
+ NA_SE_EN_DODO_J_BREATH - SFX_FLAG,
+ NA_SE_EN_DODO_J_TAIL,
+ NA_SE_EN_RIZA_DOWN,
+ NA_SE_EN_DEKU_MOUTH,
+ NA_SE_EN_DEKU_ATTACK,
+ NA_SE_EN_DEKU_DAMAGE,
+ NA_SE_EN_DEKU_DEAD,
+ NA_SE_EN_DEKU_JR_MOUTH,
+ NA_SE_EN_DEKU_JR_ATTACK,
+ NA_SE_EN_DEKU_JR_DEAD,
+ NA_SE_EN_DODO_M_GND,
+ NA_SE_EN_TAIL_FLY - SFX_FLAG,
+ NA_SE_EN_TAIL_CRY,
+ NA_SE_EN_STALTU_DOWN,
+ NA_SE_EN_STALTU_UP,
+ NA_SE_EN_STALTU_LAUGH,
+ NA_SE_EN_STALTU_DAMAGE,
+ NA_SE_EN_STAL_JUMP,
+ NA_SE_EN_DODO_M_GND,
+ NA_SE_EN_TEKU_DEAD,
+ NA_SE_EN_TEKU_WALK,
+ NA_SE_EN_PO_KANTERA,
+ NA_SE_EN_PO_FLY - SFX_FLAG,
+ NA_SE_EN_PO_AWAY - SFX_FLAG,
+ NA_SE_EN_PO_APPEAR,
+ NA_SE_EN_PO_DISAPPEAR,
+ NA_SE_EN_PO_DAMAGE,
+ NA_SE_EN_PO_DEAD,
+ NA_SE_EN_PO_DEAD2,
+ NA_SE_EN_EXTINCT,
+ NA_SE_EN_NUTS_UP,
+ NA_SE_EN_NUTS_DOWN,
+ NA_SE_EN_NUTS_THROW,
+ NA_SE_EN_NUTS_WALK,
+ NA_SE_EN_NUTS_DAMAGE,
+ NA_SE_EN_NUTS_DEAD,
+ NA_SE_EN_STALTU_ROLL,
+ NA_SE_EN_STALWALL_DEAD,
+ NA_SE_EN_TEKU_DAMAGE,
+ NA_SE_EN_FALL_AIM,
+ NA_SE_EN_FALL_UP,
+ NA_SE_EN_FALL_CATCH,
+ NA_SE_EN_FALL_LAND,
+ NA_SE_EN_FALL_WALK,
+ NA_SE_EN_FALL_DAMAGE,
+ NA_SE_EN_BIRI_FLY,
+ NA_SE_EN_BIRI_JUMP,
+ NA_SE_EN_BIRI_SPARK - SFX_FLAG,
+ NA_SE_EN_FANTOM_TRANSFORM,
+ NA_SE_EN_FANTOM_TRANSFORM,
+ NA_SE_EN_FANTOM_THUNDER,
+ NA_SE_EN_FANTOM_SPARK,
+ NA_SE_EN_FANTOM_FLOAT - SFX_FLAG,
+ NA_SE_EN_FANTOM_MASIC1,
+ NA_SE_EN_FANTOM_MASIC2,
+ NA_SE_EN_FANTOM_FIRE - SFX_FLAG,
+ NA_SE_EN_FANTOM_HIT_THUNDER,
+ NA_SE_EN_FANTOM_ATTACK,
+ NA_SE_EN_FANTOM_STICK,
+ NA_SE_EN_FANTOM_EYE,
+ NA_SE_EN_FANTOM_LAST,
+ NA_SE_EN_FANTOM_THUNDER_GND,
+ NA_SE_EN_FANTOM_DAMAGE,
+ NA_SE_EN_FANTOM_DEAD,
+ NA_SE_EN_FANTOM_LAUGH,
+ NA_SE_EN_FANTOM_DAMAGE2,
+ NA_SE_EN_FANTOM_VOICE,
+ NA_SE_EN_MORIBLIN_WALK,
+ NA_SE_EN_MORIBLIN_SLIDE,
+ NA_SE_EN_MORIBLIN_ATTACK,
+ NA_SE_EN_MORIBLIN_VOICE,
+ NA_SE_EN_MORIBLIN_SPEAR_AT,
+ NA_SE_EN_MORIBLIN_SPEAR_NORM,
+ NA_SE_EN_MORIBLIN_DEAD,
+ NA_SE_EN_NUTS_THROW,
+ NA_SE_EN_OCTAROCK_FLOAT,
+ NA_SE_EN_OCTAROCK_JUMP,
+ NA_SE_EN_OCTAROCK_LAND,
+ NA_SE_EN_OCTAROCK_SINK,
+ NA_SE_EN_OCTAROCK_BUBLE,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_SY_WIN_OPEN,
+ NA_SE_SY_WIN_CLOSE,
+ NA_SE_SY_CORRECT_CHIME,
+ NA_SE_SY_GET_RUPY,
+ NA_SE_SY_MESSAGE_WOMAN,
+ NA_SE_SY_MESSAGE_MAN,
+ NA_SE_SY_ERROR,
+ NA_SE_SY_TRE_BOX_APPEAR,
+ NA_SE_SY_TRE_BOX_APPEAR,
+ NA_SE_SY_DECIDE,
+ NA_SE_SY_CURSOR,
+ NA_SE_SY_CANCEL,
+ NA_SE_SY_HP_RECOVER,
+ NA_SE_SY_ATTENTION_ON,
+ NA_SE_SY_ATTENTION_ON,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_SY_LOCK_ON,
+ NA_SE_SY_LOCK_ON,
+ NA_SE_SY_LOCK_OFF,
+ NA_SE_SY_LOCK_ON_HUMAN,
+ NA_SE_SY_CAMERA_ZOOM_UP,
+ NA_SE_SY_CAMERA_ZOOM_DOWN,
+ NA_SE_SY_ATTENTION_ON_OLD,
+ NA_SE_SY_ATTENTION_URGENCY,
+ NA_SE_SY_MESSAGE_PASS,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_SY_PIECE_OF_HEART,
+ NA_SE_SY_GET_ITEM,
+ NA_SE_SY_WIN_SCROLL_LEFT,
+ NA_SE_SY_WIN_SCROLL_RIGHT,
+ NA_SE_SY_OCARINA_ERROR,
+ NA_SE_SY_CAMERA_ZOOM_UP_2,
+ NA_SE_SY_CAMERA_ZOOM_DOWN_2,
+ NA_SE_SY_GLASSMODE_ON,
+ NA_SE_SY_GLASSMODE_OFF,
+ NA_SE_SY_ATTENTION_ON,
+ NA_SE_SY_ATTENTION_URGENCY,
+ NA_SE_OC_OCARINA,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_LAND - SFX_FLAG,
+ NA_SE_VO_LI_SWORD_N,
+ NA_SE_VO_LI_SWORD_N,
+ NA_SE_VO_LI_SWORD_N,
+ NA_SE_VO_LI_SWORD_N,
+ NA_SE_VO_LI_SWORD_N,
+ NA_SE_VO_LI_SWORD_N,
+ NA_SE_VO_LI_SWORD_N,
+ NA_SE_VO_LI_SWORD_L,
+ NA_SE_VO_LI_SWORD_L,
+ NA_SE_VO_LI_MAGIC_ATTACK,
+ NA_SE_VO_LI_LASH,
+ NA_SE_VO_LI_HANG,
+ NA_SE_VO_LI_AUTO_JUMP,
+ NA_SE_VO_LI_CLIMB_END,
+ NA_SE_VO_LI_CLIMB_END,
+ NA_SE_VO_LI_CLIMB_END,
+ NA_SE_VO_LI_CLIMB_END,
+ NA_SE_VO_LI_DAMAGE_S,
+ NA_SE_VO_LI_DAMAGE_S,
+ NA_SE_VO_LI_FALL_L,
+ NA_SE_VO_LI_FALL_S,
+ NA_SE_VO_LI_FALL_L,
+ NA_SE_VO_LI_FALL_L,
+ NA_SE_VO_LI_BREATH_REST,
+ NA_SE_VO_LI_BREATH_REST,
+ NA_SE_VO_LI_DOWN,
+ NA_SE_VO_LI_TAKEN_AWAY,
+ NA_SE_VO_LI_HELD,
+ NA_SE_VO_NAVY_HELLO,
+ NA_SE_VO_NAVY_HEAR,
+ NA_SE_VO_NAVY_ENEMY,
+ NA_SE_VO_NAVY_HELLO,
+ NA_SE_VO_NAVY_HEAR,
+ NA_SE_VO_NAVY_ENEMY,
+ NA_SE_VO_TA_SLEEP,
+ NA_SE_EN_VALVAISA_APPEAR - SFX_FLAG,
+ NA_SE_EN_VALVAISA_ROAR,
+ NA_SE_EN_VALVAISA_MAHI1,
+ NA_SE_EN_VALVAISA_MAHI2,
+ NA_SE_EN_VALVAISA_KNOCKOUT,
+ NA_SE_EN_VALVAISA_DAMAGE1,
+ NA_SE_EN_VALVAISA_DAMAGE2,
+ NA_SE_EN_VALVAISA_ROCK,
+ NA_SE_EN_VALVAISA_LAND,
+ NA_SE_EN_VALVAISA_DEAD,
+ NA_SE_EN_VALVAISA_BURN - SFX_FLAG,
+ NA_SE_EN_VALVAISA_FIRE - SFX_FLAG,
+ NA_SE_EN_VALVAISA_LAND2,
+ NA_SE_EN_MONBLIN_HAM_LAND,
+ NA_SE_EN_MONBLIN_HAM_DOWN,
+ NA_SE_EN_MONBLIN_HAM_UP,
+ NA_SE_EN_REDEAD_CRY,
+ NA_SE_EN_REDEAD_AIM,
+ NA_SE_EN_REDEAD_DAMAGE,
+ NA_SE_EN_RIZA_DOWN,
+ NA_SE_EN_REDEAD_DEAD,
+ NA_SE_EN_REDEAD_ATTACK,
+ NA_SE_EN_PO_LAUGH,
+ NA_SE_EN_PO_CRY,
+ NA_SE_EN_PO_ROLL,
+ NA_SE_EN_PO_LAUGH2,
+ NA_SE_EN_MOFER_APPEAR - SFX_FLAG,
+ NA_SE_EN_MOFER_ATTACK - SFX_FLAG,
+ NA_SE_EN_MOFER_WAVE,
+ NA_SE_EN_MOFER_CATCH,
+ NA_SE_EN_MOFER_CORE_DAMAGE,
+ NA_SE_EN_MOFER_CUT,
+ NA_SE_EN_MOFER_MOVE_DEMO - SFX_FLAG,
+ NA_SE_EN_MOFER_BUBLE_DEMO,
+ NA_SE_EN_MOFER_CORE_JUMP,
+ NA_SE_EN_GOLON_WAKE_UP,
+ NA_SE_EN_GOLON_SIT_DOWN,
+ NA_SE_EN_DODO_M_GND,
+ NA_SE_EN_DEADHAND_BITE,
+ NA_SE_EN_DEADHAND_WALK,
+ NA_SE_EN_DEADHAND_GRIP,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ NA_SE_PL_WALK_GROUND - SFX_FLAG,
+ };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Boss_Mo/func_80925C18.s")
+ if (BREG(32) != 0) {
+ BREG(32)--;
+ Audio_QueueSeqCmd(0x100100FF);
+ func_80078914(&zeroVec, unkSfx[BREG(33)]);
+ }
+ if (BREG(34) != 0) {
+ BREG(34) = 0;
+ Audio_QueueSeqCmd((u16)BREG(35));
+ }
+}
diff --git a/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h b/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h
index e9323a37c..f7209dced 100644
--- a/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h
+++ b/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h
@@ -6,11 +6,132 @@
struct BossMo;
+typedef void (*BossMoActionFunc)(struct BossMo*, GlobalContext*);
+
+typedef enum {
+ /* 0 */ MO_TENT_ACTION_STATE,
+ /* 1 */ MO_TENT_MOVE_TIMER,
+ /* 2 */ MO_TENT_VAR_TIMER,
+ /* 3 */ MO_TENT_UNK_TIMER,
+ /* 4 */ MO_TENT_INVINC_TIMER,
+ /* 5 */ MO_TENT_BASE_TEX1_X,
+ /* 6 */ MO_TENT_BASE_TEX1_Y,
+ /* 7 */ MO_TENT_BASE_TEX2_X,
+ /* 8 */ MO_TENT_BASE_TEX2_Y,
+ /* 9 */ MO_TENT_SHORT_MAX
+} BossMoTentS16Var;
+
+typedef enum {
+ /* 0 */ MO_CORE_ACTION_STATE,
+ /* 1 */ MO_CORE_MOVE_TIMER,
+ /* 2 */ MO_CORE_VAR_TIMER,
+ /* 3 */ MO_CORE_DMG_FLASH_TIMER,
+ /* 4 */ MO_CORE_INVINC_TIMER,
+ /* 5 */ MO_CORE_SHORT_5,
+ /* 6 */ MO_CORE_POS_IN_TENT,
+ /* 7 */ MO_CORE_DRAW_SHADOW,
+ /* 8 */ MO_CORE_WAIT_IN_WATER,
+ /* 9 */ MO_CORE_SHORT_MAX
+} BossMoCoreS16Var;
+
+typedef enum {
+ /* 0 */ MO_TENT_SWING_LAG_X,
+ /* 1 */ MO_TENT_SWING_SIZE_X,
+ /* 2 */ MO_TENT_SWING_RATE_X,
+ /* 3 */ MO_TENT_SWING_LAG_Z,
+ /* 4 */ MO_TENT_SWING_SIZE_Z,
+ /* 5 */ MO_TENT_SWING_RATE_Z,
+ /* 6 */ MO_TENT_MAX_STRETCH,
+ /* 7 */ MO_TENT_FLOAT_MAX
+} BossMoTentF32Var;
+
+typedef enum {
+ /* 0 */ MO_CORE_INTRO_WATER_ALPHA,
+ /* 7 */ MO_CORE_FLOAT_MAX
+} BossMoCoreF32Var;
+
+#define MO_SHORT_MAX MAX(MO_TENT_SHORT_MAX, MO_CORE_SHORT_MAX)
+#define MO_FLOAT_MAX MAX(MO_TENT_FLOAT_MAX, MO_CORE_FLOAT_MAX)
+
typedef struct BossMo {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x1440];
+ /* 0x014C */ Actor* otherTent;
+ /* 0x0150 */ BossMoActionFunc actionFunc;
+ /* 0x0154 */ u8 tent2KillTimer;
+ /* 0x0155 */ u8 hitCount;
+ /* 0x0156 */ u8 tentSpawnPos;
+ /* 0x0158 */ s16 work[MO_SHORT_MAX];
+ /* 0x016A */ s16 widthIndex;
+ /* 0x016C */ s16 pulsePhase;
+ /* 0x016E */ s16 xSwing;
+ /* 0x0170 */ s16 zSwing;
+ /* 0x0172 */ s16 cutIndex;
+ /* 0x0174 */ s16 meltIndex;
+ /* 0x0176 */ s16 linkToLeft;
+ /* 0x0178 */ s16 mashCounter;
+ /* 0x017A */ s16 noBubbles;
+ /* 0x017C */ s16 sfxTimer;
+ /* 0x017E */ s16 timers[5];
+ /* 0x0188 */ f32 fwork[MO_FLOAT_MAX];
+ /* 0x01A4 */ f32 baseAlpha;
+ /* 0x01A8 */ f32 cutScale;
+ /* 0x01AC */ f32 waterTex1x;
+ /* 0x01B0 */ f32 waterTex1y;
+ /* 0x01B4 */ f32 waterTex2x;
+ /* 0x01B8 */ f32 waterTex2y;
+ /* 0x01BC */ f32 waterLevel;
+ /* 0x01C0 */ f32 flattenRate;
+ /* 0x01C4 */ f32 waterTexAlpha;
+ /* 0x01C8 */ f32 waterLevelMod;
+ /* 0x01CC */ s16 baseBubblesTimer;
+ /* 0x01CE */ s16 attackAngleMod;
+ /* 0x01D0 */ u8 unk_1D0; // unused?
+ /* 0x01D1 */ u8 drawActor;
+ /* 0x01D2 */ u8 linkHitTimer;
+ /* 0x01D4 */ Vec3f targetPos;
+ /* 0x01E0 */ f32 tentRippleSize;
+ /* 0x01E4 */ PosRot grabPosRot;
+ /* 0x01F8 */ f32 tentWidth[300];
+ /* 0x06A8 */ Vec3f tentStretch[41];
+ /* 0x0894 */ Vec3f tentScale[41];
+ /* 0x0A80 */ Vec3f tentRipple[41];
+ /* 0x0C6C */ Vec3s tentRot[41];
+ /* 0x0D64 */ f32 tentMaxAngle;
+ /* 0x0D68 */ f32 tentSpeed;
+ /* 0x0D6C */ f32 tentPulse;
+ /* 0x0D70 */ Vec3f tentPos[41];
+ /* 0x0F5C */ f32 cameraZoom;
+ /* 0x0F60 */ s16 csState;
+ /* 0x0F62 */ s16 csCamera;
+ /* 0x0F64 */ s16 targetIndex;
+ /* 0x0F68 */ Vec3f cameraEye;
+ /* 0x0F74 */ Vec3f cameraAt;
+ /* 0x0F80 */ Vec3f cameraUp;
+ /* 0x0F8C */ char unk_F8C[0x18];
+ /* 0x0FA4 */ Vec3f cameraEyeVel;
+ /* 0x0FB0 */ Vec3f cameraAtVel;
+ /* 0x0FBC */ Vec3f cameraNextEye;
+ /* 0x0FC8 */ Vec3f cameraEyeMaxVel;
+ /* 0x0FD4 */ Vec3f cameraNextAt;
+ /* 0x0FE0 */ Vec3f cameraAtMaxVel;
+ /* 0x0FEC */ f32 cameraSpeedMod;
+ /* 0x0FF0 */ f32 cameraAccel;
+ /* 0x0FF4 */ char unk_FF4[8];
+ /* 0x0FFC */ f32 cameraDist;
+ /* 0x1000 */ f32 cameraSpeed;
+ /* 0x1004 */ f32 cameraYaw;
+ /* 0x1008 */ f32 cameraYawRate;
+ /* 0x100C */ f32 cameraYawShake;
+ /* 0x1010 */ Vec3f tentTipPos;
+ /* 0x101C */ ColliderJntSph tentCollider;
+ /* 0x103C */ ColliderJntSphElement tentElements[19];
+ /* 0x14FC */ ColliderCylinder coreCollider;
+ /* 0x1548 */ char unk_1548[0x44];
} BossMo; // size = 0x158C
+#define BOSSMO_CORE -1
+#define BOSSMO_TENTACLE 100
+
extern const ActorInit Boss_Mo_InitVars;
#endif
diff --git a/src/overlays/actors/ovl_Boss_Mo/z_boss_mo_colchk.c b/src/overlays/actors/ovl_Boss_Mo/z_boss_mo_colchk.c
new file mode 100644
index 000000000..3826a4485
--- /dev/null
+++ b/src/overlays/actors/ovl_Boss_Mo/z_boss_mo_colchk.c
@@ -0,0 +1,247 @@
+#include "global.h"
+#include "z_boss_mo.h"
+
+static ColliderJntSphElementInit sJntSphElementsInit[19] = {
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 0, { { 0, 0, 0 }, 0 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 1, { { 0, 0, 0 }, 0 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 2, { { 0, 0, 0 }, 30 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 3, { { 0, 0, 0 }, 24 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 4, { { 0, 0, 0 }, 22 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 5, { { 0, 0, 0 }, 20 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 6, { { 0, 0, 0 }, 18 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 7, { { 0, 0, 0 }, 16 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 8, { { 0, 0, 0 }, 14 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 9, { { 0, 0, 0 }, 12 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 10, { { 0, 0, 0 }, 10 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 11, { { 0, 0, 0 }, 10 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 12, { { 0, 0, 0 }, 10 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 13, { { 0, 0, 0 }, 10 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 14, { { 0, 0, 0 }, 10 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 15, { { 0, 0, 0 }, 10 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 16, { { 0, 0, 0 }, 10 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 17, { { 0, 0, 0 }, 10 }, 100 },
+ },
+ {
+ {
+ ELEMTYPE_UNK4,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFCFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ { 18, { { 0, 0, 0 }, 10 }, 100 },
+ },
+};
+
+static ColliderJntSphInit sJntSphInit = {
+ {
+ COLTYPE_NONE,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_PLAYER,
+ OC2_TYPE_1,
+ COLSHAPE_JNTSPH,
+ },
+ 19,
+ sJntSphElementsInit,
+};
+
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_HIT3,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_PLAYER,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0xFFCFFFFF, 0x00, 0x10 },
+ { 0xFFDFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON | BUMP_HOOKABLE,
+ OCELEM_ON,
+ },
+ { 20, 40, -20, { 0, 0, 0 } },
+};