mirror of
https://github.com/JHDev2006/Super-Mario-Bros.-Remastered-Public.git
synced 2025-10-21 15:08:12 +00:00
304 lines
9.9 KiB
GDScript
304 lines
9.9 KiB
GDScript
extends PlayerState
|
|
|
|
var swim_up_meter := 0.0
|
|
|
|
var jump_queued := false
|
|
|
|
var jump_buffer := 0
|
|
|
|
var walk_frame := 0
|
|
|
|
var bubble_meter := 0.0
|
|
|
|
var wall_pushing := false
|
|
|
|
var can_wall_push := false
|
|
|
|
func enter(_msg := {}) -> void:
|
|
jump_queued = false
|
|
|
|
func physics_update(delta: float) -> void:
|
|
if player.is_actually_on_floor():
|
|
grounded(delta)
|
|
else:
|
|
in_air()
|
|
handle_movement(delta)
|
|
handle_animations()
|
|
handle_death_pits()
|
|
|
|
func handle_death_pits() -> void:
|
|
if player.global_position.y > 64 and not Level.in_vine_level and player.auto_death_pit and player.gravity_vector == Vector2.DOWN:
|
|
player.die(true)
|
|
elif player.global_position.y < Global.current_level.vertical_height - 32 and player.gravity_vector == Vector2.UP:
|
|
player.die(true)
|
|
|
|
func handle_movement(delta: float) -> void:
|
|
jump_buffer -= 1
|
|
if jump_buffer <= 0:
|
|
jump_queued = false
|
|
player.apply_gravity(delta)
|
|
if player.is_actually_on_floor():
|
|
var player_transform = player.global_transform
|
|
player_transform.origin += Vector2.UP * 1
|
|
if player.is_actually_on_floor():
|
|
handle_ground_movement(delta)
|
|
elif player.in_water or player.flight_meter > 0:
|
|
handle_swimming(delta)
|
|
else:
|
|
handle_air_movement(delta)
|
|
player.move_and_slide()
|
|
player.moved.emit()
|
|
|
|
func grounded(delta: float) -> void:
|
|
player.jump_cancelled = false
|
|
if player.velocity.y >= 0:
|
|
player.has_jumped = false
|
|
if Global.player_action_just_pressed("jump", player.player_id):
|
|
player.handle_water_detection()
|
|
if player.in_water or player.flight_meter > 0:
|
|
swim_up()
|
|
return
|
|
else:
|
|
player.jump()
|
|
if jump_queued and not (player.in_water or player.flight_meter > 0):
|
|
if player.spring_bouncing == false:
|
|
player.jump()
|
|
jump_queued = false
|
|
if not player.crouching:
|
|
if Global.player_action_pressed("move_down", player.player_id):
|
|
player.crouching = true
|
|
else:
|
|
can_wall_push = player.test_move(player.global_transform, Vector2.UP * 8 * player.gravity_vector.y) and player.power_state.hitbox_size != "Small"
|
|
if Global.player_action_pressed("move_down", player.player_id) == false:
|
|
if can_wall_push:
|
|
wall_pushing = true
|
|
else:
|
|
wall_pushing = false
|
|
player.crouching = false
|
|
else:
|
|
player.crouching = true
|
|
wall_pushing = false
|
|
if wall_pushing:
|
|
player.global_position.x += (-50 * player.direction * delta)
|
|
|
|
func handle_ground_movement(delta: float) -> void:
|
|
if player.skidding:
|
|
ground_skid(delta)
|
|
elif (player.input_direction != player.velocity_direction) and player.input_direction != 0 and abs(player.velocity.x) > player.SKID_THRESHOLD and not player.crouching:
|
|
print([player.input_direction, player.velocity_direction])
|
|
player.skidding = true
|
|
elif player.input_direction != 0 and not player.crouching:
|
|
ground_acceleration(delta)
|
|
else:
|
|
deceleration(delta)
|
|
|
|
func ground_acceleration(delta: float) -> void:
|
|
var target_move_speed := player.WALK_SPEED
|
|
if player.in_water or player.flight_meter > 0:
|
|
target_move_speed = player.SWIM_GROUND_SPEED
|
|
var target_accel := player.GROUND_WALK_ACCEL
|
|
if (Global.player_action_pressed("run", player.player_id) and abs(player.velocity.x) >= player.WALK_SPEED) and (not player.in_water and player.flight_meter <= 0) and player.can_run:
|
|
target_move_speed = player.RUN_SPEED
|
|
target_accel = player.GROUND_RUN_ACCEL
|
|
if player.input_direction != player.velocity_direction:
|
|
if Global.player_action_pressed("run", player.player_id) and player.can_run:
|
|
target_accel = player.RUN_SKID
|
|
else:
|
|
target_accel = player.WALK_SKID
|
|
player.velocity.x = move_toward(player.velocity.x, target_move_speed * player.input_direction, (target_accel / delta) * delta)
|
|
|
|
func deceleration(delta: float) -> void:
|
|
player.velocity.x = move_toward(player.velocity.x, 0, (player.DECEL / delta) * delta)
|
|
|
|
func ground_skid(delta: float) -> void:
|
|
var target_skid := player.RUN_SKID
|
|
player.skid_frames += 1
|
|
player.velocity.x = move_toward(player.velocity.x, 1 * player.input_direction, (target_skid / delta) * delta)
|
|
if abs(player.velocity.x) < 10 or player.input_direction == player.velocity_direction or player.input_direction == 0:
|
|
player.skidding = false
|
|
player.skid_frames = 0
|
|
|
|
func in_air() -> void:
|
|
if Global.player_action_just_pressed("jump", player.player_id):
|
|
if player.in_water or player.flight_meter > 0:
|
|
swim_up()
|
|
else:
|
|
jump_queued = true
|
|
jump_buffer = 4
|
|
|
|
func handle_air_movement(delta: float) -> void:
|
|
if player.input_direction != 0 and player.velocity_direction != player.input_direction:
|
|
air_skid(delta)
|
|
if player.input_direction != 0:
|
|
air_acceleration(delta)
|
|
|
|
if Global.player_action_pressed("jump", player.player_id) == false and player.has_jumped and not player.jump_cancelled:
|
|
player.jump_cancelled = true
|
|
if sign(player.gravity_vector.y * player.velocity.y) < 0.0:
|
|
player.velocity.y /= player.JUMP_CANCEL_DIVIDE
|
|
player.gravity = player.FALL_GRAVITY
|
|
|
|
func air_acceleration(delta: float) -> void:
|
|
var target_speed = player.WALK_SPEED
|
|
if abs(player.velocity.x) >= player.WALK_SPEED and Global.player_action_pressed("run", player.player_id) and player.can_run:
|
|
target_speed = player.RUN_SPEED
|
|
player.velocity.x = move_toward(player.velocity.x, target_speed * player.input_direction, (player.AIR_ACCEL / delta) * delta)
|
|
|
|
func air_skid(delta: float) -> void:
|
|
player.velocity.x = move_toward(player.velocity.x, 1 * player.input_direction, (player.AIR_SKID / delta) * delta)
|
|
|
|
func handle_swimming(delta: float) -> void:
|
|
bubble_meter += delta
|
|
if bubble_meter >= 1 and player.flight_meter <= 0:
|
|
player.summon_bubble()
|
|
bubble_meter = 0
|
|
swim_up_meter -= delta
|
|
player.skidding = (player.input_direction != player.velocity_direction) and player.input_direction != 0 and abs(player.velocity.x) > 100 and not player.crouching
|
|
if player.skidding:
|
|
ground_skid(delta)
|
|
elif player.input_direction != 0 and not player.crouching:
|
|
swim_acceleration(delta)
|
|
else:
|
|
deceleration(delta)
|
|
|
|
func swim_acceleration(delta: float) -> void:
|
|
player.velocity.x = move_toward(player.velocity.x, player.SWIM_SPEED * player.input_direction, (player.GROUND_WALK_ACCEL / delta) * delta)
|
|
|
|
func swim_up() -> void:
|
|
if player.swim_stroke:
|
|
player.play_animation("SwimIdle")
|
|
player.velocity.y = -player.SWIM_HEIGHT * player.gravity_vector.y
|
|
AudioManager.play_sfx("swim", player.global_position)
|
|
swim_up_meter = 0.5
|
|
player.crouching = false
|
|
|
|
func handle_animations() -> void:
|
|
if (player.is_actually_on_floor() or player.in_water or player.flight_meter > 0 or player.can_air_turn) and player.input_direction != 0 and not player.crouching:
|
|
player.direction = player.input_direction
|
|
var animation = get_animation_name()
|
|
player.sprite.speed_scale = 1
|
|
if ["Walk", "Move", "Run"].has(animation):
|
|
player.sprite.speed_scale = abs(player.velocity.x) / 40
|
|
player.play_animation(animation)
|
|
if player.sprite.animation == "Move":
|
|
walk_frame = player.sprite.frame
|
|
player.sprite.scale.x = player.direction * player.gravity_vector.y
|
|
|
|
func get_animation_name() -> String:
|
|
if player.attacking:
|
|
if player.crouching:
|
|
return "CrouchAttack"
|
|
elif player.is_actually_on_floor():
|
|
if player.skidding:
|
|
return "SkidAttack"
|
|
elif abs(player.velocity.x) >= 5 and not player.is_actually_on_wall():
|
|
if player.in_water:
|
|
return "SwimAttack"
|
|
elif player.flight_meter > 0:
|
|
return "FlyAttack"
|
|
elif abs(player.velocity.x) < player.RUN_SPEED - 10:
|
|
return "WalkAttack"
|
|
else:
|
|
return "RunAttack"
|
|
else:
|
|
return "IdleAttack"
|
|
else:
|
|
if player.in_water:
|
|
return "SwimAttack"
|
|
elif player.flight_meter > 0:
|
|
return "FlyAttack"
|
|
else:
|
|
return "AirAttack"
|
|
if player.kicking and player.can_kick_anim:
|
|
return "Kick"
|
|
if player.crouching and not wall_pushing:
|
|
if player.bumping:
|
|
return "CrouchBump"
|
|
elif player.is_on_floor() == false:
|
|
if player.velocity.y > 0:
|
|
return "CrouchFall"
|
|
elif player.velocity.y < 0:
|
|
return "CrouchJump"
|
|
elif player.is_actually_on_floor():
|
|
if abs(player.velocity.x) >= 5 and not player.is_actually_on_wall():
|
|
return "CrouchMove"
|
|
elif player.in_water:
|
|
return "WaterCrouch"
|
|
elif player.flight_meter > 0:
|
|
return "WingCrouch"
|
|
else:
|
|
return "Crouch"
|
|
if player.is_actually_on_floor():
|
|
if player.skidding:
|
|
return "Skid"
|
|
elif abs(player.velocity.x) >= 5 and not player.is_actually_on_wall():
|
|
if player.in_water:
|
|
return "WaterMove"
|
|
elif player.flight_meter > 0:
|
|
return "WingMove"
|
|
elif abs(player.velocity.x) < player.RUN_SPEED - 10:
|
|
return "Walk"
|
|
else:
|
|
return "Run"
|
|
else:
|
|
if Global.player_action_pressed("move_up", player.player_id):
|
|
if player.in_water:
|
|
return "WaterLookUp"
|
|
elif player.flight_meter > 0:
|
|
return "WingLookUp"
|
|
else:
|
|
return "LookUp"
|
|
else:
|
|
if player.in_water:
|
|
return "WaterIdle"
|
|
elif player.flight_meter > 0:
|
|
return "WingIdle"
|
|
else:
|
|
return "Idle"
|
|
else:
|
|
if player.in_water:
|
|
if swim_up_meter > 0:
|
|
if player.bumping and player.can_bump_swim:
|
|
return "SwimBump"
|
|
else:
|
|
return "SwimUp"
|
|
else:
|
|
return "SwimIdle"
|
|
elif player.flight_meter > 0:
|
|
if swim_up_meter > 0:
|
|
if player.bumping and player.can_bump_fly:
|
|
return "FlyBump"
|
|
else:
|
|
return "FlyUp"
|
|
else:
|
|
return "FlyIdle"
|
|
if player.has_jumped:
|
|
if player.bumping and player.can_bump_jump:
|
|
if abs(player.velocity_x_jump_stored) < player.RUN_SPEED - 10:
|
|
return "RunJumpBump"
|
|
else:
|
|
return "JumpBump"
|
|
elif player.velocity.y < 0:
|
|
if player.is_invincible:
|
|
return "StarJump"
|
|
elif abs(player.velocity_x_jump_stored) < player.RUN_SPEED - 10:
|
|
return "RunJump"
|
|
else:
|
|
return "Jump"
|
|
else:
|
|
if player.is_invincible:
|
|
return "StarFall"
|
|
elif abs(player.velocity_x_jump_stored) < player.RUN_SPEED - 10:
|
|
return "RunJumpFall"
|
|
else:
|
|
return "JumpFall"
|
|
else:
|
|
# guzlad: Fixes characters with fall anims not playing them, but also prevents old characters without that anim not being accurate
|
|
if !player.sprite.sprite_frames.has_animation("Fall"):
|
|
player.sprite.frame = walk_frame
|
|
return "Fall"
|
|
|
|
func exit() -> void:
|
|
owner.on_hammer_timeout()
|
|
owner.skidding = false
|