-- name: WallClimber -- description: Run, bounce, and jump off walls! local ACT_WALL_CLIMB = allocate_mario_action(ACT_FLAG_MOVING | ACT_FLAG_AIR) local prev_vel = {} local idx = 0 hook_mario_action(ACT_WALL_CLIMB, function(m) set_mario_animation(m, MARIO_ANIM_RUNNING) m.particleFlags = m.particleFlags | PARTICLE_DUST m.actionTimer = m.actionTimer + 1 m.marioObj.header.gfx.animInfo.animYTrans = 0 m.marioObj.header.gfx.animInfo.animAccel = 600000 m.vel.y = m.vel.y + 3 perform_air_step(m, 0) if (m.controller.buttonPressed & A_BUTTON) ~= 0 then m.vel.y = 20 m.forwardVel = 30 m.faceAngle.y = m.faceAngle.y - 65536 / 2 return set_mario_action(m, ACT_WALL_KICK_AIR, 0) end if m.vel.y < 5 then m.vel.y = 40 m.forwardVel = -30 return set_mario_action(m, ACT_BACKWARD_ROLLOUT, 0) end local hit_surface = collision_find_surface_on_ray(m.pos.x, m.pos.y + 60, m.pos.z, sins(m.faceAngle.y) * 70, 0, coss(m.faceAngle.y) * 70, 10).surface if hit_surface == nil then m.vel.y = 90 m.forwardVel = 10 return set_mario_action(m, ACT_FORWARD_ROLLOUT, 0) end end) hook_event(HOOK_MARIO_UPDATE, function(m) if m.action == ACT_WALL_CLIMB then m.marioObj.header.gfx.angle.x = -16384 end if m.playerIndex ~= 0 then return end if m.wall and m.floorHeight + 4 < m.pos.y then local wall_angle = atan2s(-m.wall.normal.z, -m.wall.normal.x) local mario_dir_x = sins(m.faceAngle.y) local mario_dir_z = coss(m.faceAngle.y) local dot = (mario_dir_x * m.wall.normal.x) + (mario_dir_z * m.wall.normal.z) if dot < -0.4 and m.action ~= ACT_WALL_CLIMB then m.faceAngle.y = wall_angle m.vel.x = 0 m.vel.z = 0 m.vel.y = 25 + prev_vel[m.playerIndex] / 4 set_mario_action(m, ACT_WALL_CLIMB, 0) end end prev_vel[m.playerIndex] = m.forwardVel end)