1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-11-25 01:34:18 +00:00

Document Player_Action_SwingBottle (#2263)

* Document Player_Action_8084ECA4

* Name func_8083721C

* Add note

* Move BottleCatchAnimationData declaration

* Apply format

* Revert "Name func_8083721C"

This reverts commit aeb7ea83ab.

* Revert "Merge branch 'main' of github.com:zeldaret/oot into bottle-info"

This reverts commit 10f1a4500368a66097c80cdb08f86ff2456ba9fb, reversing
changes made to 547280abf2a041a8f6884d43b2eada7802c7feec.

* Reapply "Merge branch 'main' of github.com:zeldaret/oot into bottle-info"

This reverts commit e9bf122be5.

* Some more bottle docs (#1)

* more docs

* struct comments

* format.py

* Revert "Merge branch 'main' of github.com:zeldaret/oot into bottle-info"

This reverts commit 10f1a4500368a66097c80cdb08f86ff2456ba9fb, reversing
changes made to 547280abf2a041a8f6884d43b2eada7802c7feec.

* add clarifying comment

* review, fix bss

---------

Co-authored-by: fig02 <fig02srl@gmail.com>
This commit is contained in:
Pepe20129 2024-10-11 22:31:06 +02:00 committed by GitHub
parent f79c9db649
commit 44460eeaec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 77 additions and 64 deletions

View file

@ -877,12 +877,15 @@ typedef struct Player {
/* 0x084F */ union {
s8 actionVar1;
s8 bottleCatchType; // Player_Action_SwingBottle: entry type for `sBottleCatchInfo`, corresponds to actor caught in a bottle
} av1; // "Action Variable 1": context dependent variable that has different meanings depending on what action is currently running
/* 0x0850 */ union {
s16 actionVar2;
s16 fallDamageStunTimer; // Player_Action_Idle: Prevents any movement and shakes model up and down quickly to indicate fall damage stun
s16 bonked; // Player_Action_Roll: set to true after bonking into a wall or an actor
s16 startedTextbox; // Player_Action_SwingBottle: set to true when the textbox is started
s16 inWater; // Player_Action_SwingBottle: true if a bottle is swung in water. Used to determine which bottle swing animation to use.
} av2; // "Action Variable 2": context dependent variable that has different meanings depending on what action is currently running
/* 0x0854 */ f32 unk_854;

View file

@ -49,13 +49,6 @@ typedef struct ExplosiveInfo {
/* 0x02 */ s16 actorId;
} ExplosiveInfo; // size = 0x04
typedef struct BottleCatchInfo {
/* 0x00 */ s16 actorId;
/* 0x02 */ u8 itemId;
/* 0x03 */ u8 itemAction;
/* 0x04 */ u8 textId;
} BottleCatchInfo; // size = 0x06
typedef struct BottleDropInfo {
/* 0x00 */ s16 actorId;
/* 0x02 */ s16 actorParams;
@ -108,13 +101,6 @@ typedef struct ItemChangeInfo {
/* 0x04 */ u8 changeFrame;
} ItemChangeInfo; // size = 0x08
typedef struct struct_80854554 {
/* 0x00 */ LinkAnimationHeader* unk_00;
/* 0x04 */ LinkAnimationHeader* unk_04;
/* 0x08 */ u8 unk_08;
/* 0x09 */ u8 unk_09;
} struct_80854554; // size = 0x0C
typedef struct struct_80854190 {
/* 0x00 */ LinkAnimationHeader* unk_00;
/* 0x04 */ LinkAnimationHeader* unk_04;
@ -330,7 +316,7 @@ void Player_Action_8084E604(Player* this, PlayState* play);
void Player_Action_8084E6D4(Player* this, PlayState* play);
void Player_Action_8084E9AC(Player* this, PlayState* play);
void Player_Action_8084EAC0(Player* this, PlayState* play);
void Player_Action_8084ECA4(Player* this, PlayState* play);
void Player_Action_SwingBottle(Player* this, PlayState* play);
void Player_Action_8084EED8(Player* this, PlayState* play);
void Player_Action_8084EFC0(Player* this, PlayState* play);
void Player_Action_ExchangeItem(Player* this, PlayState* play);
@ -370,7 +356,7 @@ static s32 sSavedCurrentMask;
static Vec3f sInteractWallCheckResult;
static Input* sControlInput;
#pragma increment_block_number "gc-eu:192 gc-eu-mq:192 gc-jp:192 gc-jp-ce:192 gc-jp-mq:192 gc-us:192 gc-us-mq:192" \
#pragma increment_block_number "gc-eu:192 gc-eu-mq:192 gc-jp:160 gc-jp-ce:160 gc-jp-mq:160 gc-us:160 gc-us-mq:160" \
"ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
// .data
@ -6587,21 +6573,28 @@ s32 func_8083C61C(PlayState* play, Player* this) {
return 0;
}
static struct_80854554 D_80854554[] = {
{ &gPlayerAnim_link_bottle_bug_miss, &gPlayerAnim_link_bottle_bug_in, 2, 3 },
{ &gPlayerAnim_link_bottle_fish_miss, &gPlayerAnim_link_bottle_fish_in, 5, 3 },
typedef struct BottleSwingInfo {
/* 0x00 */ LinkAnimationHeader* missAnimation;
/* 0x04 */ LinkAnimationHeader* catchAnimation;
/* 0x08 */ u8 firstActiveFrame;
/* 0x09 */ u8 numActiveFrames;
} BottleSwingInfo; // size = 0x0C
static BottleSwingInfo sBottleSwingInfo[] = {
{ &gPlayerAnim_link_bottle_bug_miss, &gPlayerAnim_link_bottle_bug_in, 2, 3 }, // on land
{ &gPlayerAnim_link_bottle_fish_miss, &gPlayerAnim_link_bottle_fish_in, 5, 3 }, // in water
};
s32 func_8083C6B8(PlayState* play, Player* this) {
if (sUseHeldItem) {
if (Player_GetBottleHeld(this) >= 0) {
Player_SetupAction(play, this, Player_Action_8084ECA4, 0);
Player_SetupAction(play, this, Player_Action_SwingBottle, 0);
if (this->actor.depthInWater > 12.0f) {
this->av2.actionVar2 = 1;
this->av2.inWater = true;
}
Player_AnimPlayOnceAdjusted(play, this, D_80854554[this->av2.actionVar2].unk_00);
Player_AnimPlayOnceAdjusted(play, this, sBottleSwingInfo[this->av2.inWater].missAnimation);
Player_PlaySfx(this, NA_SE_IT_SWORD_SWING);
Player_PlayVoiceSfx(this, NA_SE_VO_LI_AUTO_JUMP);
@ -13983,69 +13976,86 @@ void Player_Action_8084EAC0(Player* this, PlayState* play) {
}
}
static BottleCatchInfo sBottleCatchInfos[] = {
{ ACTOR_EN_ELF, ITEM_BOTTLE_FAIRY, PLAYER_IA_BOTTLE_FAIRY, 0x46 },
{ ACTOR_EN_FISH, ITEM_BOTTLE_FISH, PLAYER_IA_BOTTLE_FISH, 0x47 },
{ ACTOR_EN_ICE_HONO, ITEM_BOTTLE_BLUE_FIRE, PLAYER_IA_BOTTLE_FIRE, 0x5D },
{ ACTOR_EN_INSECT, ITEM_BOTTLE_BUG, PLAYER_IA_BOTTLE_BUG, 0x7A },
typedef enum BottleCatchType {
BOTTLE_CATCH_NONE, // This type does not have an associated entry in `sBottleCatchInfo`
BOTTLE_CATCH_FAIRY,
BOTTLE_CATCH_FISH,
BOTTLE_CATCH_BLUE_FIRE,
BOTTLE_CATCH_BUGS
} BottleCatchType;
typedef struct BottleCatchInfo {
/* 0x00 */ s16 actorId;
/* 0x02 */ u8 itemId;
/* 0x03 */ u8 itemAction;
/* 0x04 */ u8 textId;
} BottleCatchInfo; // size = 0x06
static BottleCatchInfo sBottleCatchInfo[] = {
{ ACTOR_EN_ELF, ITEM_BOTTLE_FAIRY, PLAYER_IA_BOTTLE_FAIRY, 0x46 }, // BOTTLE_CATCH_FAIRY
{ ACTOR_EN_FISH, ITEM_BOTTLE_FISH, PLAYER_IA_BOTTLE_FISH, 0x47 }, // BOTTLE_CATCH_FISH
{ ACTOR_EN_ICE_HONO, ITEM_BOTTLE_BLUE_FIRE, PLAYER_IA_BOTTLE_FIRE, 0x5D }, // BOTTLE_CATCH_BLUE_FIRE
{ ACTOR_EN_INSECT, ITEM_BOTTLE_BUG, PLAYER_IA_BOTTLE_BUG, 0x7A }, // BOTTLE_CATCH_BUGS
};
void Player_Action_8084ECA4(Player* this, PlayState* play) {
struct_80854554* sp24;
BottleCatchInfo* catchInfo;
s32 temp;
s32 i;
void Player_Action_SwingBottle(Player* this, PlayState* play) {
// Action Variable 2 has two separate uses within the same action.
// After it is used as `inWater` here, it will be used for `startedTextbox` below.
// The two usages will never overlap, so this won't cause any issues.
BottleSwingInfo* swingEntry = &sBottleSwingInfo[this->av2.inWater];
sp24 = &D_80854554[this->av2.actionVar2];
Player_DecelerateToZero(this);
if (LinkAnimation_Update(play, &this->skelAnime)) {
if (this->av1.actionVar1 != 0) {
if (this->av2.actionVar2 == 0) {
Message_StartTextbox(play, sBottleCatchInfos[this->av1.actionVar1 - 1].textId, &this->actor);
if (this->av1.bottleCatchType != BOTTLE_CATCH_NONE) {
if (!this->av2.startedTextbox) {
// 1 is subtracted because `sBottleCatchInfo` does not have an entry for `BOTTLE_CATCH_NONE`
Message_StartTextbox(play, sBottleCatchInfo[this->av1.bottleCatchType - 1].textId, &this->actor);
Audio_PlayFanfare(NA_BGM_ITEM_GET | 0x900);
this->av2.actionVar2 = 1;
this->av2.startedTextbox = true;
} else if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
this->av1.actionVar1 = 0;
this->av1.bottleCatchType = BOTTLE_CATCH_NONE;
Camera_SetFinishedFlag(Play_GetCamera(play, CAM_ID_MAIN));
}
} else {
func_8083C0E8(this, play);
}
} else {
if (this->av1.actionVar1 == 0) {
temp = this->skelAnime.curFrame - sp24->unk_08;
} else if (this->av1.bottleCatchType == BOTTLE_CATCH_NONE) {
s32 activeFrame = this->skelAnime.curFrame - swingEntry->firstActiveFrame;
if (temp >= 0) {
if (sp24->unk_09 >= temp) {
if (this->av2.actionVar2 != 0) {
if (temp == 0) {
if (activeFrame >= 0 && activeFrame <= swingEntry->numActiveFrames) {
if (this->av2.inWater && activeFrame == 0) {
// Play water scoop sound on the first active frame, if applicable
Player_PlaySfx(this, NA_SE_IT_SCOOP_UP_WATER);
}
}
// `interactRangeActor` will be set by the Get Item system. See `Actor_OfferGetItem`.
if (this->interactRangeActor != NULL) {
catchInfo = &sBottleCatchInfos[0];
for (i = 0; i < ARRAY_COUNT(sBottleCatchInfos); i++, catchInfo++) {
BottleCatchInfo* catchInfo = &sBottleCatchInfo[0];
s32 i;
// Try to find an `interactRangeActor` with the same ID as an entry in `sBottleCatchInfo`
for (i = 0; i < ARRAY_COUNT(sBottleCatchInfo); i++, catchInfo++) {
if (this->interactRangeActor->id == catchInfo->actorId) {
break;
}
}
if (i < ARRAY_COUNT(sBottleCatchInfos)) {
this->av1.actionVar1 = i + 1;
this->av2.actionVar2 = 0;
if (i < ARRAY_COUNT(sBottleCatchInfo)) {
// 1 is added because `sBottleCatchInfo` does not have an entry for `BOTTLE_CATCH_NONE`
this->av1.bottleCatchType = i + 1;
this->av2.startedTextbox = false;
this->stateFlags1 |= PLAYER_STATE1_28 | PLAYER_STATE1_29;
this->interactRangeActor->parent = &this->actor;
Player_UpdateBottleHeld(play, this, catchInfo->itemId, ABS(catchInfo->itemAction));
Player_AnimPlayOnceAdjusted(play, this, sp24->unk_04);
Player_AnimPlayOnceAdjusted(play, this, swingEntry->catchAnimation);
func_80835EA4(play, 4);
}
}
}
}
}
}
//! @bug If the animation is changed at any point above (such as by func_8083C0E8() or
//! Player_AnimPlayOnceAdjusted()), it will change the curFrame to 0. This causes this flag to be set for one frame,