436 lines
13 KiB
GDScript
436 lines
13 KiB
GDScript
extends Movement_StateReceiver
|
|
|
|
var parent_request_state_change :FuncRef
|
|
var parent_use_primary_item :FuncRef
|
|
|
|
var player_number: int = 1
|
|
|
|
onready var pew_machine = $"%PewMachine"
|
|
onready var stamina_component = $"%Stamina_Component"
|
|
|
|
var state_stamina_cost :Dictionary
|
|
|
|
func _ready():
|
|
var state_ref :State
|
|
var state_name :String
|
|
state_name = 'jump'
|
|
state_ref = get_node(callable_state_machine).get_state_reference(state_name)
|
|
#TODO Should probably assert here or something.
|
|
state_ref.connect("state_entered", self, "_on_state_entered_" + state_name)
|
|
parent_request_state_change = funcref(get_node(callable_state_machine), 'check_parent_before_state_change')
|
|
|
|
if parent.has_method("use_primary_item"):
|
|
parent_use_primary_item = funcref(parent, "use_primary_item")
|
|
|
|
# Lets see if this nutty thing works
|
|
# var state_ref :State = get_node(callable_state_machine).get_state_reference('idle')
|
|
# state_ref.connect("state_entered", self, "_on_state_entered_idle")
|
|
# It works but node order really mattered.
|
|
# State machine needed to be processed first probably for ready function.
|
|
# good to know!
|
|
player_number = parent.player_number
|
|
|
|
|
|
func get_movement_direction() -> float:
|
|
#return Input.get_axis('move_left', 'move_right')
|
|
desired_movement_vector.x = Input.get_axis("move_left_" + str(player_number), "move_right_" + str(player_number))
|
|
return Input.get_axis("move_left_" + str(player_number), "move_right_" + str(player_number))
|
|
|
|
var _wants_jump :bool
|
|
func wants_jump() -> bool:
|
|
if Input.is_action_just_pressed("jump_" + str(player_number)) and stamina_component.stamina >= state_stamina_cost["jump"]:
|
|
desired_movement_vector.y = UP
|
|
_wants_jump = true
|
|
return true
|
|
else:
|
|
_wants_jump = false
|
|
return false
|
|
|
|
var _wants_crouch :bool
|
|
func wants_crouch() -> bool:
|
|
if Input.is_action_pressed("crouch_" + str(player_number)):
|
|
_wants_crouch = true
|
|
return true
|
|
else:
|
|
_wants_crouch = false
|
|
return false
|
|
|
|
var _wants_attack_primary :bool
|
|
func wants_attack_primary() -> bool:
|
|
if Input.is_action_just_pressed("attack_" + str(player_number)):
|
|
_wants_attack_primary = true
|
|
return true
|
|
else:
|
|
_wants_attack_primary = false
|
|
return false
|
|
|
|
var _wants_attack_secondary :bool
|
|
func wants_attack_secondary() -> bool:
|
|
if Input.is_action_just_pressed("attack_secondary_" + str(player_number)):
|
|
_wants_attack_secondary = true
|
|
return true
|
|
else:
|
|
_wants_attack_secondary = false
|
|
return false
|
|
|
|
var _wants_dash :bool
|
|
func wants_dash() -> bool:
|
|
if Input.is_action_just_pressed("dash_" + str(player_number)):
|
|
_wants_dash = true
|
|
return true
|
|
else:
|
|
_wants_dash = false
|
|
return false
|
|
|
|
var _wants_roll :bool
|
|
func wants_roll() -> bool:
|
|
if Input.is_action_just_pressed("dash_" + str(player_number)) and Input.is_action_pressed("move_up_" + str(player_number)):
|
|
if parent.enough_stamina_for("roll"):
|
|
_wants_roll = true
|
|
return true
|
|
_wants_roll = false
|
|
return false
|
|
|
|
var _wants_climb :bool
|
|
func wants_climb() -> bool:
|
|
if Input.is_action_pressed("move_up_" + str(player_number)):
|
|
_wants_climb = true
|
|
return true
|
|
else:
|
|
_wants_climb = false
|
|
return false
|
|
|
|
#TODO: This is probably not a good way to do this.
|
|
# we want to check input once and make decisions based on
|
|
# velocity and desired movement.
|
|
#func _state_process_physics_input_idle():
|
|
# get_movement_direction()
|
|
#
|
|
#func _state_process_physics_input_move():
|
|
# get_movement_direction()
|
|
|
|
# Probably better to do it this way then allocating individual
|
|
# state functions that all do the same thing.
|
|
func process_physics_input(delta):
|
|
# call the parent, Which would call the individuals
|
|
.process_physics_input(delta)
|
|
# then process movement controls
|
|
physics_delta = delta
|
|
get_movement_direction()
|
|
wants_jump()
|
|
wants_crouch()
|
|
wants_attack_primary()
|
|
wants_attack_secondary()
|
|
wants_dash()
|
|
wants_roll()
|
|
wants_climb()
|
|
|
|
func flip_sprite_to_movement_direction():
|
|
if desired_movement_vector.x != 0.0:
|
|
parent.transform.x.x = desired_movement_vector.x
|
|
|
|
func _state_process_physics_idle():
|
|
if desired_movement_vector.y == UP:
|
|
request_state_change.call_func('jump')
|
|
|
|
if _wants_crouch == true:
|
|
request_state_change.call_func('crouch')
|
|
#TODO: May need that 'bump' logic to make velocity work.
|
|
if desired_movement_vector.x != 0: # and velocity.x != 0:
|
|
request_state_change.call_func('move')
|
|
|
|
if !parent.is_on_floor():
|
|
#return fall_state
|
|
request_state_change.call_func('fall')
|
|
|
|
if _wants_roll == true:
|
|
request_state_change.call_func('roll')
|
|
|
|
if _wants_attack_primary == true:
|
|
#request_state_change.call_func('attack_shoot')
|
|
attack_primary()
|
|
|
|
if _wants_attack_secondary == true:
|
|
#parent_request_state_change.call_func('attack_sword')
|
|
attack_secondary()
|
|
|
|
if $"../LadderDetector".is_colliding() and _wants_climb == true:
|
|
request_state_change.call_func('climb')
|
|
|
|
func attack_primary():
|
|
##Another thing I wish I could avoid the funcref or string call
|
|
# if get_parent().has_method("use_primary_item"):
|
|
# var _item_state_name :String = get_parent().use_primary_item()
|
|
# if _item_state_name != '':
|
|
# request_state_change.call_func(_item_state_name)
|
|
if parent_use_primary_item.is_valid():
|
|
var _item_state_name :String = parent_use_primary_item.call_func()
|
|
if _item_state_name != '':
|
|
request_state_change.call_func(_item_state_name)
|
|
|
|
|
|
|
|
func attack_secondary():
|
|
if get_parent().has_method("use_secondary_item"):
|
|
var _item_state_name :String = get_parent().use_secondary_item()
|
|
if _item_state_name != '':
|
|
request_state_change.call_func(_item_state_name)
|
|
|
|
|
|
func _state_process_physics_attack_shoot():
|
|
|
|
if pew_machine.timer.time_left == 0:
|
|
pew_machine.shoot()
|
|
|
|
if current_state.animation_finished == true:
|
|
request_state_change.call_func('idle')
|
|
|
|
if !parent.is_on_floor():
|
|
#return fall_state
|
|
request_state_change.call_func('fall')
|
|
|
|
func _state_process_physics_attack_punch():
|
|
if current_state.animation_finished == true:
|
|
request_state_change.call_func('idle')
|
|
|
|
if !parent.is_on_floor():
|
|
#return fall_state
|
|
request_state_change.call_func('fall')
|
|
|
|
func _state_process_physics_attack_sword():
|
|
if current_state.animation_finished == true:
|
|
request_state_change.call_func('idle')
|
|
|
|
if !parent.is_on_floor():
|
|
#return fall_state
|
|
request_state_change.call_func('fall')
|
|
|
|
func _state_process_physics_roll():
|
|
if current_state.animation_finished == true:
|
|
request_state_change.call_func('idle')
|
|
|
|
# Force role in facing direction
|
|
# instead of movement direction
|
|
move_actor_as_desired(parent.transform.x.x)
|
|
|
|
if !parent.is_on_floor():
|
|
#return fall_state
|
|
request_state_change.call_func('fall')
|
|
|
|
var level_transition_latch: bool
|
|
var level_enter_dir: float
|
|
func _on_state_change_enter_right():
|
|
#desired_movement_vector.x = RIGHT
|
|
## Trying to do this in actor now.
|
|
#parent.transform.x.x = RIGHT
|
|
level_enter_dir = parent.transform.x.x
|
|
level_transition_latch = false
|
|
|
|
func _state_process_physics_enter_right():
|
|
#flip_sprite_to_movement_direction()
|
|
|
|
if current_state.state_timeout.time_left == 0 and level_transition_latch == false:
|
|
##TODO: Optionally flip direction
|
|
#parent.transform.x.x = LEFT
|
|
## Reset global position.
|
|
parent.global_position = LevelInfo.player_start_position
|
|
current_state.state_timeout.start()
|
|
level_transition_latch = true
|
|
elif current_state.state_timeout.time_left == 0 and level_transition_latch == true:
|
|
request_state_change.call_func('idle')
|
|
|
|
# Force role in facing direction
|
|
# instead of movement direction
|
|
move_actor_as_desired(parent.transform.x.x)
|
|
|
|
func _state_process_physics_land():
|
|
$"../LedgeDetector".set_enabled(true)
|
|
if current_state.animation_finished == true:
|
|
request_state_change.call_func('idle')
|
|
|
|
if !parent.is_on_floor():
|
|
#return fall_state
|
|
request_state_change.call_func('fall')
|
|
move_actor_as_desired()
|
|
|
|
func _state_process_physics_hurt():
|
|
if current_state.state_timeout.time_left == 0:
|
|
request_state_change.call_func('idle')
|
|
|
|
# if !parent.is_on_floor():
|
|
# #return fall_state
|
|
# request_state_change.call_func('fall')
|
|
velocity.y += current_state.gravity * physics_delta
|
|
#parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1))
|
|
velocity.x = parent.transform.x.x * -1 * current_state.horizontal_speed
|
|
# if (parent.direction.x > 0):
|
|
# parent.velocity.x = 1 * move_speed
|
|
# else:
|
|
# parent.velocity.x = -1 * move_speed
|
|
velocity = parent.move_and_slide(velocity, Vector2(0, -1))
|
|
|
|
|
|
func _state_process_physics_fall():
|
|
flip_sprite_to_movement_direction()
|
|
|
|
if $"../LedgeDetector".is_colliding() and !$"../WallDetector".is_colliding():
|
|
#print("it touched me!")
|
|
if debug_component:
|
|
UiManager.debug_text = (str($"../LedgeDetector".get_collision_point()))
|
|
request_state_change.call_func('ledge_grab')
|
|
|
|
if parent.is_on_floor():
|
|
#modifier.reference()
|
|
#idle_state.modifier = landing_modifier
|
|
request_state_change.call_func('land')
|
|
|
|
move_actor_as_desired()
|
|
|
|
func _state_process_physics_jump():
|
|
|
|
flip_sprite_to_movement_direction()
|
|
|
|
#Apparently we're instantly landing
|
|
# if parent.is_on_floor():
|
|
# #modifier.reference()
|
|
# #idle_state.modifier = landing_modifier
|
|
# request_state_change.call_func('idle')
|
|
if velocity.y > 0:
|
|
request_state_change.call_func('fall')
|
|
move_actor_as_desired()
|
|
|
|
func _state_process_physics_move():
|
|
# flip sprite in direction
|
|
flip_sprite_to_movement_direction()
|
|
|
|
if desired_movement_vector.y == UP:
|
|
request_state_change.call_func('jump')
|
|
|
|
if desired_movement_vector.x == 0:
|
|
request_state_change.call_func('idle')
|
|
|
|
if !parent.is_on_floor():
|
|
request_state_change.call_func('fall')
|
|
|
|
move_actor_as_desired()
|
|
|
|
func get_climb_shape_location() -> Vector2:
|
|
if $"../LadderDetector".is_colliding():
|
|
var point: Vector2 = $"../LadderDetector".get_collision_point()
|
|
var shape_id = $"../LadderDetector".get_collider_shape()
|
|
var object = $"../LadderDetector".get_collider()
|
|
|
|
# This appears to get the shapes location!
|
|
var area = Physics2DServer.area_get_transform(object)
|
|
var areashape = Physics2DServer.area_get_shape_transform(object, shape_id)
|
|
|
|
var y_dir = Input.get_axis("ui_up" , "ui_down")
|
|
var global_origin = areashape.origin + area.origin
|
|
return Vector2(global_origin.x, y_dir)
|
|
else:
|
|
return Vector2(-1,-1)
|
|
|
|
|
|
func _state_process_physics_climb():
|
|
#$"../LadderDetector".set_enabled(false)
|
|
|
|
var ladder_location = get_climb_shape_location()
|
|
if ladder_location != Vector2(-1,-1):
|
|
#UiManager.debug_text = str(ladder_location) + '\n' + str(ladder_location - parent.global_position) #+ '\n' + str(parent.global_position.distance_to(ladder_location))
|
|
# An attempt to snap to the ladder location
|
|
if parent.global_position.x != round(ladder_location.x):
|
|
parent.global_translate(Vector2(round((ladder_location.x - parent.global_position.x)),(ladder_location.y * current_state.horizontal_speed) * physics_delta))
|
|
if ladder_location.y != 0:
|
|
#print("singal that I'm climbing?")
|
|
current_state.movement_stopped = false
|
|
else:
|
|
#print("singal that I'm not climbing?")
|
|
current_state.movement_stopped = true
|
|
# Make sure we hopped the step index
|
|
# if animation_index > 0:
|
|
# animations.stop()
|
|
else:
|
|
return request_state_change.call_func('idle')
|
|
|
|
if _wants_crouch:
|
|
request_state_change.call_func('fall')
|
|
|
|
func _state_process_physics_ledge_grab():
|
|
if debug_component:
|
|
UiManager.debug_text = (str(velocity))
|
|
$"../LedgeDetector".set_enabled(false)
|
|
|
|
if _wants_jump:
|
|
request_state_change.call_func('ledge_climb')
|
|
|
|
if _wants_crouch:
|
|
request_state_change.call_func('fall')
|
|
|
|
func _state_process_physics_ledge_climb():
|
|
# $"../LedgeDetector".set_enabled(false)
|
|
|
|
if debug_component:
|
|
UiManager.debug_text = (str(parent.is_on_floor()) +
|
|
str(parent.is_on_wall()) + ")\nV:" + str(velocity))
|
|
|
|
if current_state.animation_finished == true:
|
|
request_state_change.call_func('land')
|
|
return
|
|
|
|
if parent.is_on_wall() == true:
|
|
#velocity = parent.move_and_slide(Vector2(10.0,-60.0),Vector2.UP)
|
|
parent.move_and_slide(Vector2(sign(parent.transform.x.x) * 10.0,-100.0),Vector2.UP)
|
|
else: #parent.is_on_floor() == true:
|
|
#velocity = parent.move_and_slide(Vector2(10.0,10.0),Vector2.UP)
|
|
parent.move_and_slide(Vector2(sign(parent.transform.x.x) * 60.0,10.0),Vector2.UP)
|
|
|
|
#velocity = parent.move_and_slide(Vector2(60.0,-60.0),Vector2.UP)
|
|
# if parent.is_on_wall() != true:
|
|
# #modifier.reference()
|
|
# #idle_state.modifier = landing_modifier
|
|
# request_state_change.call_func('land')
|
|
# return
|
|
|
|
|
|
func _state_process_physics_crouch():
|
|
# flip sprite in direction
|
|
flip_sprite_to_movement_direction()
|
|
|
|
if _wants_crouch != true:
|
|
request_state_change.call_func('idle')
|
|
|
|
if !parent.is_on_floor():
|
|
request_state_change.call_func('fall')
|
|
|
|
if _wants_crouch == true and desired_movement_vector.x != 0:
|
|
request_state_change.call_func('crouch_move')
|
|
elif desired_movement_vector.x != 0: # and velocity.x != 0:
|
|
request_state_change.call_func('move')
|
|
|
|
func _state_process_physics_crouch_move():
|
|
# flip sprite in direction
|
|
flip_sprite_to_movement_direction()
|
|
|
|
if _wants_crouch != true:
|
|
request_state_change.call_func('idle')
|
|
|
|
if !parent.is_on_floor():
|
|
request_state_change.call_func('fall')
|
|
|
|
if _wants_crouch == true and desired_movement_vector.x == 0:
|
|
request_state_change.call_func('crouch')
|
|
elif _wants_crouch != true and desired_movement_vector.x != 0:
|
|
request_state_change.call_func('move')
|
|
|
|
move_actor_as_desired()
|
|
|
|
#func _on_state_entered_idle():
|
|
# print("Movement State Idle State Entered!")
|
|
|
|
func _on_state_entered_jump():
|
|
#TODO: Make this a state variable
|
|
# I used to call it 'jump_force' like an idiot.
|
|
velocity.y = -200
|
|
|
|
|