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"]: ##Bugfix: Both players 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 ##DONE: 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(): ##Bugfix if _wants_jump: 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') var _v :Vector2 = new_move_actor_as_desired( physics_delta , current_state ) apply_movement_to_parent(_v) 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(): ##TODO: Shoot should probably be more like how stun works # I'd like to not have to have an instance to the pew in this code. 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) apply_movement_to_parent(new_move_actor_as_desired( physics_delta , current_state, parent.transform.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() #apply_movement_to_parent(new_move_actor_as_desired( physics_delta , current_state )) func _state_process_physics_move(): # flip sprite in direction flip_sprite_to_movement_direction() if _wants_jump: 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') ## First version #move_actor_as_desired() ## Second One #var _v :Vector2 = new_move_actor_as_desired( physics_delta , current_state ) #apply_movement_to_parent(_v) apply_movement_to_parent(new_move_actor_as_desired( physics_delta , current_state )) 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 export variable # I used to call it 'jump_force' like an idiot. velocity.y = -200