diff --git a/config/SOUE01/rels/d_t_fairytagNP/symbols.txt b/config/SOUE01/rels/d_t_fairytagNP/symbols.txt index a31f4886..88a61735 100644 --- a/config/SOUE01/rels/d_t_fairytagNP/symbols.txt +++ b/config/SOUE01/rels/d_t_fairytagNP/symbols.txt @@ -3,8 +3,8 @@ _epilog = .text:0x00000030; // type:function size:0x2C scope:global _unresolved = .text:0x00000060; // type:function size:0x4 scope:global dTgFairy_c_classInit__Fv = .text:0x00000070; // type:function size:0x4C createHeap__10dTgFairy_cFv = .text:0x000000C0; // type:function size:0x6C -__ct__25dAcRef_c<13dAcObjFairy_c>Fv = .text:0x00000130; // type:function size:0x14 -__dt__25dAcRef_c<13dAcObjFairy_c>Fv = .text:0x00000150; // type:function size:0x58 +__ct__23dAcRef_c<11dAcOFairy_c>Fv = .text:0x00000130; // type:function size:0x14 +__dt__23dAcRef_c<11dAcOFairy_c>Fv = .text:0x00000150; // type:function size:0x58 create__10dTgFairy_cFv = .text:0x000001B0; // type:function size:0x7C doDelete__10dTgFairy_cFv = .text:0x00000230; // type:function size:0x50 actorExecute__10dTgFairy_cFv = .text:0x00000280; // type:function size:0x8 diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index d481d933..e8ff14ed 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -1450,7 +1450,9 @@ d/a/obj/d_a_obj_fairy.cpp: .text start:0x80265620 end:0x80268598 align:16 .ctors start:0x804DB838 end:0x804DB83C .data start:0x80534E78 end:0x80535270 + .sdata start:0x80573A30 end:0x80573A48 .sbss start:0x80575908 end:0x80575910 + .sdata2 start:0x8057C180 end:0x8057C238 .bss start:0x805B4DD8 end:0x805B4FA8 d/a/obj/d_a_obj_tbox.cpp: diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index cf9a02e4..fd5a5fbe 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -1060,7 +1060,7 @@ getParams2Lower__9dAcBase_cCFv = .text:0x8002D010; // type:function size:0xC findActor__9dAcBase_cFPcP9dAcBase_c = .text:0x8002D020; // type:function size:0x74 searchActor__9dAcBase_cFP9dAcBase_c = .text:0x8002D0A0; // type:function size:0x88 forEveryActor__9dAcBase_cFPFP9dAcBase_cP9dAcBase_c_PvP9dAcBase_c = .text:0x8002D130; // type:function size:0x5C -getXZAngleToPlayer__9dAcBase_cFv = .text:0x8002D190; // type:function size:0x3C +getXZAngleToPlayer__9dAcBase_cCFv = .text:0x8002D190; // type:function size:0x3C getDistanceToActor__9dAcBase_cFP9dAcBase_cfPf = .text:0x8002D1D0; // type:function size:0xB8 getDistanceAndAngleToActor__9dAcBase_cFP9dAcBase_cfssPfPsPs = .text:0x8002D290; // type:function size:0x148 isWithinPlayerRadius__9dAcBase_cCFf = .text:0x8002D3E0; // type:function size:0x5C @@ -2468,7 +2468,7 @@ getRidingActor__17daPlayerActBase_cFv = .text:0x8005BB50; // type:function size: AcNpcTke__setRefInLinkToCall = .text:0x8005BB60; // type:function size:0xC setObtainedItemID = .text:0x8005BB70; // type:function size:0x3C fn_8005BBB0 = .text:0x8005BBB0; // type:function size:0xC -fn_8005BBC0 = .text:0x8005BBC0; // type:function size:0xC +fairyHeal__17daPlayerActBase_cFP11dAcOFairy_c = .text:0x8005BBC0; // type:function size:0xC turnSoupCold = .text:0x8005BBD0; // type:function size:0x8 addExtraHearts = .text:0x8005BBE0; // type:function size:0x74 AcItem__healLink = .text:0x8005BC60; // type:function size:0x18 @@ -2502,7 +2502,7 @@ isItemRestricted = .text:0x8005C4F0; // type:function size:0xE0 fn_8005C5D0 = .text:0x8005C5D0; // type:function size:0x34 getLinkPtr__Fv = .text:0x8005C610; // type:function size:0x8 getShieldRegenProgressMaybe__17daPlayerActBase_cFv = .text:0x8005C620; // type:function size:0x8 -isUsingBottle__17daPlayerActBase_cFv = .text:0x8005C630; // type:function size:0x8 +isUsingBottle__17daPlayerActBase_cCFv = .text:0x8005C630; // type:function size:0x8 isBottleOut__17daPlayerActBase_cFv = .text:0x8005C640; // type:function size:0x8 isHealingShield__17daPlayerActBase_cFv = .text:0x8005C650; // type:function size:0x8 isDrinkingPotion__17daPlayerActBase_cFv = .text:0x8005C660; // type:function size:0x8 @@ -13551,7 +13551,7 @@ checkFlag__9dAcItem_cFUl = .text:0x80251B70; // type:function size:0x128 setFlag__9dAcItem_cFl = .text:0x80251CA0; // type:function size:0xC0 AcItem__checkFlagForItem = .text:0x80251D60; // type:function size:0x34 AcItem__checkItemFlag = .text:0x80251DA0; // type:function size:0x48 -isItemAnyFairy = .text:0x80251DF0; // type:function size:0x50 +hasAnyFairy__9dAcItem_cFv = .text:0x80251DF0; // type:function size:0x50 setItemflag = .text:0x80251E40; // type:function size:0x1C getRupeeCounter = .text:0x80251E60; // type:function size:0x8 getRupeeCounter__9dAcItem_cFv = .text:0x80251E70; // type:function size:0x4 @@ -14173,71 +14173,71 @@ initializeState__29sFStateID_c<14dAcBoomerang_c>CFR14dAcBoomerang_c = .text:0x80 __sinit_\d_a_obj_boomerang_cpp = .text:0x80265110; // type:function size:0x41C __dt__29sFStateID_c<14dAcBoomerang_c>Fv = .text:0x80265530; // type:function size:0x58 isSameName__29sFStateID_c<14dAcBoomerang_c>CFPCc = .text:0x80265590; // type:function size:0x88 -dAcObjFairy_c_classInit__Fv = .text:0x80265620; // type:function size:0x144 -__dt__26sFState_c<13dAcObjFairy_c>Fv = .text:0x80265770; // type:function size:0x58 -__dt__29sFStateFct_c<13dAcObjFairy_c>Fv = .text:0x802657D0; // type:function size:0x6C -__dt__82sStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80265840; // type:function size:0xA0 -__dt__52sFStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c>Fv = .text:0x802658E0; // type:function size:0xA4 -createHeap__13dAcObjFairy_cFv = .text:0x80265990; // type:function size:0x78 -create__13dAcObjFairy_cFv = .text:0x80265A10; // type:function size:0x478 -changeState__82sStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x80265E90; // type:function size:0x10 -doDelete__13dAcObjFairy_cFv = .text:0x80265EA0; // type:function size:0x78 -actorExecute__13dAcObjFairy_cFv = .text:0x80265F20; // type:function size:0x578 -getStateID__82sStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x802664A0; // type:function size:0x10 -executeState__82sStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x802664B0; // type:function size:0x10 -draw__13dAcObjFairy_cFv = .text:0x802664C0; // type:function size:0x10C -initializeState_Wait__13dAcObjFairy_cFv = .text:0x802665D0; // type:function size:0x64 -executeState_Wait__13dAcObjFairy_cFv = .text:0x80266640; // type:function size:0x38C -finalizeState_Wait__13dAcObjFairy_cFv = .text:0x802669D0; // type:function size:0x4 -initializeState_Avoid__13dAcObjFairy_cFv = .text:0x802669E0; // type:function size:0x178 -executeState_Avoid__13dAcObjFairy_cFv = .text:0x80266B60; // type:function size:0xE8 -finalizeState_Avoid__13dAcObjFairy_cFv = .text:0x80266C50; // type:function size:0x10 -initializeState_PlayerAvoid__13dAcObjFairy_cFv = .text:0x80266C60; // type:function size:0x50 -executeState_PlayerAvoid__13dAcObjFairy_cFv = .text:0x80266CB0; // type:function size:0x90 -finalizeState_PlayerAvoid__13dAcObjFairy_cFv = .text:0x80266D40; // type:function size:0x10 -initializeState_CureStart__13dAcObjFairy_cFv = .text:0x80266D50; // type:function size:0xFC -executeState_CureStart__13dAcObjFairy_cFv = .text:0x80266E50; // type:function size:0x1AC -finalizeState_CureStart__13dAcObjFairy_cFv = .text:0x80267000; // type:function size:0x4 -initializeState_Cure__13dAcObjFairy_cFv = .text:0x80267010; // type:function size:0xA0 -executeState_Cure__13dAcObjFairy_cFv = .text:0x802670B0; // type:function size:0x88 -finalizeState_Cure__13dAcObjFairy_cFv = .text:0x80267140; // type:function size:0x4 -initializeState_CureEnd__13dAcObjFairy_cFv = .text:0x80267150; // type:function size:0x4 -executeState_CureEnd__13dAcObjFairy_cFv = .text:0x80267160; // type:function size:0x68 -finalizeState_CureEnd__13dAcObjFairy_cFv = .text:0x802671D0; // type:function size:0x4 -initializeState_CatchDemo__13dAcObjFairy_cFv = .text:0x802671E0; // type:function size:0x88 -executeState_CatchDemo__13dAcObjFairy_cFv = .text:0x80267270; // type:function size:0x28 -finalizeState_CatchDemo__13dAcObjFairy_cFv = .text:0x802672A0; // type:function size:0x18 -shouldAvoidLink__13dAcObjFairy_cCFv = .text:0x802672C0; // type:function size:0xF0 -isCuring__13dAcObjFairy_cCFv = .text:0x802673B0; // type:function size:0x10C -canTargetWithBugNet__13dAcObjFairy_cCFv = .text:0x802674C0; // type:function size:0x74 -fn_80267540 = .text:0x80267540; // type:function size:0xA4 -fn_802675F0 = .text:0x802675F0; // type:function size:0x70 -fn_80267660 = .text:0x80267660; // type:function size:0x74 -fn_802676E0 = .text:0x802676E0; // type:function size:0x10C -fn_802677F0 = .text:0x802677F0; // type:function size:0x144 -fn_80267940 = .text:0x80267940; // type:function size:0xB0 -fn_802679F0 = .text:0x802679F0; // type:function size:0x158 -fn_80267B50 = .text:0x80267B50; // type:function size:0x2C -fn_80267B80 = .text:0x80267B80; // type:function size:0x6C -fn_80267BF0 = .text:0x80267BF0; // type:function size:0x60 -__dt__13dAcObjFairy_cFv = .text:0x80267C50; // type:function size:0x124 -build__29sFStateFct_c<13dAcObjFairy_c>FRC12sStateIDIf_c = .text:0x80267D80; // type:function size:0x60 -dispose__29sFStateFct_c<13dAcObjFairy_c>FRP10sStateIf_c = .text:0x80267DE0; // type:function size:0xC -initialize__26sFState_c<13dAcObjFairy_c>Fv = .text:0x80267DF0; // type:function size:0x1C -execute__26sFState_c<13dAcObjFairy_c>Fv = .text:0x80267E10; // type:function size:0x1C -finalize__26sFState_c<13dAcObjFairy_c>Fv = .text:0x80267E30; // type:function size:0x1C -initializeState__82sStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80267E50; // type:function size:0x10 -finalizeState__82sStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80267E60; // type:function size:0x10 -refreshState__82sStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80267E70; // type:function size:0x10 -getState__82sStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80267E80; // type:function size:0x10 -getNewStateID__82sStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80267E90; // type:function size:0x10 -getOldStateID__82sStateMgr_c<13dAcObjFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80267EA0; // type:function size:0x10 -finalizeState__28sFStateID_c<13dAcObjFairy_c>CFR13dAcObjFairy_c = .text:0x80267EB0; // type:function size:0x30 -executeState__28sFStateID_c<13dAcObjFairy_c>CFR13dAcObjFairy_c = .text:0x80267EE0; // type:function size:0x30 -initializeState__28sFStateID_c<13dAcObjFairy_c>CFR13dAcObjFairy_c = .text:0x80267F10; // type:function size:0x30 +dAcOFairy_c_classInit__Fv = .text:0x80265620; // type:function size:0x144 +__dt__24sFState_c<11dAcOFairy_c>Fv = .text:0x80265770; // type:function size:0x58 scope:weak +__dt__27sFStateFct_c<11dAcOFairy_c>Fv = .text:0x802657D0; // type:function size:0x6C scope:weak +__dt__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80265840; // type:function size:0xA0 scope:weak +__dt__50sFStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c>Fv = .text:0x802658E0; // type:function size:0xA4 scope:weak +createHeap__11dAcOFairy_cFv = .text:0x80265990; // type:function size:0x78 +create__11dAcOFairy_cFv = .text:0x80265A10; // type:function size:0x478 +changeState__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x80265E90; // type:function size:0x10 scope:weak +doDelete__11dAcOFairy_cFv = .text:0x80265EA0; // type:function size:0x78 +actorExecute__11dAcOFairy_cFv = .text:0x80265F20; // type:function size:0x578 +getStateID__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x802664A0; // type:function size:0x10 scope:weak +executeState__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x802664B0; // type:function size:0x10 scope:weak +draw__11dAcOFairy_cFv = .text:0x802664C0; // type:function size:0x10C +initializeState_Wait__11dAcOFairy_cFv = .text:0x802665D0; // type:function size:0x64 +executeState_Wait__11dAcOFairy_cFv = .text:0x80266640; // type:function size:0x38C +finalizeState_Wait__11dAcOFairy_cFv = .text:0x802669D0; // type:function size:0x4 +initializeState_Avoid__11dAcOFairy_cFv = .text:0x802669E0; // type:function size:0x178 +executeState_Avoid__11dAcOFairy_cFv = .text:0x80266B60; // type:function size:0xE8 +finalizeState_Avoid__11dAcOFairy_cFv = .text:0x80266C50; // type:function size:0x10 +initializeState_PlayerAvoid__11dAcOFairy_cFv = .text:0x80266C60; // type:function size:0x50 +executeState_PlayerAvoid__11dAcOFairy_cFv = .text:0x80266CB0; // type:function size:0x90 +finalizeState_PlayerAvoid__11dAcOFairy_cFv = .text:0x80266D40; // type:function size:0x10 +initializeState_CureStart__11dAcOFairy_cFv = .text:0x80266D50; // type:function size:0xFC +executeState_CureStart__11dAcOFairy_cFv = .text:0x80266E50; // type:function size:0x1AC +finalizeState_CureStart__11dAcOFairy_cFv = .text:0x80267000; // type:function size:0x4 +initializeState_Cure__11dAcOFairy_cFv = .text:0x80267010; // type:function size:0xA0 +executeState_Cure__11dAcOFairy_cFv = .text:0x802670B0; // type:function size:0x88 +finalizeState_Cure__11dAcOFairy_cFv = .text:0x80267140; // type:function size:0x4 +initializeState_CureEnd__11dAcOFairy_cFv = .text:0x80267150; // type:function size:0x4 +executeState_CureEnd__11dAcOFairy_cFv = .text:0x80267160; // type:function size:0x68 +finalizeState_CureEnd__11dAcOFairy_cFv = .text:0x802671D0; // type:function size:0x4 +initializeState_CatchDemo__11dAcOFairy_cFv = .text:0x802671E0; // type:function size:0x88 +executeState_CatchDemo__11dAcOFairy_cFv = .text:0x80267270; // type:function size:0x28 +finalizeState_CatchDemo__11dAcOFairy_cFv = .text:0x802672A0; // type:function size:0x18 +shouldAvoidBugNet__11dAcOFairy_cCFv = .text:0x802672C0; // type:function size:0xF0 +isCuring__11dAcOFairy_cCFv = .text:0x802673B0; // type:function size:0x10C +canTargetWithBugNet__11dAcOFairy_cCFv = .text:0x802674C0; // type:function size:0x74 +setSpawnPosition__11dAcOFairy_cFRC7mVec3_c = .text:0x80267540; // type:function size:0xA4 +setPosYWaveParams__11dAcOFairy_cFv = .text:0x802675F0; // type:function size:0x70 +rndTurnSpeed__11dAcOFairy_cCFv = .text:0x80267660; // type:function size:0x74 +calcInitialSpawnPosition__11dAcOFairy_cFv = .text:0x802676E0; // type:function size:0x10C +calcCurePosition__11dAcOFairy_cFRCfRCf = .text:0x802677F0; // type:function size:0x144 +calcPosYWave__11dAcOFairy_cFv = .text:0x80267940; // type:function size:0xB0 +executeCheckForWindOrBellows__11dAcOFairy_cFv = .text:0x802679F0; // type:function size:0x158 +randMaxSpeedY__11dAcOFairy_cCFv = .text:0x80267B50; // type:function size:0x2C +shouldAvoidLink__11dAcOFairy_cCFv = .text:0x80267B80; // type:function size:0x6C +isMovingAwayFromOrigY__11dAcOFairy_cCFv = .text:0x80267BF0; // type:function size:0x60 +__dt__11dAcOFairy_cFv = .text:0x80267C50; // type:function size:0x124 scope:weak +build__27sFStateFct_c<11dAcOFairy_c>FRC12sStateIDIf_c = .text:0x80267D80; // type:function size:0x60 scope:weak +dispose__27sFStateFct_c<11dAcOFairy_c>FRP10sStateIf_c = .text:0x80267DE0; // type:function size:0xC scope:weak +initialize__24sFState_c<11dAcOFairy_c>Fv = .text:0x80267DF0; // type:function size:0x1C scope:weak +execute__24sFState_c<11dAcOFairy_c>Fv = .text:0x80267E10; // type:function size:0x1C scope:weak +finalize__24sFState_c<11dAcOFairy_c>Fv = .text:0x80267E30; // type:function size:0x1C scope:weak +initializeState__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80267E50; // type:function size:0x10 scope:weak +finalizeState__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80267E60; // type:function size:0x10 scope:weak +refreshState__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80267E70; // type:function size:0x10 scope:weak +getState__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80267E80; // type:function size:0x10 scope:weak +getNewStateID__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80267E90; // type:function size:0x10 scope:weak +getOldStateID__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80267EA0; // type:function size:0x10 scope:weak +finalizeState__26sFStateID_c<11dAcOFairy_c>CFR11dAcOFairy_c = .text:0x80267EB0; // type:function size:0x30 scope:weak +executeState__26sFStateID_c<11dAcOFairy_c>CFR11dAcOFairy_c = .text:0x80267EE0; // type:function size:0x30 scope:weak +initializeState__26sFStateID_c<11dAcOFairy_c>CFR11dAcOFairy_c = .text:0x80267F10; // type:function size:0x30 scope:weak __sinit_\d_a_obj_fairy_cpp = .text:0x80267F40; // type:function size:0x56C scope:local -__dt__28sFStateID_c<13dAcObjFairy_c>Fv = .text:0x802684B0; // type:function size:0x58 -isSameName__28sFStateID_c<13dAcObjFairy_c>CFPCc = .text:0x80268510; // type:function size:0x88 +__dt__26sFStateID_c<11dAcOFairy_c>Fv = .text:0x802684B0; // type:function size:0x58 scope:weak +isSameName__26sFStateID_c<11dAcOFairy_c>CFPCc = .text:0x80268510; // type:function size:0x88 scope:weak dAcTbox_c_classInit__Fv = .text:0x802685A0; // type:function size:0x30 tryGetDowsingTargetOffset__9dAcTbox_cFiR7mVec3_c = .text:0x802685D0; // type:function size:0x68 getDowsingTargetOffset__9dAcTbox_cFiR7mVec3_c = .text:0x80268640; // type:function size:0x4 @@ -17279,9 +17279,9 @@ cLib__chasePosXZ = .text:0x802E0550; // type:function size:0x124 targetAngleY__4cLibFRC7mVec3_cRC7mVec3_c = .text:0x802E0680; // type:function size:0x1C targetAngleX__4cLibFRC7mVec3_cRC7mVec3_c = .text:0x802E06A0; // type:function size:0x68 cLib__offsetPos = .text:0x802E0710; // type:function size:0xD8 -fn_802E07F0 = .text:0x802E07F0; // type:function size:0x24 +easeIn__4cLibFff = .text:0x802E07F0; // type:function size:0x24 easeOut__4cLibFff = .text:0x802E0820; // type:function size:0x34 -fn_802E0860 = .text:0x802E0860; // type:function size:0x60 +easeInOut__4cLibFff = .text:0x802E0860; // type:function size:0x60 insertAfter__9cListMg_cFP9cListNd_cP9cListNd_c = .text:0x802E08C0; // type:function size:0x40 remove__9cListMg_cFP9cListNd_c = .text:0x802E0900; // type:function size:0xAC append__9cListMg_cFP9cListNd_c = .text:0x802E09B0; // type:function size:0x30 @@ -36091,16 +36091,48 @@ __vt__30sFStateFct_c<14dAcBoomerang_c> = .data:0x80534C40; // type:object size:0 __vt__27sFState_c<14dAcBoomerang_c> = .data:0x80534C58; // type:object size:0x18 __vt__18dAcBoomerangProc_c = .data:0x80534C70; // type:object size:0x1D0 lbl_80534E40 = .data:0x80534E40; // type:object size:0x38 -g_profile_OBJ_FAIRY = .data:0x80534E78; // type:object size:0x68 -lbl_80534EE0 = .data:0x80534EE0; // type:object size:0x30 -lbl_80534F10 = .data:0x80534F10; // type:object size:0xC -lbl_80534F1C = .data:0x80534F1C; // type:object size:0x2C -__vt__13dAcObjFairy_c = .data:0x80534F48; // type:object size:0x80 -lbl_80534FC8 = .data:0x80534FC8; // type:object size:0x30 -lbl_80534FF8 = .data:0x80534FF8; // type:object size:0x30 -lbl_80535028 = .data:0x80535028; // type:object size:0x18 -lbl_80535040 = .data:0x80535040; // type:object size:0x1F8 -__vt__28sFStateID_c<13dAcObjFairy_c> = .data:0x80535238; // type:object size:0x38 +g_profile_OBJ_FAIRY = .data:0x80534E78; // type:object size:0x10 +...data.0 = .data:0x80534E78; // type:label scope:local +sSphSrc1 = .data:0x80534E88; // type:object size:0x2C scope:local +sSphSrc2 = .data:0x80534EB4; // type:object size:0x2C scope:local +sAttnTarget = .data:0x80534EE0; // type:object size:0x30 scope:local +@27475 = .data:0x80534F10; // type:object size:0x9 scope:local data:string +@27476 = .data:0x80534F1C; // type:object size:0xD scope:local data:string +@27563 = .data:0x80534F2C; // type:object size:0x19 scope:local data:string +__vt__11dAcOFairy_c = .data:0x80534F48; // type:object size:0x80 +__vt__50sFStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c> = .data:0x80534FC8; // type:object size:0x30 scope:weak +__vt__80sStateMgr_c<11dAcOFairy_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x80534FF8; // type:object size:0x30 scope:weak +__vt__27sFStateFct_c<11dAcOFairy_c> = .data:0x80535028; // type:object size:0x14 scope:weak +__vt__24sFState_c<11dAcOFairy_c> = .data:0x80535040; // type:object size:0x18 scope:weak +@28233 = .data:0x80535064; // type:object size:0xC scope:local +@28234 = .data:0x80535070; // type:object size:0xC scope:local +@28235 = .data:0x8053507C; // type:object size:0xC scope:local +@28236 = .data:0x80535088; // type:object size:0xC scope:local +@28237 = .data:0x80535094; // type:object size:0xC scope:local +@28238 = .data:0x805350A0; // type:object size:0xC scope:local +@28239 = .data:0x805350AC; // type:object size:0xC scope:local +@28240 = .data:0x805350B8; // type:object size:0xC scope:local +@28241 = .data:0x805350C4; // type:object size:0xC scope:local +@28242 = .data:0x805350D0; // type:object size:0xC scope:local +@28243 = .data:0x805350DC; // type:object size:0xC scope:local +@28244 = .data:0x805350E8; // type:object size:0xC scope:local +@28245 = .data:0x805350F4; // type:object size:0xC scope:local +@28246 = .data:0x80535100; // type:object size:0xC scope:local +@28247 = .data:0x8053510C; // type:object size:0xC scope:local +@28248 = .data:0x80535118; // type:object size:0xC scope:local +@28249 = .data:0x80535124; // type:object size:0xC scope:local +@28250 = .data:0x80535130; // type:object size:0xC scope:local +@28251 = .data:0x8053513C; // type:object size:0xC scope:local +@28252 = .data:0x80535148; // type:object size:0xC scope:local +@28253 = .data:0x80535154; // type:object size:0xC scope:local +@28255 = .data:0x80535160; // type:object size:0x1A scope:local data:string +@28256 = .data:0x8053517C; // type:object size:0x1B scope:local data:string +@28257 = .data:0x80535198; // type:object size:0x21 scope:local data:string +@28258 = .data:0x805351BC; // type:object size:0x1F scope:local data:string +@28259 = .data:0x805351DC; // type:object size:0x1A scope:local data:string +@28260 = .data:0x805351F8; // type:object size:0x1D scope:local data:string +@28261 = .data:0x80535218; // type:object size:0x1F scope:local data:string +__vt__26sFStateID_c<11dAcOFairy_c> = .data:0x80535238; // type:object size:0x34 scope:weak g_profile_TBOX = .data:0x80535270; // type:object size:0x10 lbl_80535280 = .data:0x80535280; // type:object size:0xC data:string lbl_8053528C = .data:0x8053528C; // type:object size:0xC @@ -40782,12 +40814,12 @@ lbl_80573A20 = .sdata:0x80573A20; // type:object size:0x4 data:4byte lbl_80573A24 = .sdata:0x80573A24; // type:object size:0x4 data:4byte lbl_80573A28 = .sdata:0x80573A28; // type:object size:0x4 data:4byte lbl_80573A2C = .sdata:0x80573A2C; // type:object size:0x4 data:4byte -lbl_80573A30 = .sdata:0x80573A30; // type:object size:0x4 align:4 data:float -lbl_80573A34 = .sdata:0x80573A34; // type:object size:0x4 -lbl_80573A38 = .sdata:0x80573A38; // type:object size:0x4 -lbl_80573A3C = .sdata:0x80573A3C; // type:object size:0x4 -lbl_80573A40 = .sdata:0x80573A40; // type:object size:0x4 -lbl_80573A44 = .sdata:0x80573A44; // type:object size:0x4 data:4byte +@26080 = .sdata:0x80573A30; // type:object size:0x4 scope:local align:4 data:float +@26123 = .sdata:0x80573A34; // type:object size:0x4 scope:local +@26124 = .sdata:0x80573A38; // type:object size:0x4 scope:local +@26150 = .sdata:0x80573A3C; // type:object size:0x4 scope:local +@26167 = .sdata:0x80573A40; // type:object size:0x4 scope:local +@26240 = .sdata:0x80573A44; // type:object size:0x4 scope:local data:4byte lbl_80573A48 = .sdata:0x80573A48; // type:object size:0x8 lbl_80573A50 = .sdata:0x80573A50; // type:object size:0x4 lbl_80573A54 = .sdata:0x80573A54; // type:object size:0x4 @@ -42135,7 +42167,7 @@ lbl_805758F0 = .sbss:0x805758F0; // type:object size:0x2 data:2byte lbl_805758F4 = .sbss:0x805758F4; // type:object size:0x1 data:byte lbl_805758F8 = .sbss:0x805758F8; // type:object size:0x8 data:byte lbl_80575900 = .sbss:0x80575900; // type:object size:0x8 data:byte -@GUARD@draw__13dAcObjFairy_cFv@rot = .sbss:0x80575908; // type:object size:0x8 data:byte +@GUARD@draw__11dAcOFairy_cFv@rot = .sbss:0x80575908; // type:object size:0x1 scope:local data:byte sTboxActorList__9dAcTbox_c = .sbss:0x80575910; // type:object size:0x8 data:4byte sCurrentObtainingItemOarcName = .sbss:0x80575918; // type:object size:0x4 data:4byte @GUARD@create__9dAcTbox_cFv@s1 = .sbss:0x8057591C; // type:object size:0x1 data:byte @@ -47798,48 +47830,48 @@ lbl_8057C170 = .sdata2:0x8057C170; // type:object size:0x4 align:4 data:float lbl_8057C174 = .sdata2:0x8057C174; // type:object size:0x4 align:4 data:float lbl_8057C178 = .sdata2:0x8057C178; // type:object size:0x4 align:4 data:float lbl_8057C17C = .sdata2:0x8057C17C; // type:object size:0x4 align:4 data:float -lbl_8057C180 = .sdata2:0x8057C180; // type:object size:0x4 align:4 data:float -lbl_8057C184 = .sdata2:0x8057C184; // type:object size:0x4 align:4 data:float -lbl_8057C188 = .sdata2:0x8057C188; // type:object size:0x4 align:4 data:float -lbl_8057C18C = .sdata2:0x8057C18C; // type:object size:0x4 align:4 data:float -lbl_8057C190 = .sdata2:0x8057C190; // type:object size:0x4 align:4 data:float -lbl_8057C194 = .sdata2:0x8057C194; // type:object size:0x4 align:4 data:float -lbl_8057C198 = .sdata2:0x8057C198; // type:object size:0x4 align:4 data:float -lbl_8057C19C = .sdata2:0x8057C19C; // type:object size:0x4 align:4 data:float -lbl_8057C1A0 = .sdata2:0x8057C1A0; // type:object size:0x4 align:4 data:float -lbl_8057C1A4 = .sdata2:0x8057C1A4; // type:object size:0x4 align:4 data:float -lbl_8057C1A8 = .sdata2:0x8057C1A8; // type:object size:0x4 align:4 data:float -lbl_8057C1B0 = .sdata2:0x8057C1B0; // type:object size:0x8 align:8 data:double -lbl_8057C1B8 = .sdata2:0x8057C1B8; // type:object size:0x4 align:4 data:float -lbl_8057C1BC = .sdata2:0x8057C1BC; // type:object size:0x4 align:4 data:float -lbl_8057C1C0 = .sdata2:0x8057C1C0; // type:object size:0x4 align:4 data:float -lbl_8057C1C8 = .sdata2:0x8057C1C8; // type:object size:0x8 align:8 data:double -lbl_8057C1D0 = .sdata2:0x8057C1D0; // type:object size:0x4 align:4 data:float -lbl_8057C1D4 = .sdata2:0x8057C1D4; // type:object size:0x4 align:4 data:float -lbl_8057C1D8 = .sdata2:0x8057C1D8; // type:object size:0x4 align:4 data:float -lbl_8057C1DC = .sdata2:0x8057C1DC; // type:object size:0x4 align:4 data:float -lbl_8057C1E0 = .sdata2:0x8057C1E0; // type:object size:0x4 align:4 data:float -lbl_8057C1E4 = .sdata2:0x8057C1E4; // type:object size:0x4 align:4 data:float -lbl_8057C1E8 = .sdata2:0x8057C1E8; // type:object size:0x4 align:4 data:float -lbl_8057C1EC = .sdata2:0x8057C1EC; // type:object size:0x4 align:4 data:float -lbl_8057C1F0 = .sdata2:0x8057C1F0; // type:object size:0x4 align:4 data:float -lbl_8057C1F4 = .sdata2:0x8057C1F4; // type:object size:0x4 align:4 data:float -lbl_8057C1F8 = .sdata2:0x8057C1F8; // type:object size:0x4 align:4 data:float -lbl_8057C1FC = .sdata2:0x8057C1FC; // type:object size:0x4 align:4 data:float -lbl_8057C200 = .sdata2:0x8057C200; // type:object size:0x4 align:4 data:float -lbl_8057C204 = .sdata2:0x8057C204; // type:object size:0x4 align:4 data:float -lbl_8057C208 = .sdata2:0x8057C208; // type:object size:0x4 align:4 data:float -lbl_8057C20C = .sdata2:0x8057C20C; // type:object size:0x4 align:4 data:float -lbl_8057C210 = .sdata2:0x8057C210; // type:object size:0x4 align:4 data:float -lbl_8057C214 = .sdata2:0x8057C214; // type:object size:0x4 align:4 data:float -lbl_8057C218 = .sdata2:0x8057C218; // type:object size:0x4 align:4 data:float -lbl_8057C21C = .sdata2:0x8057C21C; // type:object size:0x4 align:4 data:float -lbl_8057C220 = .sdata2:0x8057C220; // type:object size:0x4 align:4 data:float -lbl_8057C224 = .sdata2:0x8057C224; // type:object size:0x4 align:4 data:float -lbl_8057C228 = .sdata2:0x8057C228; // type:object size:0x4 align:4 data:float -lbl_8057C22C = .sdata2:0x8057C22C; // type:object size:0x4 align:4 data:float -lbl_8057C230 = .sdata2:0x8057C230; // type:object size:0x4 align:4 data:float -lbl_8057C234 = .sdata2:0x8057C234; // type:object size:0x4 align:4 data:float +@27564 = .sdata2:0x8057C180; // type:object size:0x4 scope:local align:4 data:float +@27565 = .sdata2:0x8057C184; // type:object size:0x4 scope:local align:4 data:float +@27566 = .sdata2:0x8057C188; // type:object size:0x4 scope:local align:4 data:float +@27567 = .sdata2:0x8057C18C; // type:object size:0x4 scope:local align:4 data:float +@27568 = .sdata2:0x8057C190; // type:object size:0x4 scope:local align:4 data:float +@27569 = .sdata2:0x8057C194; // type:object size:0x4 scope:local align:4 data:float +@27570 = .sdata2:0x8057C198; // type:object size:0x4 scope:local align:4 data:float +@27571 = .sdata2:0x8057C19C; // type:object size:0x4 scope:local align:4 data:float +@27572 = .sdata2:0x8057C1A0; // type:object size:0x4 scope:local align:4 data:float +@27573 = .sdata2:0x8057C1A4; // type:object size:0x4 scope:local align:4 data:float +@27574 = .sdata2:0x8057C1A8; // type:object size:0x4 scope:local align:4 data:float +@27577 = .sdata2:0x8057C1B0; // type:object size:0x8 scope:local align:8 data:double +@27682 = .sdata2:0x8057C1B8; // type:object size:0x4 scope:local align:4 data:float +@27683 = .sdata2:0x8057C1BC; // type:object size:0x4 scope:local align:4 data:float +@27684 = .sdata2:0x8057C1C0; // type:object size:0x4 scope:local align:4 data:float +@27687 = .sdata2:0x8057C1C8; // type:object size:0x8 scope:local align:8 data:double +@27804 = .sdata2:0x8057C1D0; // type:object size:0x4 scope:local align:4 data:float +@27805 = .sdata2:0x8057C1D4; // type:object size:0x4 scope:local align:4 data:float +@27806 = .sdata2:0x8057C1D8; // type:object size:0x4 scope:local align:4 data:float +@27807 = .sdata2:0x8057C1DC; // type:object size:0x4 scope:local align:4 data:float +@27808 = .sdata2:0x8057C1E0; // type:object size:0x4 scope:local align:4 data:float +@27809 = .sdata2:0x8057C1E4; // type:object size:0x4 scope:local align:4 data:float +@27810 = .sdata2:0x8057C1E8; // type:object size:0x4 scope:local align:4 data:float +@27811 = .sdata2:0x8057C1EC; // type:object size:0x4 scope:local align:4 data:float +@27812 = .sdata2:0x8057C1F0; // type:object size:0x4 scope:local align:4 data:float +@27813 = .sdata2:0x8057C1F4; // type:object size:0x4 scope:local align:4 data:float +@27814 = .sdata2:0x8057C1F8; // type:object size:0x4 scope:local align:4 data:float +@27815 = .sdata2:0x8057C1FC; // type:object size:0x4 scope:local align:4 data:float +@27846 = .sdata2:0x8057C200; // type:object size:0x4 scope:local align:4 data:float +@27921 = .sdata2:0x8057C204; // type:object size:0x4 scope:local align:4 data:float +@27945 = .sdata2:0x8057C208; // type:object size:0x4 scope:local align:4 data:float +@27946 = .sdata2:0x8057C20C; // type:object size:0x4 scope:local align:4 data:float +@27947 = .sdata2:0x8057C210; // type:object size:0x4 scope:local align:4 data:float +@27948 = .sdata2:0x8057C214; // type:object size:0x4 scope:local align:4 data:float +@27959 = .sdata2:0x8057C218; // type:object size:0x4 scope:local align:4 data:float +@27960 = .sdata2:0x8057C21C; // type:object size:0x4 scope:local align:4 data:float +@27969 = .sdata2:0x8057C220; // type:object size:0x4 scope:local align:4 data:float +@27975 = .sdata2:0x8057C224; // type:object size:0x4 scope:local align:4 data:float +@28054 = .sdata2:0x8057C228; // type:object size:0x4 scope:local align:4 data:float +@28055 = .sdata2:0x8057C22C; // type:object size:0x4 scope:local align:4 data:float +@28158 = .sdata2:0x8057C230; // type:object size:0x4 scope:local align:4 data:float +@28159 = .sdata2:0x8057C234; // type:object size:0x4 scope:local align:4 data:float lbl_8057C238 = .sdata2:0x8057C238; // type:object size:0x4 data:4byte lbl_8057C23C = .sdata2:0x8057C23C; // type:object size:0x4 data:4byte lbl_8057C240 = .sdata2:0x8057C240; // type:object size:0x4 data:4byte @@ -51876,15 +51908,22 @@ StateID_Move__14dAcBoomerang_c = .bss:0x805B4CD8; // type:object size:0x40 data: StateID_MoveCancelWait__14dAcBoomerang_c = .bss:0x805B4D18; // type:object size:0x40 data:4byte StateID_ReturnWait__14dAcBoomerang_c = .bss:0x805B4D58; // type:object size:0x40 data:4byte StateID_EventReturnWait__14dAcBoomerang_c = .bss:0x805B4D98; // type:object size:0x40 data:4byte -lbl_805B4DD8 = .bss:0x805B4DD8; // type:object size:0x10 -AcFairy__STATE_WAIT = .bss:0x805B4DE8; // type:object size:0x40 data:4byte -AcFairy__STATE_AVOID = .bss:0x805B4E28; // type:object size:0x40 data:4byte -AcFairy__STATE_PLAYER_AVOID = .bss:0x805B4E68; // type:object size:0x40 data:4byte -AcFairy__STATE_CURE_START = .bss:0x805B4EA8; // type:object size:0x40 data:4byte -AcFairy__STATE_CURE = .bss:0x805B4EE8; // type:object size:0x40 data:4byte -AcFairy__STATE_CURE_END = .bss:0x805B4F28; // type:object size:0x40 data:4byte -StateID_CatchDemo__13dAcObjFairy_c = .bss:0x805B4F68; // type:object size:0x30 data:4byte -@LOCAL@draw__13dAcObjFairy_cFv@rot = .bss:0x805B4F98; // type:object size:0x10 align:4 data:4byte +@25786 = .bss:0x805B4DD8; // type:object size:0xC scope:local +...bss.0 = .bss:0x805B4DD8; // type:label scope:local +StateID_Wait__11dAcOFairy_c = .bss:0x805B4DE8; // type:object size:0x30 data:4byte +@25790 = .bss:0x805B4E18; // type:object size:0xC scope:local +StateID_Avoid__11dAcOFairy_c = .bss:0x805B4E28; // type:object size:0x30 data:4byte +@25794 = .bss:0x805B4E58; // type:object size:0xC scope:local +StateID_PlayerAvoid__11dAcOFairy_c = .bss:0x805B4E68; // type:object size:0x30 data:4byte +@25798 = .bss:0x805B4E98; // type:object size:0xC scope:local +StateID_CureStart__11dAcOFairy_c = .bss:0x805B4EA8; // type:object size:0x30 data:4byte +@25802 = .bss:0x805B4ED8; // type:object size:0xC scope:local +StateID_Cure__11dAcOFairy_c = .bss:0x805B4EE8; // type:object size:0x30 data:4byte +@25806 = .bss:0x805B4F18; // type:object size:0xC scope:local +StateID_CureEnd__11dAcOFairy_c = .bss:0x805B4F28; // type:object size:0x30 data:4byte +@25810 = .bss:0x805B4F58; // type:object size:0xC scope:local +StateID_CatchDemo__11dAcOFairy_c = .bss:0x805B4F68; // type:object size:0x30 data:4byte +@LOCAL@draw__11dAcOFairy_cFv@rot = .bss:0x805B4F98; // type:object size:0x10 scope:local align:4 data:4byte lbl_805B4FA8 = .bss:0x805B4FA8; // type:object size:0x30 align:4 data:float lbl_805B4FD8 = .bss:0x805B4FD8; // type:object size:0xC align:4 data:float lbl_805B4FE4 = .bss:0x805B4FE4; // type:object size:0xC align:4 data:float diff --git a/configure.py b/configure.py index e6315bf0..77fdc8ff 100644 --- a/configure.py +++ b/configure.py @@ -609,7 +609,7 @@ config.libs = [ Object(NonMatching, "d/a/obj/d_a_obj_bomb.cpp"), Object(NonMatching, "d/a/obj/d_a_obj_arrow.cpp"), Object(NonMatching, "d/a/obj/d_a_obj_boomerang.cpp"), - Object(NonMatching, "d/a/obj/d_a_obj_fairy.cpp"), + Object(Matching, "d/a/obj/d_a_obj_fairy.cpp"), Object(NonMatching, "d/a/obj/d_a_obj_tbox.cpp"), Object(NonMatching, "d/a/obj/d_a_obj_time_area.cpp"), Object(Matching, "d/a/obj/d_a_obj_switch.cpp"), diff --git a/include/c/c_lib.h b/include/c/c_lib.h index 46f809a1..6cba820d 100644 --- a/include/c/c_lib.h +++ b/include/c/c_lib.h @@ -13,7 +13,9 @@ f32 addCalcPosXZ(mVec3_c *src, const mVec3_c &target, f32 scale, f32 maxStep, f3 f32 addCalcPos(mVec3_c *src, const mVec3_c &target, f32 scale, f32 maxStep, f32 minStep); // made up name +f32 easeIn(f32 value, f32 exponent); f32 easeOut(f32 value, f32 exponent); +f32 easeInOut(f32 value, f32 exponent); } // namespace cLib diff --git a/include/d/a/d_a_base.h b/include/d/a/d_a_base.h index df04f53c..9c0c85cb 100644 --- a/include/d/a/d_a_base.h +++ b/include/d/a/d_a_base.h @@ -203,7 +203,7 @@ public: static dAcBase_c *searchActor(dAcBase_c *parent); // Kinda performs the code of the first param on every actor (second param is optional parent) static void forEveryActor(void *func(dAcBase_c *, dAcBase_c *), dAcBase_c *parent); - mAng getXZAngleToPlayer(); + mAng getXZAngleToPlayer() const; // returns true if under the distThresh, False if not. the actual distance is returned in outDist bool getDistanceToActor(dAcBase_c *actor, f32 distThresh, f32 *outDist); // same concept as above diff --git a/include/d/a/d_a_item.h b/include/d/a/d_a_item.h index afcbbb28..e0a6ae91 100644 --- a/include/d/a/d_a_item.h +++ b/include/d/a/d_a_item.h @@ -86,6 +86,8 @@ public: static void addRupees(s32 amount); + static bool hasAnyFairy(); + enum Trial_e { TRIAL_SKYLOFT, TRIAL_FARON, diff --git a/include/d/a/obj/d_a_obj_fairy.h b/include/d/a/obj/d_a_obj_fairy.h index 4340372a..e9283b46 100644 --- a/include/d/a/obj/d_a_obj_fairy.h +++ b/include/d/a/obj/d_a_obj_fairy.h @@ -2,15 +2,20 @@ #define D_A_OBJ_FAIRY_H #include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_s_acch.h" +#include "d/col/cc/d_cc_d.h" +#include "d/d_shadow.h" #include "m/m3d/m_anmmdl.h" -#include "m/m3d/m_shadow.h" +#include "m/m_angle.h" +#include "m/m_mtx.h" +#include "m/m_vec.h" #include "s/s_State.hpp" -#include "s/s_StateMgr.hpp" +#include "toBeSorted/d_emitter.h" -class dAcObjFairy_c : public dAcObjBase_c { +class dAcOFairy_c : public dAcObjBase_c { public: - dAcObjFairy_c() : mStateMgr(*this, sStateID::null) {} - virtual ~dAcObjFairy_c() {} + dAcOFairy_c() : field_0x330(0), mStateMgr(*this, sStateID::null) {} + virtual ~dAcOFairy_c() {} virtual bool createHeap() override; virtual int create() override; @@ -18,30 +23,82 @@ public: virtual int actorExecute() override; virtual int draw() override; - STATE_FUNC_DECLARE(dAcObjFairy_c, Wait); - STATE_FUNC_DECLARE(dAcObjFairy_c, Avoid); - STATE_FUNC_DECLARE(dAcObjFairy_c, PlayerAvoid); - STATE_FUNC_DECLARE(dAcObjFairy_c, CureStart); - STATE_FUNC_DECLARE(dAcObjFairy_c, Cure); - STATE_FUNC_DECLARE(dAcObjFairy_c, CureEnd); - STATE_FUNC_DECLARE(dAcObjFairy_c, CatchDemo); + STATE_FUNC_DECLARE(dAcOFairy_c, Wait); + STATE_FUNC_DECLARE(dAcOFairy_c, Avoid); + STATE_FUNC_DECLARE(dAcOFairy_c, PlayerAvoid); + STATE_FUNC_DECLARE(dAcOFairy_c, CureStart); + STATE_FUNC_DECLARE(dAcOFairy_c, Cure); + STATE_FUNC_DECLARE(dAcOFairy_c, CureEnd); + STATE_FUNC_DECLARE(dAcOFairy_c, CatchDemo); private: - bool shouldAvoidLink() const; + enum SpawnType_e { + SPAWN_0, + SPAWN_1, + /** The player released the fairy from a bottle or the bug net */ + SPAWN_MANUAL_RELEASE, + /** The previously bottled fairy saves the player from death */ + SPAWN_AUTO_RELEASE, + }; + + bool shouldAvoidBugNet() const; bool isCuring() const; bool canTargetWithBugNet() const; + bool shouldAvoidLink() const; + bool isMovingAwayFromOrigY() const; - /* 0x330 */ UNKWORD field_0x330; + mVec3_c calcInitialSpawnPosition(); + void setSpawnPosition(const mVec3_c &); + + void calcCurePosition(const f32 &xzOffsetTarget, const f32 &yOffsetTarget); + bool calcPosYWave(); + void setPosYWaveParams(); + + void executeCheckForWindOrBellows(); + + f32 randMaxSpeedY() const; + mAng rndTurnSpeed() const; + + /* 0x330 */ UNKWORD field_0x330; // might be a nw4r::g3d::ResFile /* 0x334 */ m3d::mdlAnmChr mModel; - /* 0x39C */ m3d::mShadowCircle_c mShadow; - /* 0x3A4 */ u8 field_0x3A4[0x4B0 - 0x3A4]; - /* 0x4B0 */ f32 field_0x4B0; - /* 0x4B4 */ u8 field_0x4B4[0xA50 - 0x4B4]; - /* 0xA50 */ STATE_MGR_DECLARE(dAcObjFairy_c); - /* 0xA8C */ u8 field_0xA8C[0xB89 - 0xA8C]; - /* 0xB89 */ u8 field_0xB89; - - // TODO collision, effects + /* 0x39C */ dShadowCircle_c mShadow; + /* 0x3A4 */ dBgS_AcchCir mAcchCir; + /* 0x400 */ dBgS_ObjAcch mObjAcch; + /* 0x7B0 */ dCcD_Sph mCcSph1; + /* 0x900 */ dCcD_Sph mCcSph2; + /* 0xA50 */ STATE_MGR_DECLARE(dAcOFairy_c); + /* 0xA8C */ EffectsStruct mEffects[2]; + /* 0xAF4 */ mVec3_c mOrigPosition; ///< The original position of the actor around which it is moving + /* 0xB00 */ mVec3_c mSpawnPosition; ///< The (slightly randomized) spawn position + /* 0xB0C */ u8 _0xB0C[0xB18 - 0xB0C]; + /* 0xB18 */ mVec3_c mCurePosition; ///< When curing the player, holds the calculated + ///< position that is applied in actorExecute + /* 0xB24 */ mMtx_c field_0xB24; + /* 0xB54 */ mAng mPosYWaveTime; + /* 0xB56 */ mAng mPosYWaveSpeed; + /* 0xB58 */ mAng mTurnSpeedY; + /* 0xB5A */ mAng mCureAngle; ///< When curing the player, holds the angle on the + ///< circular path around the player + /* 0xB5C */ mAng mCureAngularSpeed; ///< When curing the player, holds the speed with which + ///< the fairy is circling around the player + /* 0xB60 */ u32 mPosYWaveAmplitude; + /* 0xB64 */ f32 mMaxSpeedY; + /* 0xB68 */ f32 targetSpeedY; + /* 0xB6C */ f32 mOriginalGndHeight; + /* 0xB70 */ f32 mCurePosXZOffset; + /* 0xB74 */ f32 mCurePosXZOffsetTarget; + /* 0xB78 */ f32 mCurePosYOffset; + /* 0xB7C */ f32 mAutoReleaseProgress; + /* 0xB80 */ u8 mSpawnType; + /* 0xB81 */ u8 field_0xB81; + /* 0xB82 */ u8 mPreventAvoidTimer; + /* 0xB83 */ u8 mAvoidTimer; + /* 0xB84 */ u8 mPreventCatchAfterSpawnTimer; + /* 0xB85 */ bool mHasSetTurnSpeedY; + /* 0xB86 */ bool field_0xB86; + /* 0xB87 */ u8 _0xB87; + /* 0xB88 */ bool field_0xB88; + /* 0xB89 */ bool field_0xB89; }; #endif diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index 4eb90964..b06ba8fa 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -4,6 +4,7 @@ #include "d/d_player_base.h" class dAcEnBase_c; +class dAcOFairy_c; // Does this one have a vtable? // Name unknown @@ -432,7 +433,7 @@ public: /* vt 0x2D4 */ virtual bool isBottleOut() { return false; } - /* vt 0x2D8 */ virtual bool isUsingBottle() { + /* vt 0x2D8 */ virtual bool isUsingBottle() const { return false; } /* vt 0x2DC */ virtual f32 getShieldRegenProgressMaybe() { @@ -629,6 +630,7 @@ public: bool someTargetedActorCheck() const; static mAng fn_8005BA90(); static mAng fn_8005BAA0(); + static void fairyHeal(dAcOFairy_c *fairy); static void updateCurrentSword(); static bool isOutOfStamina(); diff --git a/include/d/t/d_t_fairytag.h b/include/d/t/d_t_fairytag.h index f7793569..a4c9fd8a 100644 --- a/include/d/t/d_t_fairytag.h +++ b/include/d/t/d_t_fairytag.h @@ -20,7 +20,7 @@ private: mVec3_c calcLocation(const f32 &); f32 calcRnd(const f32 &, const f32 &); - dAcRef_c *mpFairyRefs; + dAcRef_c *mpFairyRefs; s32 mCount; }; diff --git a/include/m/m_angle.h b/include/m/m_angle.h index 6eddfc96..1ef491a7 100644 --- a/include/m/m_angle.h +++ b/include/m/m_angle.h @@ -56,6 +56,10 @@ struct mAng { mVal *= other; return *this; } + mAng &operator*=(const f32 &other) { + mVal *= other; + return *this; + } static s32 abs(const mAng b) { return labs(b); diff --git a/include/m/m_vec.h b/include/m/m_vec.h index 7f5fa836..852ba68b 100644 --- a/include/m/m_vec.h +++ b/include/m/m_vec.h @@ -218,7 +218,7 @@ public: static mVec3_c createProjectionXZ(const mAng3_c &ang, f32 scalar); inline f32 mag() const { - return PSVECMag(*this); + return VECMag(*this); } f32 distance(const mVec3_c &to) const { @@ -259,13 +259,20 @@ public: f32 absXZ() const { return EGG::Math::sqrt(squareMagXZ()); } + f32 absXZTo(const mVec3_c &other) const { + return EGG::Math::sqrt(squareDistanceToXZ(other)); + } s16 atan2sX_Z() const { return cM::atan2s(x, z); } - s16 atan2sY_XZ() const { + s16 atan2snY_XZ() const { return cM::atan2s(-y, absXZ()); } + s16 atan2sY_XZ() const { + return cM::atan2s(y, absXZ()); + } + f32 angle(const mVec3_c &other) const { return EGG::Vector3f::angle(other); } diff --git a/include/toBeSorted/attention.h b/include/toBeSorted/attention.h index 45a59c8c..7ba3534e 100644 --- a/include/toBeSorted/attention.h +++ b/include/toBeSorted/attention.h @@ -53,6 +53,8 @@ enum InteractionType { UNK_18, SIT, UNK_20, + + UNK_0x58 = 0x58, }; class AttentionInfo { diff --git a/src/REL/d/t/d_t_fairytag.cpp b/src/REL/d/t/d_t_fairytag.cpp index 68664d1c..bc4ad6a5 100644 --- a/src/REL/d/t/d_t_fairytag.cpp +++ b/src/REL/d/t/d_t_fairytag.cpp @@ -5,7 +5,7 @@ SPECIAL_ACTOR_PROFILE(T_FAIRY, dTgFairy_c, fProfile::T_FAIRY, 0x0296, 0, 0); bool dTgFairy_c::createHeap() { - mpFairyRefs = new dAcRef_c[mCount](); + mpFairyRefs = new dAcRef_c[mCount](); return static_cast(mpFairyRefs); } @@ -52,7 +52,7 @@ void dTgFairy_c::createFairies() { mVec3_c v2; mVec3_c v = calcLocation(f); v2 = v; - dAcObjFairy_c *ac = static_cast( + dAcOFairy_c *ac = static_cast( dAcObjBase_c::create("Fairy", mRoomID, fairyParams1, &v2, nullptr, nullptr, -1, -1, mViewClipIdx) ); if (ac != nullptr) { diff --git a/src/d/a/d_a_base.cpp b/src/d/a/d_a_base.cpp index bcb71dc5..ffe8a66b 100644 --- a/src/d/a/d_a_base.cpp +++ b/src/d/a/d_a_base.cpp @@ -381,7 +381,7 @@ void dAcBase_c::forEveryActor(void *func(dAcBase_c *, dAcBase_c *), dAcBase_c *p } } -mAng dAcBase_c::getXZAngleToPlayer() { +mAng dAcBase_c::getXZAngleToPlayer() const { return cLib::targetAngleY(this->mPosition, dAcPy_c::LINK->mPosition); } diff --git a/src/d/a/obj/d_a_obj_fairy.cpp b/src/d/a/obj/d_a_obj_fairy.cpp index bdc0bf8a..4155855a 100644 --- a/src/d/a/obj/d_a_obj_fairy.cpp +++ b/src/d/a/obj/d_a_obj_fairy.cpp @@ -1,58 +1,272 @@ #include "d/a/obj/d_a_obj_fairy.h" +#include "c/c_lib.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/d_a_base.h" +#include "d/a/d_a_item.h" +#include "d/a/d_a_itembase.h" #include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_s.h" +#include "d/col/bg/d_bg_s_acch.h" +#include "d/col/bg/d_bg_s_gnd_chk.h" +#include "d/col/c/c_cc_d.h" +#include "d/col/cc/d_cc_s.h" +#include "d/d_player_act.h" +#include "d/d_stage_mgr.h" +#include "d/snd/d_snd_small_effect_mgr.h" +#include "d/snd/d_snd_wzsound.h" +#include "f/f_base.h" +#include "m/m3d/m_fanm.h" +#include "m/m_mtx.h" +#include "m/m_vec.h" +#include "nw4r/math/math_arithmetic.h" +#include "s/s_Math.h" +#include "toBeSorted/attention.h" +#include "toBeSorted/d_emitter.h" -SPECIAL_ACTOR_PROFILE(OBJ_FAIRY, dAcObjFairy_c, fProfile::OBJ_FAIRY, 0x166, 0, 2); +SPECIAL_ACTOR_PROFILE(OBJ_FAIRY, dAcOFairy_c, fProfile::OBJ_FAIRY, 0x22D, 0, 0x23); -STATE_DEFINE(dAcObjFairy_c, Wait); -STATE_DEFINE(dAcObjFairy_c, Avoid); -STATE_DEFINE(dAcObjFairy_c, PlayerAvoid); -STATE_DEFINE(dAcObjFairy_c, CureStart); -STATE_DEFINE(dAcObjFairy_c, Cure); -STATE_DEFINE(dAcObjFairy_c, CureEnd); -STATE_DEFINE(dAcObjFairy_c, CatchDemo); +static dCcD_SrcSph sSphSrc1 = { + /* mObjInf */ + {/* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + /* mObjTg */ {AT_TYPE_BUGNET | AT_TYPE_BELLOWS | AT_TYPE_WIND, 0x200311, {0, 0, 0x40F}, 0, 0}, + /* mObjCo */ {0}}, + /* mSphInf */ + {30.f}, +}; -bool dAcObjFairy_c::createHeap() { +static dCcD_SrcSph sSphSrc2 = { + /* mObjInf */ + {/* mObjAt */ {0, 0x0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + /* mObjTg */ {0, 0x0, {0, 0, 0x40F}, 0, 0}, + /* mObjCo */ {0x29}}, + /* mSphInf */ + {10.f}, +}; + +static InteractionTargetDef sAttnTarget = {1, 0, 0, UNK_18, 0x2, 400.0f, 0.0f, 0.0f, -400.0f, 400.0f, 50.0f, 1.0f}; + +STATE_DEFINE(dAcOFairy_c, Wait); +STATE_DEFINE(dAcOFairy_c, Avoid); +STATE_DEFINE(dAcOFairy_c, PlayerAvoid); +STATE_DEFINE(dAcOFairy_c, CureStart); +STATE_DEFINE(dAcOFairy_c, Cure); +STATE_DEFINE(dAcOFairy_c, CureEnd); +STATE_DEFINE(dAcOFairy_c, CatchDemo); + +static void vecCylCalc(mVec3_c &target, const mAng &rot, f32 factor); + +bool dAcOFairy_c::createHeap() { void *file = getOarcResFile("PutFairy"); TRY_CREATE(mModel.create(file, "PutFairy", "PutFairy_fly", &mAllocator, 0x120)); return true; } -int dAcObjFairy_c::create() { - CREATE_ALLOCATOR(dAcObjFairy_c); +int dAcOFairy_c::create() { + CREATE_ALLOCATOR(dAcOFairy_c); - // TODO + mStts.SetRank(1); + mCcSph1.Set(sSphSrc1); + mCcSph1.SetStts(mStts); + mCcSph2.Set(sSphSrc2); + mCcSph2.SetStts(mStts); + + mObjAcch.Set(this, 1, &mAcchCir); + mAcchCir.SetWall(20.0f, 150.0f); + mObjAcch.SetWaterNone(); + mObjAcch.SetGndThinCellingOff(); + mAcceleration = 0.0f; + mMaxSpeed = -40.0f; + + setPosYWaveParams(); + int rnd = cM::rndInt(40); + s16 tmp = mPosYWaveSpeed; + mPosYWaveTime = tmp * rnd; + mOrigPosition = mPosition; + mMaxSpeedY = randMaxSpeedY(); + mSpeed = mMaxSpeedY; + + mSpawnType = getFromParams(0, 0xF); + field_0xB81 = getFromParams(4, 0x3); + + setSpawnPosition(calcInitialSpawnPosition()); + + mVec3_c crrPos = mPosition; + mObjAcch.CrrPos(*dBgS::GetInstance()); + if (mObjAcch.ChkWallHit(nullptr)) { + mAng tmp1 = mAcchCir.GetWallAngleY() + cM::rndFX(1.0f) * 1820.0f; + mAng tmp2 = mAngle.y; + mVelocity.rotY(tmp1 - tmp2); + mAngle.y = tmp1; + + mVec3_c v(mVec3_c::Ez * (cM::rndFX(10.0f) + 150.0f)); + v.rotY(tmp1); + + mOrigPosition += v; + setPosition(crrPos); + mOldPosition = mPosition; + } + + if (mSpawnType == SPAWN_MANUAL_RELEASE || mSpawnType == SPAWN_AUTO_RELEASE) { + mStateMgr.changeState(StateID_CureStart); + } else { + mStateMgr.changeState(StateID_Wait); + } - mStateMgr.changeState(StateID_CureStart); - mStateMgr.changeState(StateID_Wait); mModel.getModel().setPriorityDraw(0x7F, 0x7F); mBoundingBox.Set(mVec3_c(-20.0f, -200.0f, -20.0f), mVec3_c(20.0f, 20.0f, 20.0f)); - return SUCCEEDED; -} + mVec3_c pos = mPosition; + dBgS_ObjGndChk chk; + pos.y += 10.0f; + if (chk.CheckPos(pos)) { + mOriginalGndHeight = chk.GetGroundHeight(); + mOrigPosition.y = mOriginalGndHeight + 20.0f + 100.0f; + } + mPreventCatchAfterSpawnTimer = 45; -int dAcObjFairy_c::doDelete() { - // TODO + if (isWithinPlayerRadius(200.0f)) { + s16 ang = mVelocity.atan2sX_Z(); + if (sLib::absDiff(getXZAngleToPlayer(), ang) < 0x2000) { + mVelocity.rotY(0x8000); + mAngle.y += 0x8000; + } + } + + mModel.setAnm("PutFairy_fly", m3d::PLAY_MODE_4, 0.0f); + mModel.setRate(1.0f); + mModel.setFrame(cM::rndInt(60)); + + for (int i = 0; i < ARRAY_LENGTH(mEffects); i++) { + mEffects[i].init(this); + } return SUCCEEDED; } -int dAcObjFairy_c::actorExecute() { +int dAcOFairy_c::doDelete() { + if (!isCuring()) { + setObjectProperty(OBJ_PROP_0x200); + for (int i = 0; i < (int)ARRAY_LENGTH(mEffects); i++) { + mEffects[i].remove(true); + } + } + + return SUCCEEDED; +} + +int dAcOFairy_c::actorExecute() { + if (!mStateMgr.isState(StateID_CatchDemo)) { + if (mCcSph1.ChkTgHit() && !mStateMgr.isState(StateID_CatchDemo) && mCcSph1.ChkTgAtHitType(AT_TYPE_BUGNET)) { + mStateMgr.changeState(StateID_CatchDemo); + return SUCCEEDED; + } + + if (!sLib::calcTimer(&mPreventCatchAfterSpawnTimer)) { + if (mCcSph2.ChkCoHit() && !isCuring() && !dAcPy_c::GetLink()->checkCurrentAction(/* SCOOP */ 0x9E)) { + if (!dAcItem_c::hasAnyFairy()) { + for (int i = 0; i < (int)ARRAY_LENGTH(mEffects); i++) { + mEffects[i].remove(true); + } + dAcItem_c::giveItem(ITEM_FAIRY, 0, 0); + deleteRequest(); + return SUCCEEDED; + } + mStateMgr.changeState(StateID_CureStart); + return SUCCEEDED; + } + } + mPositionCopy3 = mPosition; + mPositionCopy3.y += 20.0f; + + if (canTargetWithBugNet()) { + AttentionManager::GetInstance()->addTarget(*this, sAttnTarget, 0, nullptr); + } + + if (!isCuring()) { + AttentionManager::GetInstance()->addCatchLikeTarget(*this, UNK_0x58, 1, 125.0f, -200.0f, 50.0f); + + if (dAcPy_c::GetLink()->isUsingBottle()) { + AttentionManager::GetInstance()->addTarget(*this, sAttnTarget, 0, nullptr); + } + } + + mPositionCopy2 = mPosition; + } + mStateMgr.executeState(); + executeCheckForWindOrBellows(); - // TODO + if (!isCuring()) { + calcVelocity(); + mPosition += mVelocity; + mPosition += mStts.GetCcMove(); + } + + mRotation.y = mAngle.y; + + if (isCuring()) { + mPosition = mCurePosition; + } + + if (!field_0xB89) { + mEffects[0].createContinuousEffect( + PARTICLE_RESOURCE_ID_MAPPING_331_, mPosition, nullptr, nullptr, nullptr, nullptr + ); + if (!isCuring() && !dAcPy_c::GetLink()->checkActionFlagsCont(0x400000)) { + holdSound(SE_O_FAIRY_FLY_LEV); + } + } + + if (!isCuring()) { + if (dAcPy_c::GetLink()->checkActionFlagsCont(0x400000)) { + setObjectProperty(OBJ_PROP_0x200); + f32 alpha = dStageMgr_c::GetInstance()->getGlobalAlpha(); + if (alpha < 255.0f) { + mEffects[0].setGlobalAlpha(0); + } + } else { + unsetObjectProperty(OBJ_PROP_0x200); + mEffects[0].setGlobalAlpha(255); + } + } + if (isCuring() && mRoomID != dAcPy_c::GetLink()->mRoomID) { + // will delete when curing is done + deleteRequest(); + return SUCCEEDED; + } + + if (isCuring() && !field_0xB89) { + mEffects[1].createContinuousEffect( + PARTICLE_RESOURCE_ID_MAPPING_327_, mPosition, nullptr, nullptr, nullptr, nullptr + ); + } + + if (!mStateMgr.isState(StateID_CatchDemo) && !isCuring()) { + mCcSph1.SetC(mPosition); + dCcS::GetInstance()->Set(&mCcSph1); + mCcSph2.SetC(mPosition); + dCcS::GetInstance()->Set(&mCcSph2); + } + + updateMatrix(); + mModel.getModel().setLocalMtx(mWorldMtx); + mModel.getModel().setScale(mVec3_c(mScale)); + mModel.play(); return SUCCEEDED; } -int dAcObjFairy_c::draw() { +int dAcOFairy_c::draw() { if (!mStateMgr.isState(StateID_CatchDemo)) { drawModelType1(&mModel.getModel()); if (!isCuring()) { static mQuat_c rot(0.0f, 0.0f, 0.0f, 10.0f); - f32 f = field_0x4B0; + f32 f = mObjAcch.GetGroundH(); drawShadow(mShadow, nullptr, mWorldMtx, &rot, -1, -1, -1, -1, -1, mPosition.y - f); } } @@ -60,69 +274,370 @@ int dAcObjFairy_c::draw() { return SUCCEEDED; } -void dAcObjFairy_c::initializeState_Wait() {} -void dAcObjFairy_c::executeState_Wait() {} -void dAcObjFairy_c::finalizeState_Wait() {} +void dAcOFairy_c::initializeState_Wait() { + mSpeed = mMaxSpeedY; + mPreventAvoidTimer = cM::rndInt(60) + 120; + mHasSetTurnSpeedY = false; + field_0xB86 = false; + mModel.setRate(1.0f); +} +void dAcOFairy_c::executeState_Wait() { + sLib::addCalc(&mSpeed, mMaxSpeedY, 0.1f, 2.0f, 0.01f); -void dAcObjFairy_c::initializeState_Avoid() {} -void dAcObjFairy_c::executeState_Avoid() {} -void dAcObjFairy_c::finalizeState_Avoid() { + mVelocity.y = cM::minMaxLimit(mVelocity.y, -mMaxSpeedY, mMaxSpeedY); + + f32 diff = mOrigPosition.absXZTo(mPosition); + f32 yDiff = mPosition.y - mOrigPosition.y; + yDiff = nw4r::math::FAbs(yDiff); + + if (60.0f < diff) { + // Fairy has moved away from its original position by more than 60 units, + // time to turn it (in a random direction) until it's facing back to the + // original position + if (!mHasSetTurnSpeedY) { + mTurnSpeedY = rndTurnSpeed(); + } + mHasSetTurnSpeedY = true; + + mVec3_c v = mOrigPosition - mPosition; + v.normalize(); + f32 factor = 1.0f / mVelocity.mag(); + if (v.dot(mVelocity * factor) < 0.9f) { + mAngle.y += mTurnSpeedY; + } + } else { + mHasSetTurnSpeedY = false; + if (!sLib::calcTimer(&mPreventAvoidTimer)) { + mAvoidTimer = cM::rndInt(30); + mStateMgr.changeState(StateID_Avoid); + return; + } else if (shouldAvoidBugNet()) { + mAvoidTimer = 30; + mStateMgr.changeState(StateID_Avoid); + return; + } + } + + if (shouldAvoidLink()) { + mStateMgr.changeState(StateID_PlayerAvoid); + return; + } + + if (40.0f < yDiff) { + if (isMovingAwayFromOrigY()) { + f32 absVelY = mVelocity.y; + absVelY = nw4r::math::FAbs(absVelY); + f32 f = absVelY < 0.2f ? 0.3f : 0.1f; + targetSpeedY = absVelY * 0.75f + f; + if (mPosition.y - mOrigPosition.y >= 0.0f) { + targetSpeedY *= -1.0f; + } + // @bug ineffective clamping + (void)cM::minMaxLimit(targetSpeedY, -10.0f, 10.0f); + } + field_0xB86 = true; + sLib::chase(&mVelocity.y, targetSpeedY, 0.1f); + } else { + field_0xB86 = false; + } + + if (mVelocity.y < 0.0f && mPosition.y - mOriginalGndHeight <= 50.0f) { + // slow down when approaching ground + mVelocity.y *= 0.7f; + } + + calcPosYWave(); + if (mHasSetTurnSpeedY || field_0xB86) { + unsetActorProperty(AC_PROP_0x1); + } else { + setActorProperty(AC_PROP_0x1); + } +} +void dAcOFairy_c::finalizeState_Wait() {} + +void dAcOFairy_c::initializeState_Avoid() { + mTurnSpeedY = rndTurnSpeed(); + field_0xB88 = cM::rnd() <= 0.2f; + if (field_0xB88) { + mAvoidTimer = cM::rndInt(30) + 45; + mVec3_c res; + + const mVec3_c *v; + if (mVelocity.dot(mVec3_c::Ez) >= 0.0f) { + v = &mVec3_c::Ey; + } else { + // TODO - technically UB, but seems to be required + mVec3_c tmp = -mVec3_c::Ey; + v = &tmp; + } + mMtx_c mtx; + mtx.makeRotationFromVecs(mVec3_c::Ez, *v, 1.0f); + + MTXMultVecSR(mtx, mVelocity, res); + + f32 f = (mAvoidTimer % 2) != 0 ? 4.0f : 2.0f; + field_0xB24.makeRotationFromVecs(mVelocity, res, f / (mAvoidTimer - 1)); + } + unsetActorProperty(AC_PROP_0x1); +} +void dAcOFairy_c::executeState_Avoid() { + if (shouldAvoidLink()) { + mStateMgr.changeState(StateID_PlayerAvoid); + } else if (!sLib::calcTimer(&mAvoidTimer)) { + mStateMgr.changeState(StateID_Wait); + } else if (field_0xB88) { + MTXMultVecSR(field_0xB24, mVelocity, mVelocity); + mSpeed = mVelocity.absXZ(); + mAngle.y = mVelocity.atan2sX_Z(); + } else { + mAngle.y += mTurnSpeedY; + calcPosYWave(); + } +} +void dAcOFairy_c::finalizeState_Avoid() { setActorProperty(AC_PROP_0x1); } -void dAcObjFairy_c::initializeState_PlayerAvoid() {} -void dAcObjFairy_c::executeState_PlayerAvoid() {} -void dAcObjFairy_c::finalizeState_PlayerAvoid() { +void dAcOFairy_c::initializeState_PlayerAvoid() { + mTurnSpeedY *= 1.5f; + unsetActorProperty(AC_PROP_0x1); +} +void dAcOFairy_c::executeState_PlayerAvoid() { + s32 tmp = mTurnSpeedY; + mAng ang = getXZAngleToPlayer(); + bool end = sLib::chaseAngle2(&mAngle.y.mVal, ang + mAng(0x8000), tmp); + if (end) { + mStateMgr.changeState(StateID_Wait); + } else { + calcPosYWave(); + } +} +void dAcOFairy_c::finalizeState_PlayerAvoid() { setActorProperty(AC_PROP_0x1); } -void dAcObjFairy_c::initializeState_CureStart() {} -void dAcObjFairy_c::executeState_CureStart() {} -void dAcObjFairy_c::finalizeState_CureStart() {} +void dAcOFairy_c::initializeState_CureStart() { + mCureAngularSpeed = cM::rndInt(0x100) + 0x2000; + mCureAngle = getXZAngleToPlayer(); + // If the fairy saves the player from death, it spawns directly + // at the player's position and circles outwards. Otherwise it directly + // starts 50 units away. + mCurePosXZOffset = mSpawnType == SPAWN_AUTO_RELEASE ? 0.0f : 50.0f; + mCurePosYOffset = mSpawnType == SPAWN_AUTO_RELEASE ? 0.0f : 50.0f; -void dAcObjFairy_c::initializeState_Cure() {} -void dAcObjFairy_c::executeState_Cure() {} -void dAcObjFairy_c::finalizeState_Cure() {} + mCcSph2.ClrCoSet(); + mCcSph2.ClrTgSet(); + mModel.setRate(12.0f); + mSpeed = 0.0f; + mVelocity = mVec3_c::Zero; + dAcPy_c::fairyHeal(this); + if (mSpawnType != SPAWN_AUTO_RELEASE) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_O_FAIRY_RECOVER); + } +} +void dAcOFairy_c::executeState_CureStart() { + if (mSpawnType == SPAWN_AUTO_RELEASE) { + // Start circling away from the player up to the normal distance + sLib::chase(&mAutoReleaseProgress, 1.0f, 0.04f); + f32 f = cLib::easeInOut(mAutoReleaseProgress, 3.0f) * 50.0f; + mCurePosXZOffset = f; + mCurePosYOffset = f; -void dAcObjFairy_c::initializeState_CureEnd() {} -void dAcObjFairy_c::executeState_CureEnd() {} -void dAcObjFairy_c::finalizeState_CureEnd() {} + const dAcPy_c *link = dAcPy_c::GetLink(); -void dAcObjFairy_c::initializeState_CatchDemo() {} -void dAcObjFairy_c::executeState_CatchDemo() { + mCurePosition = link->mPosition; + mCurePosition.y += f; + vecCylCalc(mCurePosition, mCureAngle, f); + + mAngle.y = getXZAngleToPlayer(); + + if (link->checkActionFlags(daPlayerActBase_c::FLG0_IN_WATER)) { + mCurePosition.y += -150.0f; + } + + holdSound(SE_O_FAIRY_FLY_LEV); + if (mAutoReleaseProgress == 1.0f) { + mStateMgr.changeState(StateID_Cure); + } + } else { + calcCurePosition(50.0f, 50.0f); + s32 diff = sLib::absDiff(mCureAngle, 0); + if (diff < mCureAngularSpeed && mCurePosYOffset == 50.0f) { + mStateMgr.changeState(StateID_Cure); + } + } +} +void dAcOFairy_c::finalizeState_CureStart() {} + +void dAcOFairy_c::initializeState_Cure() { + mCureAngularSpeed = cM::rndInt(0x100) + 0x1111; + mCureAngle = getXZAngleToPlayer(); + mCurePosXZOffset = 50.0f; + mCurePosYOffset = 50.0f; + mModel.setRate(15.0f); + mCurePosXZOffsetTarget = cM::rnd() * 80.0f + 20.0f; + if (mSpawnType == SPAWN_AUTO_RELEASE) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_O_FAIRY_RECOVER); + } +} +void dAcOFairy_c::executeState_Cure() { + calcCurePosition(mCurePosXZOffsetTarget, 160.0f); + if (mCureAngle < mCureAngularSpeed) { + mCurePosXZOffsetTarget = cM::rnd() * 80.0f + 20.0f; + } + if (mCurePosYOffset == 160.0f) { + mStateMgr.changeState(StateID_CureEnd); + } +} +void dAcOFairy_c::finalizeState_Cure() {} + +void dAcOFairy_c::initializeState_CureEnd() {} +void dAcOFairy_c::executeState_CureEnd() { + calcCurePosition(mCurePosXZOffsetTarget, 180.0f); + sLib::chase(&mScale.x, 0.0f, 0.07f); + mScale.y = mScale.z = mScale.x; + if (mScale.x <= 0.0f) { + deleteRequest(); + } +} +void dAcOFairy_c::finalizeState_CureEnd() {} + +void dAcOFairy_c::initializeState_CatchDemo() { + field_0xB89 = true; + dAcPy_c::GetLinkM()->bugNetCollectTreasure(ITEM_FAIRY); + for (int i = 0; i < (int)ARRAY_LENGTH(mEffects); i++) { + mEffects[i].remove(true); + } + setObjectProperty(OBJ_PROP_0x200); +} +void dAcOFairy_c::executeState_CatchDemo() { if (!field_0xB89) { mStateMgr.changeState(StateID_Wait); } } -void dAcObjFairy_c::finalizeState_CatchDemo() { - field_0xB89 = 0; +void dAcOFairy_c::finalizeState_CatchDemo() { + field_0xB89 = false; unsetObjectProperty(OBJ_PROP_0x200); } -bool dAcObjFairy_c::shouldAvoidLink() const { - // TODO shuffles +bool dAcOFairy_c::shouldAvoidBugNet() const { if (dAcPy_c::LINK->isUsingBugnet()) { mVec3_c dist = dAcPy_c::LINK->getBugNetPos() - mPosition; - bool isClose = false; - if (dist.mag() < 100.0f && mVelocity.dot(dist) > 0.0f) { - isClose = true; - } - - return isClose; + return dist.mag() < 100.0f && mVelocity.dot(dist) > 0.0f; } return false; } -bool dAcObjFairy_c::isCuring() const { +bool dAcOFairy_c::isCuring() const { return mStateMgr.isState(StateID_CureStart) || mStateMgr.isState(StateID_Cure) || mStateMgr.isState(StateID_CureEnd); } -bool dAcObjFairy_c::canTargetWithBugNet() const { +bool dAcOFairy_c::canTargetWithBugNet() const { bool canTarget = false; if (dAcPy_c::LINK != nullptr && dAcPy_c::LINK->isUsingBugnet() && !isCuring()) { canTarget = true; } return canTarget; } + +void dAcOFairy_c::setSpawnPosition(const mVec3_c &v) { + mSpawnPosition = v; + mAngle.y = cLib::targetAngleY(mPosition, mSpawnPosition); + mVec3_c tmp(0.0f, 0.0f, mSpeed); + mWorldMtx.YrotS(mAngle.y); + mWorldMtx.XrotM(cLib::targetAngleX(mSpawnPosition, mPosition)); + MTXMultVec(mWorldMtx, tmp, mVelocity); + targetSpeedY = mVelocity.y; +} + +void dAcOFairy_c::setPosYWaveParams() { + mPosYWaveSpeed = (cM::rndF(2.0f) + 1.0f) * 546.0f; + mPosYWaveAmplitude = mSpeed * (cM::rndF(0.5f) + 0.5f); +} + +mAng dAcOFairy_c::rndTurnSpeed() const { + mAng ret = (cM::rnd() + 1.0f) * 546.0f; + if (cM::rndF(1.0f) < 0.5f) { + ret *= (s32)-1; + } + return ret; +} + +mVec3_c dAcOFairy_c::calcInitialSpawnPosition() { + mVec3_c ret = mOrigPosition; + ret.x += (cM::rndF(60.0f) * 2.0f - 60.0f); + ret.z += (cM::rndF(60.0f) * 2.0f - 60.0f); + + f32 tmp = (mOrigPosition - ret).absXZ(); + if (tmp > 60.0f) { + // @bug maybe? assigning to local fixes stack order... + mVec3_c _ignored = calcInitialSpawnPosition(); + } + + ret.y += (cM::rndF(40.0f) * 2.0f - 40.0f); + return ret; +} + +void dAcOFairy_c::calcCurePosition(const f32 &xzOffsetTarget, const f32 &yOffsetTarget) { + const dAcPy_c *link = dAcPy_c::GetLink(); + + mCurePosition = link->mPosition; + mCurePosition.y += mCurePosYOffset; + vecCylCalc(mCurePosition, mCureAngle, mCurePosXZOffset); + + sLib::chase(&mCurePosXZOffset, xzOffsetTarget, mCurePosXZOffsetTarget / 10.0f); + sLib::chase(&mCurePosYOffset, yOffsetTarget, 2.0f); + mCureAngle += mCureAngularSpeed; + + if (link->checkActionFlags(daPlayerActBase_c::FLG0_IN_WATER)) { + mCurePosition.y += -150.0f; + } + mAngle.y = getXZAngleToPlayer() + mAng(-0x4000); +} + +bool dAcOFairy_c::calcPosYWave() { + if (0.9f < mPosYWaveTime.cos()) { + setPosYWaveParams(); + } + mPosYWaveTime += mPosYWaveSpeed; + mPosition.y += mPosYWaveAmplitude * mPosYWaveTime.sin(); + return false; +} + +void dAcOFairy_c::executeCheckForWindOrBellows() { + if (mCcSph1.ChkTgHit() && mCcSph1.ChkTgAtHitType(AT_TYPE_BELLOWS | AT_TYPE_WIND) && !isCuring()) { + mVec3_c dir = mCcSph1.GetTgAtHitDir(); + mAngle.x = dir.atan2sY_XZ(); + mAngle.y = dir.atan2sX_Z(); + + // Blow the fairy in the wind direction, but slowly + mVelocity.x += dir.x * 0.05f; + mVelocity.z += dir.z * 0.05f; + mVelocity.y += dir.y * 0.01f; + + f32 f = mMaxSpeedY * 5.0f; + mSpeed = nw4r::ut::Min(mVelocity.absXZ(), f); + } +} + +f32 dAcOFairy_c::randMaxSpeedY() const { + return cM::rndFX(0.5f) + 3.0f; +} + +bool dAcOFairy_c::shouldAvoidLink() const { + return isWithinPlayerRadius(150.0f) && sLib::absDiff(mAngle.y, getXZAngleToPlayer()) < 0x2000; +} + +bool dAcOFairy_c::isMovingAwayFromOrigY() const { + return (targetSpeedY >= 0.0f && mPosition.y - mOrigPosition.y > 0.0f) || + (targetSpeedY <= 0.0f && mPosition.y - mOrigPosition.y < 0.0f); +} + +// This is a repeated calculation, it correctly flips the stack order of the casts, +// and it avoids temporaries, so it's a pretty good inline candidate +inline static void vecCylCalc(mVec3_c &target, const mAng &rot, f32 factor) { + target.x += factor * rot.sin(); + target.z += factor * rot.cos(); +} diff --git a/src/d/d_jnt_col.cpp b/src/d/d_jnt_col.cpp index 8d60b22f..6efea4f4 100644 --- a/src/d/d_jnt_col.cpp +++ b/src/d/d_jnt_col.cpp @@ -279,7 +279,7 @@ void dJntCol_c::setArrowPosAndAngle( getAnmMtx(i_anmMtxIdx, &mtx); MTXMultVecSR(mtx, *i_srcPos, dstPos); - i_arrowPosP->x = dstPos.atan2sY_XZ(); + i_arrowPosP->x = dstPos.atan2snY_XZ(); i_arrowPosP->y = dstPos.atan2sX_Z(); MTXMultVec(mtx, *param_0, *param_3); } diff --git a/src/d/d_pad.cpp b/src/d/d_pad.cpp index efc067d1..098983e4 100644 --- a/src/d/d_pad.cpp +++ b/src/d/d_pad.cpp @@ -430,14 +430,8 @@ void ex_c::fn_800562B0(s32 chan, mVec3_c &mpls) { } } -// this looks like nw4r::ut::Clamp but the ternaries are swapped -template -inline T WeirdClamp(T value, T min, T max) { - return value < min ? min : (value > max ? max : value); -} - void ex_c::fn_80056330(s32 chan) { - f32 mult = WeirdClamp(1.f - field_0x8C.y * field_0x8C.y, 0.f, 1.f); + f32 mult = cM::minMaxLimit(1.f - field_0x8C.y * field_0x8C.y, 0.f, 1.f); mVec3_c basis; if (field_0x53) { @@ -520,9 +514,9 @@ void ex_c::fn_80056790(s32 chan) { v2.z = nw4r::ut::Max(v2.z, field_0x70.cos()); s16 b1 = cM::atan2s(-v2.x, v2.z); - field_0x5C.x = WeirdClamp(b1 * (1.0f / field_0x70), -1.0f, 1.0f); + field_0x5C.x = cM::minMaxLimit(b1 * (1.0f / field_0x70), -1.0f, 1.0f); s16 b2 = cM::atan2s(-v2.y, v2.z); - field_0x5C.y = WeirdClamp(b2 * (1.0f / field_0x70), -f, f); + field_0x5C.y = cM::minMaxLimit(b2 * (1.0f / field_0x70), -f, f); if (field_0x51 != 0) { field_0x51--; diff --git a/src/d/d_player_mdl.cpp b/src/d/d_player_mdl.cpp index 19d7b35c..06ebc427 100644 --- a/src/d/d_player_mdl.cpp +++ b/src/d/d_player_mdl.cpp @@ -1286,8 +1286,8 @@ void daPlayerModelBase_c::adjustMainModelWorldMtx(PlayerMainModelNode_e nodeId, mAng v1 = -3277; mAng v2 = 910; if (nodeId == PLAYER_MAIN_NODE_HAND_R) { - v1 *= -1; - v2 *= -1; + v1 *= (s32)-1; + v2 *= (s32)-1; } applyWorldRotationMaybe(result, 0xec17, v1, v2, nullptr, true); } diff --git a/src/toBeSorted/dowsing_target.cpp b/src/toBeSorted/dowsing_target.cpp index 79297112..5969bf73 100644 --- a/src/toBeSorted/dowsing_target.cpp +++ b/src/toBeSorted/dowsing_target.cpp @@ -155,8 +155,6 @@ bool DowsingTarget::hasDowsingInSlot(int slot) { return false; } -#define MYCLAMP(low, high, x) ((x) < (low) ? (low) : ((x) > (high) ? (high) : (x))) - DowsingTarget *DowsingTarget::getDowsingInfo( const mVec3_c &playerPosition, const mVec3_c &dowsingDirection, f32 *p3, f32 *p4, f32 *intensity, int slot ) { @@ -177,13 +175,13 @@ DowsingTarget *DowsingTarget::getDowsingInfo( targetDir.normalize(); f32 dot = dwsDir.dot(targetDir); - dot = MYCLAMP(-1.0f, 1.0f, dot); + dot = cM::minMaxLimit(dot, -1.0f, 1.0f); f32 a = 1.0f - dot * dot <= 0.0f ? 0.0f : nw4r::math::FrSqrt(1.0f - dot * dot) * (1.0f - dot * dot); f32 f9 = (5461 - labs(cM::atan2s(a, dot))) * (1.0f / 5461.0f); if (!(f9 < 0.0f)) { f32 val; - f32 f10 = MYCLAMP(0.0f, 0.9f, proximity * 0.0001f) * 1.1111112f; + f32 f10 = cM::minMaxLimit(proximity * 0.0001f, 0.0f, 0.9f) * 1.1111112f; if (f9 > 0.85f) { f9 = 0.85f; }