diff options
author | metamuffin <metamuffin@disroot.org> | 2025-09-24 00:00:36 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-09-24 00:00:36 +0200 |
commit | a759c6743dccbc77464df91173b670339208afa4 (patch) | |
tree | 85bc7ccd49842372ba207e198f66b7942749fb1a /client | |
parent | 83903a571109a47d74d0be2892cc51ed8c26a335 (diff) | |
download | hurrycurry-a759c6743dccbc77464df91173b670339208afa4.tar hurrycurry-a759c6743dccbc77464df91173b670339208afa4.tar.bz2 hurrycurry-a759c6743dccbc77464df91173b670339208afa4.tar.zst |
Improve first person controller
Diffstat (limited to 'client')
-rw-r--r-- | client/gui/menus/game.gd | 11 | ||||
-rw-r--r-- | client/gui/menus/ingame.gd | 2 | ||||
-rw-r--r-- | client/gui/menus/menu.gd | 2 | ||||
-rw-r--r-- | client/player/controllable_player.gd | 53 | ||||
-rw-r--r-- | client/player/follow_camera.gd | 9 | ||||
-rw-r--r-- | client/project.godot | 2 |
6 files changed, 65 insertions, 14 deletions
diff --git a/client/gui/menus/game.gd b/client/gui/menus/game.gd index a730e385..0466d287 100644 --- a/client/gui/menus/game.gd +++ b/client/gui/menus/game.gd @@ -25,6 +25,8 @@ func _ready(): get_tree().get_root().go_back_requested.connect(open_ingame_menu) super() transition.set_loading_text(tr("c.menu.game.connecting")) + + Settings.hook_changed_init("gameplay.first_person", "mouse_lock", func (_a): update_mouse_capture()) func _input(_event): if Input.is_action_just_pressed("ui_menu"): @@ -55,8 +57,17 @@ func get_shot_path(template: String) -> String: return "%s/%s" % [path, filename] func _menu_cover(state): + super(state) game.follow_camera.disable_input_menu = state game.follow_camera.update_disable_input() + update_mouse_capture() +func _menu_exit(): + super() + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + +func update_mouse_capture(): + var cap = Settings.read("gameplay.first_person") and not covered + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED if cap else Input.MOUSE_MODE_VISIBLE func open_ingame_menu(): if popup != null: return diff --git a/client/gui/menus/ingame.gd b/client/gui/menus/ingame.gd index c9bbead9..133b6d8f 100644 --- a/client/gui/menus/ingame.gd +++ b/client/gui/menus/ingame.gd @@ -40,10 +40,12 @@ func _menu_open(): anim.play("activate") await anim.animation_finished game.mp.send_idle(true) + func _menu_exit(): game.mp.send_idle(false) anim.play_backwards("activate") await anim.animation_finished + func _menu_cover(state: bool): if Settings.read("ui.scale_mode") == "disabled": return # TODO perhaps check for overlap than scale_mode if state: anim.play_backwards("activate") diff --git a/client/gui/menus/menu.gd b/client/gui/menus/menu.gd index 0f6e0624..516b64bb 100644 --- a/client/gui/menus/menu.gd +++ b/client/gui/menus/menu.gd @@ -67,8 +67,8 @@ func submenu(path: String, data_ = null): print("Submenu opened ", path) await submenu_close print("Submenu closed ", path) - await _menu_cover(false) covered = false + await _menu_cover(false) Global.focused_menu = self _disable_recursive(self, false) if prev_focus != null: prev_focus.grab_focus() diff --git a/client/player/controllable_player.gd b/client/player/controllable_player.gd index 1700d900..ebc91488 100644 --- a/client/player/controllable_player.gd +++ b/client/player/controllable_player.gd @@ -57,6 +57,10 @@ func _ready(): game.mp.send_movement(game.my_player_id, position_, direction, boosting) ) add_child(onscreen_controls) + Settings.hook_changed_init("gameplay.first_person", "hide_head", func(fps): + character.head_default.visible = not fps + character.username_tag.visible = not fps + ) super() const MAX_DT = 1. / 50. @@ -69,22 +73,35 @@ func _process(delta): delta -= dt update_touch_scrolls() +func _input(event: InputEvent): + if Input.mouse_mode != Input.MOUSE_MODE_CAPTURED: return + if event is InputEventMouseMotion: + fps_look.x += event.relative.y * -0.001 + fps_look.y += event.relative.x * 0.001 + fps_look.x = max(-PI * 0.45, min(PI * 0.45, fps_look.x)) + if event is InputEventMouseButton: + var action = "" + match event.button_index: + MOUSE_BUTTON_LEFT: action = "interact_left" + MOUSE_BUTTON_RIGHT: action = "interact_right" + _: return + if event.pressed: Input.action_press(action) + else: Input.action_release(action) + + var moving_duration = 0 -var fps_rotation_target = 0 +var fps_look = Vector2(0., 0.) func _process_movement(delta): var input = Input.get_vector("left", "right", "forwards", "backwards") if is_input_enabled() else Vector2.ZERO - if Settings.read("gameplay.first_person"): - fps_rotation_target += input.x * delta * 3. - if abs(input.x) > 0.1: input.y -= 0.5 - input.x = 0. - input.y = min(input.y, 0) - input = input.rotated(fps_rotation_target) - else: - input = input.rotated(input_rotation) + if Settings.read("gameplay.first_person"): input = (input + Vector2(0.0, -0.1)).rotated(fps_look.y) + else: input = input.rotated(input_rotation) var boost = Input.is_action_pressed("boost") or (Settings.read("gameplay.latch_boost") and boosting) - if Input.is_action_pressed("interact_left") or Input.is_action_just_released("interact_left") or Input.is_action_pressed("interact_right") or Input.is_action_just_released("interact_right"): + if (Input.is_action_pressed("interact_left") + or Input.is_action_just_released("interact_left") + or Input.is_action_pressed("interact_right") + or Input.is_action_just_released("interact_right")): input *= 0 else: update_interact_target() @@ -229,6 +246,8 @@ func interact(): marker.visible = false func update_interact_target(): + if Settings.read("gameplay.first_person"): + return update_interact_target_fps() match Settings.read("gameplay.interact_target"): "dirsnap": return update_interact_target_dirsnap() "dir": return update_interact_target_dir() @@ -247,6 +266,20 @@ func update_interact_target_dir(): found_interact_target = false target_visual = Vector3(float(target_tile.x), 1., float(target_tile.y)) +func update_interact_target_fps(): + target_tile = Vector2i( + int(floor(movement_base.position.x + sin(-fps_look.y + PI))), + int(floor(movement_base.position.z + cos(-fps_look.y + PI))) + ) + var tile = game.map.get_tile_instance(target_tile) + if tile != null: + found_interact_target = game.get_tile_interactive(target_tile) + target_visual = tile.item_base.global_position + else: + found_interact_target = false + target_visual = Vector3(float(target_tile.x), 1., float(target_tile.y)) + + func update_interact_target_dirsnap(): var interact_target := Vector2( movement_base.position.x + sin(movement_base.rotation.y) * 0.7, diff --git a/client/player/follow_camera.gd b/client/player/follow_camera.gd index 804a9ebe..42670118 100644 --- a/client/player/follow_camera.gd +++ b/client/player/follow_camera.gd @@ -76,12 +76,17 @@ func zoom(zoom_dist: float) -> void: func follow(delta): if Settings.read("gameplay.first_person"): + var player = target.get_parent() + if not player is ControllablePlayer: return + fov = 80. global_position = target.global_position + Vector3.UP * 1.33 - rotation = target.rotation + Vector3(0,PI,0) + rotation.x = player.fps_look.x + rotation.y = -player.fps_look.y if target.get_parent() is ControllablePlayer: target.get_parent().input_rotation = -rotation.y return - + else: fov = 45. + var invert_factor = -1 if Settings.read("gameplay.invert_camera") else 1; if not _disable_input: diff --git a/client/project.godot b/client/project.godot index 16557b08..7646be34 100644 --- a/client/project.godot +++ b/client/project.godot @@ -168,7 +168,7 @@ reset={ } fullscreen={ "deadzone": 0.5, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194342,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194342,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } previous={ |