Handoff OSD#334
Conversation
…and compliation errors
…ityEdition-Friend Merge
…roll into character specific tech
…w. Removed the bespoke handoff osd and rolled it into fighter specific tech.
…w. Removed the bespoke handoff osd and rolled it into fighter specific tech.
| #include "events.h" | ||
| #include "osds.h" | ||
|
|
||
| static GXColor stc_msg_colors[] = { |
There was a problem hiding this comment.
Ugly duplication with array in events.c but fine for now. I'll replace it in the future.
| 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; |
There was a problem hiding this comment.
Should be HandoffState state[6] imo.
There was a problem hiding this comment.
Easy to do, ill clean up soon.
| //icies check | ||
| if (!ft_sub || !ft || !enm) return; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Sheik / zelda also uses the subfighter for the unused transformation.
There was a problem hiding this comment.
This i did not know. i will add an explicit are you icies check.
| int ft_state_previous[6]; | ||
| int sub_state_previous[6]; | ||
| int enemy_state_previous[6]; |
There was a problem hiding this comment.
Could you use ft_data->TM.state_prev instead?
There was a problem hiding this comment.
Yea i just didn't realize this existed. that's mmuch nicer. will make this change.
| 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; | ||
| } | ||
| } |
There was a problem hiding this comment.
Looks like this is mostly duplicated with above. Is it possible to dedup into a function?
There was a problem hiding this comment.
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.
Enables a Handoff OSD when Fighter Specific Tech is selected with The Ice Climbers.