Add Knuckles clambering

This commit is contained in:
Lucas S. Vieira 2025-04-15 22:10:32 -03:00
parent 63d7acb006
commit 4488cb53b2

View file

@ -46,17 +46,17 @@
#define ANIM_TAILMOVE 0x0ab30262 // MILES ONLY #define ANIM_TAILMOVE 0x0ab30262 // MILES ONLY
#define ANIM_TAILFLY 0x08390216 // MILES ONLY #define ANIM_TAILFLY 0x08390216 // MILES ONLY
#define ANIM_CLIMBSTOP 0x0d1102ae // KNUCKLKES ONLY #define ANIM_CLIMBSTOP 0x0d1102ae // KNUCKLES ONLY
#define ANIM_CLIMBUP 0x0805020d // KNUCKLKES ONLY #define ANIM_CLIMBUP 0x0805020d // KNUCKLES ONLY
#define ANIM_CLIMBDOWN 0x0cd402a0 // KNUCKLKES ONLY #define ANIM_CLIMBDOWN 0x0cd402a0 // KNUCKLES ONLY
#define ANIM_CLIMBRISE 0x0ce9029b // KNUCKLKES ONLY #define ANIM_CLIMBRISE 0x0ce9029b // KNUCKLES ONLY
#define ANIM_CLIMBEND 0x0a22023f // KNUCKLKES ONLY #define ANIM_CLIMBEND 0x0a22023f // KNUCKLES ONLY
#define ANIM_GLIDE 0x04400166 // KNUCKLKES ONLY #define ANIM_GLIDE 0x04400166 // KNUCKLES ONLY
#define ANIM_GLIDETURNA 0x100902f0 // KNUCKLKES ONLY #define ANIM_GLIDETURNA 0x100902f0 // KNUCKLES ONLY
#define ANIM_GLIDETURNB 0x100a02f1 // KNUCKLKES ONLY #define ANIM_GLIDETURNB 0x100a02f1 // KNUCKLES ONLY
#define ANIM_GLIDECANCEL 0x1252030c // KNUCKLKES ONLY #define ANIM_GLIDECANCEL 0x1252030c // KNUCKLES ONLY
#define ANIM_GLIDELAND 0x0cab0285 // KNUCKLKES ONLY #define ANIM_GLIDELAND 0x0cab0285 // KNUCKLES ONLY
#define ANIM_GLIDERISE 0x0ce60299 // KNUCKLKES ONLY #define ANIM_GLIDERISE 0x0ce60299 // KNUCKLES ONLY
extern int debug_mode; extern int debug_mode;
@ -948,6 +948,9 @@ player_update(Player *player)
// Ignore input while gasping. Release action when control // Ignore input while gasping. Release action when control
// lock is over // lock is over
if(player->ctrllock <= 0) player_set_action(player, ACTION_NONE); if(player->ctrllock <= 0) player_set_action(player, ACTION_NONE);
} else if(player->action == ACTION_CLAMBER) {
// Do not move while clambering
player->vel.vx = player->vel.vy = player->vel.vz = 0;
} else { } else {
// Default physics // Default physics
player_set_action(player, ACTION_NONE); player_set_action(player, ACTION_NONE);
@ -1092,7 +1095,8 @@ player_update(Player *player)
player_set_action(player, ACTION_CLIMB); player_set_action(player, ACTION_CLIMB);
} }
} else if((player->ctrllock == 0) } else if((player->ctrllock == 0)
&& (player->action != ACTION_CLIMB)) { && (player->action != ACTION_CLIMB)
&& (player->action != ACTION_CLAMBER)) {
if(input_pressing(&player->input, PAD_RIGHT)) { if(input_pressing(&player->input, PAD_RIGHT)) {
if(player->vel.vx < player->cnst->x_top_spd) if(player->vel.vx < player->cnst->x_top_spd)
player->vel.vx += player->cnst->x_air_accel; player->vel.vx += player->cnst->x_air_accel;
@ -1192,9 +1196,13 @@ player_update(Player *player)
// Fall off bottom of wall if no wall is found at Y + height radius // Fall off bottom of wall if no wall is found at Y + height radius
player_set_action(player, ACTION_DROP); player_set_action(player, ACTION_DROP);
} }
/* else if(!player->ev_clamber.collided) { */ else if(!player->ev_clamber.collided) {
/* // Clamber if no wall is found at Y - height radius */ // Clamber if no wall is found at Y - height radius
/* } */ player_set_action(player, ACTION_CLAMBER);
// Spinrev used as frame counter
player->framecount = 18;
player->vel.vx = player->vel.vy = player->vel.vz = 0;
}
else { else {
// Climbing movement // Climbing movement
if(input_pressing(&player->input, PAD_UP)) if(input_pressing(&player->input, PAD_UP))
@ -1212,6 +1220,24 @@ player_update(Player *player)
player->holding_jump = 1; player->holding_jump = 1;
} }
} }
} else if(player->action == ACTION_CLAMBER) {
// Clambering while still on air.
// Decrement framecount (set at the beginning to 16 frames).
// Once we reach six remaining frames, put player over
// platform
if(player->framecount > 0) {
player->framecount--;
if(player->framecount <= 6) {
int32_t x_dislocate = (HEIGHT_RADIUS_CLIMB + 1) << 12;
player->pos.vy -= HEIGHT_RADIUS_CLIMB << 12;
player->pos.vx += (x_dislocate * player->anim_dir);
}
}
// Finish clambering, usually when still not on ground.
// But we also have a failsafe ground action, see below.
if(player->framecount == 0)
player_set_action(player, ACTION_NONE);
} }
// Apply gravity // Apply gravity
@ -1230,17 +1256,24 @@ player_update(Player *player)
else player->vel.vy -= KNUX_GLIDE_GRAVITY; else player->vel.vy -= KNUX_GLIDE_GRAVITY;
break; break;
case ACTION_CLIMB: case ACTION_CLIMB:
case ACTION_CLAMBER:
// NO GRAVITY! // NO GRAVITY!
break; break;
default: default:
player->vel.vy += player->cnst->y_gravity; player->vel.vy += player->cnst->y_gravity;
break; break;
} }
} else { } else { // Y MOVEMENT, ON GROUND
if(input_pressed(&player->input, PAD_CROSS) if(player->action == ACTION_CLAMBER) {
// Failsafe for clambering while on ground.
// Finish frame count.
// When on 0, reset action
if(player->framecount > 0) player->framecount--;
else player_set_action(player, ACTION_NONE);
} else if(input_pressed(&player->input, PAD_CROSS)
&& (player->action != ACTION_SPINDASH) && (player->action != ACTION_SPINDASH)
&& (player->action != ACTION_PEELOUT)) { && (player->action != ACTION_PEELOUT)) {
// TODO: Review jump according to angle // Jump according to angle
player->vel.vx -= (player->cnst->y_jump_strength * rsin(player->angle)) >> 12; player->vel.vx -= (player->cnst->y_jump_strength * rsin(player->angle)) >> 12;
player->vel.vy -= (player->cnst->y_jump_strength * rcos(player->angle)) >> 12; player->vel.vy -= (player->cnst->y_jump_strength * rcos(player->angle)) >> 12;
player->grnd = 0; player->grnd = 0;
@ -1268,6 +1301,10 @@ player_update(Player *player)
else if(player->spinrev >= (player->underwater ? 15 : 10)) else if(player->spinrev >= (player->underwater ? 15 : 10))
player_set_animation_direct(player, ANIM_RUNNING); player_set_animation_direct(player, ANIM_RUNNING);
else player_set_animation_direct(player, ANIM_WALKING); else player_set_animation_direct(player, ANIM_WALKING);
} else if(player->action == ACTION_CLAMBER) {
// If grounded, then this means we climbed up the ledge and
// are just waiting for things to finish
player_set_animation_direct(player, ANIM_CLIMBEND);
} else if(player->col_ledge && input_pressing(&player->input, PAD_UP)) { } else if(player->col_ledge && input_pressing(&player->input, PAD_UP)) {
player_set_animation_direct(player, ANIM_LOOKUP); player_set_animation_direct(player, ANIM_LOOKUP);
player->idle_timer = ANIM_IDLE_TIMER_MAX; player->idle_timer = ANIM_IDLE_TIMER_MAX;
@ -1364,6 +1401,9 @@ player_update(Player *player)
else if(player->vel.vy < 0) else if(player->vel.vy < 0)
player_set_animation_direct(player, ANIM_CLIMBUP); player_set_animation_direct(player, ANIM_CLIMBUP);
else player_set_animation_direct(player, ANIM_CLIMBDOWN); else player_set_animation_direct(player, ANIM_CLIMBDOWN);
} else if(player->action == ACTION_CLAMBER) {
// We're clambering, but still on air!
player_set_animation_direct(player, ANIM_CLIMBRISE);
} else { } else {
// NO ACTION // NO ACTION
// Only handle cases where we have certain animations that would // Only handle cases where we have certain animations that would
@ -1376,6 +1416,8 @@ player_update(Player *player)
case ANIM_GLIDE: case ANIM_GLIDE:
case ANIM_GLIDETURNA: case ANIM_GLIDETURNA:
case ANIM_GLIDETURNB: case ANIM_GLIDETURNB:
case ANIM_CLIMBRISE:
case ANIM_CLIMBEND:
player_set_animation_direct(player, ANIM_WALKING); player_set_animation_direct(player, ANIM_WALKING);
break; break;
} }
@ -1445,7 +1487,14 @@ player_update(Player *player)
case ANIM_CLIMBUP: case ANIM_CLIMBUP:
case ANIM_CLIMBDOWN: case ANIM_CLIMBDOWN:
player_set_frame_duration(player, 4); player_set_frame_duration(player, 6);
break;
case ANIM_CLIMBRISE:
case ANIM_CLIMBEND:
if(anim_hash == ANIM_CLIMBRISE)
player->loopback_frame = 1;
player_set_frame_duration(player, 6);
break; break;
// Single-frame animations // Single-frame animations