Conversation
|
This works but is draft for now because StoryQuests have to be maintained, as a quick grep shows: |
|
Play this branch at https://play.threadbare.game/branches/endlessm/player-input/. (This launches the game from the start, not directly at the change(s) in this pull request.) |
|
This also fixes scenes which had Player mode still set to 1, which now means "system controlled". Ouch. It could be a separate PR but I did it here directly. |
wjt
left a comment
There was a problem hiding this comment.
Looks good. I think there is one thing that needs addressing:
| if mode in [Mode.SYSTEM_CONTROLLED, Mode.DEFEATED]: | ||
| func _set_speeds(new_speeds: CharacterSpeeds) -> void: | ||
| speeds = new_speeds | ||
| # speeds.changed.connect() |
There was a problem hiding this comment.
Did you mean to come back and connect something to speeds.changed?
There was a problem hiding this comment.
I think the reason to listen to this signal is to update the _initial_walk_speed and _initial_run_speed if the character's speed is changed in code, e.g. this is done in after the tremor. But... you would then need to ignore the signal when changing the speeds in _on_player_hook_aiming_changed.
There was a problem hiding this comment.
Oh thanks for finding the leftover. Yes indeed, I started questioning myself when I went to see after the tremor and thinking: what if we want to change speeds.walk_speed directly in a level? Should it update the initial walk speed that is being saved just to change it back after aiming with the grappling hook? Maybe we can revisit this when the problem arise, but we should think in decoupling the grapple.
There was a problem hiding this comment.
By the way for actually using speeds.changed.connect() I think we'll need to add setters to every exported property of Speeds and call emit_changed() in each.
| func _on_player_hook_aiming_changed(is_aiming: bool) -> void: | ||
| input_walk_behavior.speeds.walk_speed = aiming_speed if is_aiming else _initial_walk_speed | ||
| input_walk_behavior.speeds.run_speed = aiming_speed if is_aiming else _initial_run_speed |
There was a problem hiding this comment.
Another way to do this would be to swap the whole input_walk_behavior.speeds value out with a copy that is initialised in _ready with these changes. This is fine I think.
There was a problem hiding this comment.
Actually I had that at one point, using Resource.duplicate(). Let me check again if that's better before merging.
| func _process(_delta: float) -> void: | ||
| if not player: | ||
| return | ||
| if player.is_running() and not player.velocity.is_zero_approx(): | ||
| emitting = true | ||
| func _on_input_walk_behavior_running_changed(is_running: bool) -> void: | ||
| emitting = is_running | ||
| if emitting: | ||
| process_material.direction = Vector3(player.velocity.x, player.velocity.y, 0.0) | ||
| else: | ||
| emitting = false |
There was a problem hiding this comment.
I'm always kind of surprised that you can't do:
process_material.direction = Vector3(player.velocity, 0.0)i.e. a Vector3 ctor that takes a Vector2 and then 1 additional component.
There was a problem hiding this comment.
Indeed, it would be a nice addition to the Vector3 constructor.
| [connection signal="running_changed" from="InputWalkBehavior" to="PlayerDustParticles" method="_on_input_walk_behavior_running_changed"] | ||
| [connection signal="running_changed" from="InputWalkBehavior" to="AnimationPlayer" method="_on_input_walk_behavior_running_changed"] | ||
| [connection signal="body_entered" from="PlayerRepel/AirStream" to="PlayerRepel" method="_on_air_stream_body_entered"] | ||
| [connection signal="aiming_changed" from="PlayerHook" to="." method="_on_player_hook_aiming_changed"] | ||
| [connection signal="body_entered" from="PlayerHarm/HitBox" to="PlayerHarm" method="_on_hit_box_body_entered"] |
There was a problem hiding this comment.
I am still not totally sure (c.f. https://github.com/endlessm/threadbare/wiki/Contributing#connect-signals-to-callbacks-through-the-editor-interface) that this is preferred. These components are tightly coupled - player.gd doesn't work properly if these signals aren't connected, and it has references to all (?) these child nodes and calls methods on them, so IMO it would be clearer to connect the signals in code. But this isn't a firm conviction. At present it's no big deal because player.tscn and player.gd are also tightly coupled, so this is fine.
There was a problem hiding this comment.
I'm glad you raise this! What I wrote there is open to discussion. So maybe I should open a post in Discussions instead. Yes if we want to decouple the mechanics from player, this is not helping.
| walk_speed = 190.0 | ||
| run_speed = 200.0 | ||
| metadata/_custom_type_script = "uid://csev4hv57utxv" |
There was a problem hiding this comment.
I was about to say that the speeds resource should be saved so it can be shared between scenes, but the speeds are actually different in each scene!
Keep slowing down the player while the grappling hook is being used. For this, add a new aiming_changed signal to the PlayerHook. Also use the running_changed signal of InputWalkBehavior instead of checking constantly for: - Emitting the dust particles. - Doubling the frame-by-frame animation speed or using a special run animation.
Adapt to the speeds change. Also these instances have editable children to hide and disable the dust particles, but the node in that position is now the InputWalkBehavior, so switch it back to enabled and disable the dusts (2nd node) instead. Also remove mode=1 from players, because now that means "system controlled".
Adapt to the speeds change.
Because now that means "system controlled".
Keep slowing down the player while the grappling hook is being used. For this, add a new aiming_changed signal to the PlayerHook.
Also use the running_changed signal of InputWalkBehavior instead of checking constantly for:
Adapt the scenes and scripts in StoryQuests that had the player speeds set.
Resolve #1151