diff --git a/lib/classes/movement_state_receiver.gd b/lib/classes/movement_state_receiver.gd index 3962523..e908c14 100644 --- a/lib/classes/movement_state_receiver.gd +++ b/lib/classes/movement_state_receiver.gd @@ -154,6 +154,8 @@ func _on_modifiers_updated(_modifier_type :int, _modifier_action :int, _merged_m #var calc_inertia = velocity.abs() #var calc_inertial_dir :Vector2 var debug_speed_tracker :Vector2 +var impulse_applied_dir :float = 0.0 +var impulse_applied :bool = false func new_move_actor_as_desired(_delta :float, _state :StateAnimatedActor, _movement_override_normal := Vector2(0,0), @@ -168,7 +170,7 @@ func new_move_actor_as_desired(_delta :float, # "_gravity" : _state.gravity # } var movement_parameters :MovementParameters = _state.get_movement_parameters() - if modifier: + if modifier and modifier.is_active: movement_parameters.apply_state_modifier(modifier) var calc_velocity = Vector2.ZERO @@ -183,21 +185,18 @@ func new_move_actor_as_desired(_delta :float, var calc_acceleration = Vector2.ZERO var calc_inertia :Vector2 - calc_inertia.x = abs(calc_velocity.x) + #calc_inertia.x = abs(calc_velocity.x) + ## We're now toing to preserve inertia direction + calc_inertia.x = calc_velocity.x calc_inertia.y = calc_velocity.y var calc_inertial_dir = Vector2(sign(calc_velocity.x),sign(calc_velocity.y)) - var calc_friction :Vector2 = Vector2.ZERO - - ## Inertia only applies if there is a difference between the - # base move speed and a derived move speed. This makes it so all you - # have to do is provide a move speed and that is the speed we will travel. - # but if a modifier applies, or an accelleration is given. - # an entirely differant process occurs. + #var calc_friction :Vector2 = Vector2.ZERO + + ## Determine movement direction + # If there is an inertia direction from existing velocity and + # no desired movement we'll continue to travel in that direction. ## - var h_speed = resolve_h_speed(movement_parameters) - #if h_speed != Vector2.ZERO: - # pass ## If an override has been passed (we're ignoring input direction var move_direction = Vector2.ZERO if _movement_override_normal != Vector2.ZERO: @@ -205,51 +204,83 @@ func new_move_actor_as_desired(_delta :float, else: move_direction = resolve_move_direction(calc_inertial_dir, desired_movement_vector) - ## Which direction will acceleration be applied. - calc_acceleration.x = resolve_h_acceleration(movement_parameters, calc_velocity, move_direction.x) + if move_direction.x != 0.0 or sign(calc_velocity.x) != impulse_applied_dir: + impulse_applied = false + impulse_applied_dir = sign(calc_velocity.x) + + + ## Inertia only applies if there is a difference between the + # base move speed and a derived move speed. This makes it so all you + # have to do is provide a move speed and that is the speed we will travel. + # but if a modifier applies, or an accelleration is given. + # an entirely differant process occurs. + # h_speed.x can be thought of as impulse speed. While h_speed.y + # is the destination speed. + # We move towards h_speed.y at the acceleration rate + ## + var h_speed = resolve_h_speed(movement_parameters) + ## Speed will now be expected to move in the direction of travel + h_speed *= move_direction.x + + ## We don't want to be able to scoot our impulse speed to cheat the movement + # Any non zero speed that goes opposite to our inertial direction + # should only be allowed once. + + ## Acceleration is always postive because we use the + # move toward functions. + calc_acceleration.x = abs(resolve_h_acceleration(movement_parameters, move_direction.x)) ## Direction of inertia not equal to move direction ## If inertia is applying in a direction - if calc_inertial_dir.x: - ## And it doesn't apply in the same direction as our movement direction - if calc_inertial_dir.x != sign(move_direction.x): - ## Apply the direction of acceleration and apply as friction - # Friction allows the inertia to trend toward 0 instead of the - # 'To' direction of speed. - ## - #calc_friction.x = calc_acceleration.x * -1 - calc_friction.x = abs(calc_acceleration.x) - calc_acceleration.x = 0.0 +# if calc_inertial_dir.x: +# ## And it doesn't apply in the same direction as our movement direction +# if calc_inertial_dir.x != sign(move_direction.x): +# ## Apply the direction of acceleration and apply as friction +# # Friction allows the inertia to trend toward 0 instead of the +# # 'To' direction of speed. +# ## +# #calc_friction.x = calc_acceleration.x * -1 +# calc_friction.x = abs(calc_acceleration.x) +# calc_acceleration.x = 0.0 ## We are always moving from h_speed.x towards y at a given rate - ## if we have a difference of speed - if h_speed.x != h_speed.y: + ## if we have a difference of speed and an acceleration + if h_speed.x != h_speed.y and calc_acceleration.x != 0.0: debug_speed_tracker = h_speed - ## Clamp inertia to in between speed. - # Problem is that we can suddenly gain or lose inertia. - ## -# calc_inertia.x = clamp( calc_inertia.x + (calc_acceleration.x * _delta), -# h_speed.x , h_speed.y) + ## Start speed really shouldn't be less than zero (modifiers can do this) - if h_speed.x < h_speed.y: - h_speed.x = clamp(h_speed.x,0.0,h_speed.y) +# if h_speed.x < h_speed.y: +# h_speed.x = clamp(h_speed.x,0.0,h_speed.y) + + ##TODO: Find a better way to apply impulse on target velocity changes. + ## Determine whether we should apply impulse ## If there is currently no inertia apply the base h_speed - if calc_inertia.x == 0.0: - calc_inertia.x = h_speed.x - elif calc_inertia.x != 0.0: - ##WIP: attempts to apply start speed only once - if h_speed.x < h_speed.y: - if calc_inertia.x < h_speed.x and sign(move_direction.x) == calc_inertial_dir.x: - calc_inertia.x = h_speed.x - elif h_speed.x > h_speed.y: - if calc_inertia.x > h_speed.x and sign(move_direction.x) == calc_inertial_dir.x: - calc_inertia.x = h_speed.x + ## If the direction of our inertia is different to our intended speed direction + # and the inertia is not already in range of the movement speed, apply impulse. + ## + if sign(calc_inertia.x) != sign(h_speed.x): + ## Only if inertia is not already in range. +# if calc_inertia.x <= h_speed.x or calc_inertia.x >= h_speed.y: + if is_out_of_range(calc_inertia.x, h_speed.x, h_speed.y): + ## ? But we only want to do this once though. + if impulse_applied == false: + calc_inertia.x += h_speed.x + impulse_applied = true + impulse_applied_dir = move_direction.x +# elif calc_inertia.x != 0.0: +# ##WIP: attempts to apply start speed only once +# if h_speed.x < h_speed.y: +# if calc_inertia.x < h_speed.x and sign(move_direction.x) == calc_inertial_dir.x: +# calc_inertia.x = h_speed.x +# elif h_speed.x > h_speed.y: +# if calc_inertia.x > h_speed.x and sign(move_direction.x) == calc_inertial_dir.x: +# calc_inertia.x = h_speed.x ## Apply acceleration - calc_inertia.x = move_toward(calc_inertia.x, h_speed.y, abs(calc_acceleration.x * _delta)) + calc_inertia.x = move_toward(calc_inertia.x, h_speed.y, calc_acceleration.x * _delta) ## Apply friction - calc_inertia.x = move_toward(calc_inertia.x, 0, abs(calc_friction.x * _delta)) + #calc_inertia.x = move_toward(calc_inertia.x, 0, abs(calc_friction.x * _delta)) if modifier and modifier.is_active: var foo = 2+2 # breakpoint check @@ -264,37 +295,12 @@ func new_move_actor_as_desired(_delta :float, # h_speed.y , h_speed.x) - elif calc_inertia.x != 0.0: ## We still have inertia but no difference in movement + elif calc_inertia.x != 0.0 and calc_acceleration.x != 0.0: ## We still have inertia but no difference in movement if h_speed.x < h_speed.y: h_speed.x = clamp(h_speed.x,0.0,h_speed.y) - if calc_acceleration.x != 0.0: # We are applying acceleration - ## Move back towards the base speed - calc_inertia.x = move_toward(calc_inertia.x, h_speed.x, abs(calc_acceleration.x * _delta)) - ## This was working but trying to simplify with just move_toward -# if calc_inertia.x < h_speed.x: -# calc_inertia.x = clamp( calc_inertia.x + ( calc_acceleration.x * _delta), -# calc_inertia.x, h_speed.x) -# else: -# calc_inertia.x = clamp( calc_inertia.x + ( calc_acceleration.x * _delta), -# h_speed.x, calc_inertia.x) - else: ## No longer applying acceleration - ## Neutralize the inertia? but how? - ## Recalc the acceleration with inertia - #var friction :Vector2 - calc_friction.x = resolve_h_acceleration(movement_parameters,Vector2(calc_inertia.x, h_speed.x), move_direction.x) - if calc_friction.x != 0.0: ## No dapening acceleration applies - #calc_inertia.x = move_toward(calc_inertia.x, h_speed.x, ( calc_friction.x * _delta)) - ## Apply friction - calc_inertia.x = move_toward(calc_inertia.x, 0, abs(calc_friction.x * _delta)) -# if calc_inertia.x < 0: -# calc_inertia.x = move_toward(calc_inertia.x, 0, abs(calc_friction.x * _delta)) -# if calc_inertia.x > 0: -# calc_inertia.x = move_toward(calc_inertia.x, 0, abs(calc_friction.x * _delta) * -1) - else: - ## no residual acceleration (friction) applies, kill the momentum - calc_inertia.x = 0.0 - calc_inertial_dir.x = 0.0 + ## Move back towards the base speed + calc_inertia.x = move_toward(calc_inertia.x, h_speed.x, calc_acceleration.x * _delta) # if (h_speed != debug_speed_tracker): # print("Inertia SpeedShift: ", debug_speed_tracker, h_speed, (0.0 == -0.0)) @@ -320,10 +326,12 @@ func new_move_actor_as_desired(_delta :float, #calc_velocity.x = calc_inertia.x * move_direction.x ## Control, direction can only be controlled when overcome inertia direction. - if calc_inertial_dir.x != 0: - calc_velocity.x = calc_inertia.x * calc_inertial_dir.x - else: - calc_velocity.x = calc_inertia.x * move_direction.x +# if calc_inertial_dir.x != 0: +# calc_velocity.x = calc_inertia.x * calc_inertial_dir.x +# else: +# calc_velocity.x = calc_inertia.x * move_direction.x + + calc_velocity.x = calc_inertia.x ## Attempting to move this to the top #calc_inertial_dir = Vector2(sign(calc_velocity.x),sign(calc_velocity.y)) @@ -333,7 +341,7 @@ func new_move_actor_as_desired(_delta :float, "\nVelocity_Calc: {0}, {1}".format({"0":"%5.2f" % calc_velocity.x, "1":"%5.2f" % calc_velocity.y}) + "\nInertia_Calc: {0}, {1}".format({"0":"%5.2f" % calc_inertia.x, "1":"%5.2f" % calc_inertia.y}) + "\nVelocity_Real: {0}, {1}".format({"0":"%5.2f" % velocity.x, "1":"%5.2f" % velocity.y}) + - "\nFriction: {0}, {1}".format({"0":"%5.2f" % calc_friction.x, "1":"%5.2f" % calc_friction.y}) + + #"\nFriction: {0}, {1}".format({"0":"%5.2f" % calc_friction.x, "1":"%5.2f" % calc_friction.y}) + "\nAccelCalc : {0}, {1}".format({"0":"%5.2f" % calc_acceleration.x, "1":"%5.2f" % calc_acceleration.y}) + #"\nLength: " + str(velocity.length()) + @@ -342,6 +350,11 @@ func new_move_actor_as_desired(_delta :float, return calc_velocity +func is_out_of_range(value: float, a: float, b: float) -> bool: + var lower = min(a, b) + var upper = max(a, b) + return value < lower or value > upper + ## 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: @@ -360,7 +373,7 @@ func resolve_h_speed(_params :MovementParameters) -> Vector2: return(Vector2(base_speed, speed_differance)) return Vector2(base_speed,base_speed) -func resolve_h_acceleration(_params :MovementParameters, _inertia :Vector2, _move_direction :float) -> float: +func resolve_h_acceleration(_params :MovementParameters, _move_direction :float) -> float: ## TODO: Adjust for jerk, determine if we're currently experiencing accel ## if a speed difference applies var _acceleration :float = 0.0 diff --git a/src/actors/players/playerE/PlayerE.gd b/src/actors/players/playerE/PlayerE.gd index 23acd4c..b211096 100644 --- a/src/actors/players/playerE/PlayerE.gd +++ b/src/actors/players/playerE/PlayerE.gd @@ -16,6 +16,7 @@ const state_stamina_cost :Dictionary = { "attack_sword":20, "attack_punch":10, "roll":40, + #"roll":4, "ledge_climb":10 }