190 lines
6.8 KiB
GDScript
190 lines
6.8 KiB
GDScript
class_name Movement_StateReceiver
|
|
extends Node
|
|
|
|
## Movement component
|
|
# attempts to interact with movement of the scene root without knowing what
|
|
# it is. It can be perhaps a static body or kinematicbody
|
|
# it doesn't actually move a node, that's what the state machine does
|
|
# but it does keep track of velocity
|
|
# I can't give it an actor node or a direct reference.
|
|
# It can use a number of detection components to help inform decisions.
|
|
|
|
export var debug_component: bool = false
|
|
|
|
onready var current_state = StateAnimatedActor.new()
|
|
onready var parent: KinematicBody2D = get_parent()
|
|
|
|
export var callable_state_machine :NodePath
|
|
var request_state_change: FuncRef
|
|
|
|
var get_state_machine_modifiers: FuncRef #get_modifiers_of_type
|
|
|
|
onready var desired_movement_vector: Vector2 = Vector2(0,0)
|
|
|
|
# Since animactor state machine can actually view properties from this type
|
|
# I'm thinking about moving the velocity tracker in here instead of player.
|
|
#var velocity = Vector2(0,0)
|
|
var velocity_controller :VelocityController = VelocityController.new()
|
|
|
|
#Removing Probably not used
|
|
#var sim_velocity = Vector2(0,0)
|
|
var physics_delta:float
|
|
var process_delta:float
|
|
|
|
var modifier: StateModifierMovement
|
|
|
|
#Removing Probably not used
|
|
#var attack_function: FuncRef
|
|
|
|
const UP = -1.0
|
|
const DOWN = 1.0
|
|
const LEFT = -1.0
|
|
const RIGHT = 1.0
|
|
#const TILE_SIZE = 4
|
|
var FLOOR_ANGLE_THRESHOLD := deg2rad(60)
|
|
|
|
func _ready():
|
|
#velocity_controller.debug = true
|
|
|
|
## FuncRef to request state machine change state
|
|
request_state_change = funcref(get_node(callable_state_machine), 'change_to_known_state')
|
|
get_state_machine_modifiers = funcref(get_node(callable_state_machine), 'get_modifiers_of_type')
|
|
## Connect signal to get alerted of state change
|
|
get_node(callable_state_machine).connect("state_changed", self,"_on_state_change")
|
|
## Get notified when modifiers updated
|
|
get_node(callable_state_machine).connect("modifiers_updated",self,"_on_modifiers_updated")
|
|
## A reference to the current state machine state
|
|
current_state = get_node(callable_state_machine).current_state
|
|
## A reference to the state machine merged modifiers
|
|
#modifier = get_node(callable_state_machine).merged_animation_state_modifiers
|
|
|
|
############
|
|
## These get called by the parent
|
|
############
|
|
func process_physics(delta):
|
|
physics_delta = delta
|
|
if has_method('_state_process_physics_' + current_state.name):
|
|
call('_state_process_physics_' + current_state.name)
|
|
# else:
|
|
# move_actor_as_desired()
|
|
|
|
# more likely needed for Players
|
|
func process_physics_input(delta):
|
|
physics_delta = delta
|
|
desired_movement_vector = Vector2(0,0)
|
|
if has_method('_state_process_physics_input_' + current_state.name):
|
|
call('_state_process_physics_input_' + current_state.name)
|
|
|
|
# More likely needed for NPCs
|
|
func process(delta):
|
|
process_delta = delta
|
|
if has_method('_state_process_' + current_state.name):
|
|
call('_state_process_' + current_state.name)
|
|
|
|
# For event based input polling (Hadouken?)
|
|
func process_unhandled_input(event: InputEvent):
|
|
# Reset desired movement vector
|
|
desired_movement_vector = Vector2(0,0)
|
|
if has_method('_state_process_input_' + current_state.name):
|
|
call('_state_process_input_' + current_state.name)
|
|
|
|
############
|
|
|
|
############
|
|
## A Series of helper functions
|
|
############
|
|
func go_up():
|
|
desired_movement_vector.y = UP
|
|
func go_down():
|
|
desired_movement_vector.y = DOWN
|
|
func go_left():
|
|
desired_movement_vector.x = LEFT
|
|
func go_right():
|
|
desired_movement_vector.x = RIGHT
|
|
func stop():
|
|
desired_movement_vector = Vector2(0,0)
|
|
|
|
# Return the desired direction of movement for the character
|
|
# in the range [-1, 1], where positive values indicate a desire
|
|
# to move to the right and negative values to the left.
|
|
func get_movement_direction() -> float:
|
|
return desired_movement_vector.x
|
|
|
|
# Return a boolean indicating if the character wants to jump
|
|
func wants_jump() -> bool:
|
|
return false
|
|
|
|
# Return a boolean indicating if the character wants to attack
|
|
func wants_shoot() -> bool:
|
|
return false
|
|
|
|
# Return a boolean indicating if the character wants to dash
|
|
func wants_dash() -> bool:
|
|
return false
|
|
|
|
func wants_roll() -> bool:
|
|
return false
|
|
|
|
func wants_climb() -> bool:
|
|
return false
|
|
############
|
|
|
|
func get_climb_shape_location() -> Vector2:
|
|
return Vector2(-1,-1)
|
|
|
|
func _on_state_change(old_state_name:String, new_state :State):
|
|
###### State machine
|
|
if new_state is StateAnimatedActor: #Testing this. Update: It works
|
|
## Confirmed that I do neet to update the current_state with the passed state.
|
|
current_state = new_state
|
|
if has_method('_on_state_change_' + current_state.name):
|
|
call('_on_state_change_' + current_state.name)
|
|
else:
|
|
push_warning("Received non animated Actor state.")
|
|
#current_state = new_state
|
|
|
|
func _on_modifiers_updated(_modifier_type :int, _modifier_action :int, _merged_modifier :StateModifier):
|
|
## Get reference (subscribe) to the merged modifier for movement
|
|
if _merged_modifier is StateModifierMovement:
|
|
if debug_component:
|
|
print("Registered Modifier Movement: ", _merged_modifier.horizontal_speed)
|
|
modifier = _merged_modifier
|
|
|
|
func apply_state_modifier(movement_parameters :MovementParameters) -> MovementParameters:
|
|
# if modifier and modifier.is_active:
|
|
# if (current_state.is_grounded and modifier.only_grounded): # Should we skip
|
|
# movement_parameters.apply_state_modifier(modifier)
|
|
|
|
var active_mods :bool= true
|
|
var mods :Array = get_state_machine_modifiers.call_func('StateModifierMovement', active_mods, current_state.is_grounded)
|
|
if (mods.size() > 0):
|
|
## Process mods and supply current velocity for single directions
|
|
movement_parameters.apply_multiple_modifiers(mods, velocity_controller.velocity)
|
|
return movement_parameters
|
|
|
|
|
|
## Passed in acceleration, vel, etc is applied to whatever
|
|
## the parent is. If Kinematic then move_and_slide, otherwise manually adjusted
|
|
func apply_movement_to_parent( _velocity :Vector2) -> void:
|
|
#var snap = Vector2((_velocity.normalized().x * -1 * TILE_SIZE) ,DOWN * TILE_SIZE)
|
|
var snap = Vector2.DOWN #* TILE_SIZE
|
|
|
|
#var snap = Vector2.DOWN
|
|
## Disable snap when trying to jump (hacky?)
|
|
if !current_state.is_grounded:
|
|
snap = Vector2.ZERO
|
|
|
|
if parent is KinematicBody2D:
|
|
#velocity_controller.velocity = parent.move_and_slide_with_snap(_velocity, snap , Vector2.UP, true, 4, FLOOR_ANGLE_THRESHOLD)
|
|
#velocity_controller.velocity.x = parent.move_and_slide(_velocity,Vector2.UP,false,TILE_SIZE,FLOOR_ANGLE_THRESHOLD).x
|
|
velocity_controller.velocity = parent.move_and_slide_with_snap(_velocity, snap , Vector2.UP, true, 4, FLOOR_ANGLE_THRESHOLD)
|
|
if !parent.is_on_floor() and parent.get_slide_count() == 0:
|
|
var collision_to_floor = parent.get_floor_angle()
|
|
var collision_count = parent.get_slide_count()
|
|
var foo = 2+2
|
|
|
|
|
|
#move_and_slide_with_snap(linear_velocity: Vector2, snap: Vector2, up_direction: Vector2 = Vector2( 0, 0 ), stop_on_slope: bool = false, max_slides: int = 4, floor_max_angle: float = 0.785398, infinite_inertia: bool = true)
|
|
|
|
|