Skip to content

Handoff OSD#334

Open
RegularFriend wants to merge 26 commits into
AlexanderHarrison:masterfrom
RegularFriend:pr/osd-handoff
Open

Handoff OSD#334
RegularFriend wants to merge 26 commits into
AlexanderHarrison:masterfrom
RegularFriend:pr/osd-handoff

Conversation

@RegularFriend
Copy link
Copy Markdown

Enables a Handoff OSD when Fighter Specific Tech is selected with The Ice Climbers.

Comment thread src/osds.c
#include "events.h"
#include "osds.h"

static GXColor stc_msg_colors[] = {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugly duplication with array in events.c but fine for now. I'll replace it in the future.

Comment thread src/osds.c
Comment on lines +105 to +114
typedef struct {
int ft_handoff_begin[6];
int sub_handoff_begin[6];
int ft_grab_hitbox_begin[6];
int sub_grab_hitbox_begin[6];
int ft_state_previous[6];
int sub_state_previous[6];
int enemy_state_previous[6];
int enemy_release[6];
} HandoffState;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be HandoffState state[6] imo.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easy to do, ill clean up soon.

Comment thread src/osds.c
Comment on lines +145 to +146
//icies check
if (!ft_sub || !ft || !enm) return;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing icies check?

Copy link
Copy Markdown
Author

@RegularFriend RegularFriend May 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the icies check. if you have both a ft and a ft sub, you're an icies. comment a bit misleading because really im checking 'are you icies and is there an enemy'

i checked ft sub + ft valid over explicit icies because some people like to run mods like 'youre double fox' or 'the ike climbers', and it seemed free for this mod to be compatible with that if i checked it this way.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sheik / zelda also uses the subfighter for the unused transformation.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This i did not know. i will add an explicit are you icies check.

Comment thread src/osds.c
Comment on lines +110 to +112
int ft_state_previous[6];
int sub_state_previous[6];
int enemy_state_previous[6];
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use ft_data->TM.state_prev instead?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea i just didn't realize this existed. that's mmuch nicer. will make this change.

Comment thread src/osds.c
Comment on lines +225 to +272
const bool enemy_released = IsThrownState(state.enemy_state_previous[enemy_ply]) && !IsThrownState(
enemy_data->state_id);
if (enemy_released) {
state.enemy_release[enemy_ply] = event_vars->game_timer;
}
//wait a few frames after the handoff begins to start looking for the other to throw. to avoid synced throws
//false-reporting a handoff miss on nana's throw.
if (event_vars->game_timer - state.sub_handoff_begin[ft_ply] > 8 && IsGrabHitboxActive(ft_data) && !
OSDHandoff_FtGrabHitboxActiveLastFrame(&state, ft_ply)) {
state.ft_grab_hitbox_begin[ft_ply] = event_vars->game_timer;
}

if (ft_data->state_id == ASID_CATCHPULL) {
//if throw release was never caught, that means it was this same frame. same deal for grab hurtbox.
if (state.enemy_release[enemy_ply] == 0) state.enemy_release[enemy_ply] = event_vars->game_timer;
if (state.ft_grab_hitbox_begin[ft_ply] == 0) state.ft_grab_hitbox_begin[ft_ply] = event_vars->game_timer;

int grab_to_throw_delta = state.ft_grab_hitbox_begin[ft_ply] - state.enemy_release[enemy_ply];
bool grab_was_early = grab_to_throw_delta < 1;
int color_timing = grab_to_throw_delta == -1 || grab_to_throw_delta == 0 ? MSGCOLOR_GREEN : MSGCOLOR_WHITE;
GOBJ *msg_gobj = Message_Display(OSD_FighterSpecificTech, ft_ply, MSGCOLOR_WHITE,
"Handoff Success\n %dF %s", abs(grab_to_throw_delta),
grab_was_early ? "early" : "late");
MsgData *msg = msg_gobj->userdata;
Text_SetColor(msg->text, 0, &stc_msg_colors[MSGCOLOR_GREEN]);
Text_SetColor(msg->text, 1, &stc_msg_colors[color_timing]);
state.sub_handoff_begin[ft_ply] = 0;
} else if (state.ft_grab_hitbox_begin[ft_ply] != 0 &&
event_vars->game_timer - state.ft_grab_hitbox_begin[ft_ply] > grab_miss_timeout) {
int grab_to_throw_delta = state.ft_grab_hitbox_begin[ft_ply] - state.enemy_release[enemy_ply];
bool grab_was_early = grab_to_throw_delta < 1;
Message_Display(OSD_FighterSpecificTech, ft_ply, MSGCOLOR_RED, "Handoff Failure\n %dF %s",
abs(grab_to_throw_delta), grab_was_early ? "early" : "late");
state.sub_handoff_begin[ft_ply] = 0;
}
} else {
//Don't start a new handoff if you were throwing last frame.
if (!IsThrowState(state.sub_state_previous[ft_ply])) {
//if you're throwing this frame, a handoff begins
if (IsThrowState(sub_data->state_id)) {
state.sub_handoff_begin[ft_ply] = event_vars->game_timer;
}
//reset state
if (!tick_ft_handoff) {
state.ft_grab_hitbox_begin[ft_ply] = 0;
state.enemy_release[enemy_ply] = 0;
}
}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is mostly duplicated with above. Is it possible to dedup into a function?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really tried to deup into a function, but the struggle is that the ft_sub doesn't have a unique ID. you have to know if its the ft sub throwing to the ft (or vice versa) for the logic to be correct, but because both character pointers reference the same player ID, i struggled to figure out how to do this generically.

for example, you can't check 'did your player id have a grab hitbox last frame' generically because both the sub and the fighter have the same id and which one you check really matters for the logic.

I'll take a stab at it, and if you have any suggestions i'm all ears, but i similarly didn't like the duplication but couldn't find a way around it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants