diff options
author | tpart <tpart120@proton.me> | 2025-06-18 22:29:59 +0200 |
---|---|---|
committer | tpart <tpart120@proton.me> | 2025-06-18 22:30:03 +0200 |
commit | 05fe59c831a5f1b7f0666d617f275a86a6ce4d35 (patch) | |
tree | 9f0e0c16e390486611dbbbe3b7ac2748339d011c /client/player | |
parent | dc86da97ca960ce2ecebb3fde3c4122a56529bb8 (diff) | |
download | hurrycurry-05fe59c831a5f1b7f0666d617f275a86a6ce4d35.tar hurrycurry-05fe59c831a5f1b7f0666d617f275a86a6ce4d35.tar.bz2 hurrycurry-05fe59c831a5f1b7f0666d617f275a86a6ce4d35.tar.zst |
Consider players interact targets; Rewrite a lot of interact target code; Fix #321
Diffstat (limited to 'client/player')
-rw-r--r-- | client/player/controllable_player.gd | 82 | ||||
-rw-r--r-- | client/player/player.gd | 3 |
2 files changed, 62 insertions, 23 deletions
diff --git a/client/player/controllable_player.gd b/client/player/controllable_player.gd index fbc09859..126e4c10 100644 --- a/client/player/controllable_player.gd +++ b/client/player/controllable_player.gd @@ -23,6 +23,7 @@ const PLAYER_FRICTION = 15 const BOOST_FACTOR = 2.5 const BOOST_DURATION = 0.3 const BOOST_RESTORE = 0.5 +const MAX_PLAYER_INTERACT_DIST := 1.9 var onscreen_controls = preload("res://player/onscreen_controls/controls.tscn").instantiate() @@ -38,7 +39,10 @@ var vibration_timer := Timer.new() var current_vibration_strength := 0. var current_vibration_change := 0. -var target: Vector2i = Vector2i(0, 0) +var target_tile: Vector2i = Vector2i.ZERO +var target_visual: Vector3 = Vector3.ZERO +var found_interact_target := false + var last_interaction = null func _ready(): @@ -53,7 +57,7 @@ func _ready(): timer.start() timer.connect("timeout", func(): if game.mp != null and game.join_state == Game.JoinState.JOINED: - game.mp.send_movement(game.player_id, position_, direction, boosting) + game.mp.send_movement(game.my_player_id, position_, direction, boosting) ) add_child(onscreen_controls) super() @@ -61,7 +65,7 @@ func _ready(): const MAX_DT = 1. / 50. func _process(delta): super(delta) - marker.position = G.interpolate(marker.position, marker_target, delta * 30.) + marker.position = G.interpolate(marker.position, target_visual, delta * 30.) while delta > 0.001: var dt = min(delta, MAX_DT) _process_movement(dt) @@ -86,7 +90,9 @@ func _process_movement(delta): 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: - target = get_interact_target() + var targets := get_interact_target() + target_visual = targets[0] + target_tile = targets[1] # target = Vector2i( # int(floor(movement_base.position.x + sin(movement_base.rotation.y))), # int(floor(movement_base.position.z + cos(movement_base.rotation.y))) @@ -205,52 +211,84 @@ func take_item(tile: Tile, h: int): func interact(): if not is_input_enabled(): return - var tile = game.map.get_tile_instance(target) + + var tile = game.map.get_tile_instance(target_tile) if tile != null: marker.visible = true - # clear last interaction if target has moved since - if last_interaction != null and not last_interaction == target: - game.mp.send_tile_interact(game.player_id, last_interaction, false, 0) + # clear last interaction if target_tile has moved since + if last_interaction != null and not last_interaction == target_tile: + game.mp.send_tile_interact(game.my_player_id, last_interaction, false, 0) marker.set_interacting(false) last_interaction = null - marker.set_interactive(game.get_tile_interactive(target)) - marker_target = tile.item_base.global_position + marker.set_interactive(found_interact_target) for h in [0, 1]: if Input.is_action_just_pressed("interact_"+G.index_to_hand(h)) and last_interaction == null: - last_interaction = target - game.mp.send_tile_interact(game.player_id, target, true, h) + last_interaction = target_tile + game.mp.send_tile_interact(game.my_player_id, target_tile, true, h) tile.interact() marker.set_interacting(true) if Input.is_action_just_released("interact_"+G.index_to_hand(h)): last_interaction = null - game.mp.send_tile_interact(game.player_id, target, false, h) + game.mp.send_tile_interact(game.my_player_id, target_tile, false, h) marker.set_interacting(false) else: marker.visible = false -func get_interact_target() -> Vector2i: +func get_interact_target() -> Array: # -> [visual_target: Vector3, tile_target: Vector2i] var interact_target := Vector2( movement_base.position.x + sin(movement_base.rotation.y) * 0.7, movement_base.position.z + cos(movement_base.rotation.y) * 0.7 ) - var interact_target_i := Vector2i(interact_target.floor()) - var best_cursor := interact_target_i + var interact_target_i := interact_target.floor() + var best_cursor_visual := Vector3(interact_target_i.x, 0, interact_target_i.y) + var best_cursor_i := interact_target_i var best_distance := 100. - + found_interact_target = false + + # Calculate player positions. Tiles with players on them are valid interact targets. + var player_positions: Dictionary = {} # Dictionary[id: int, pos: Vector3] + for p: Player in game.players.values(): + player_positions[p.id] = Vector3(p.position_anim.x, 0, p.position_anim.y) + + # Test all tiles in a 3x3 square around the player for interactible tiles. + # Return the one which is closest to interact_target. for offset_x in range(-1,1): for offset_y in range (-1, 1): - var offset_cursor := interact_target_i + Vector2i(offset_x, offset_y) + var offset_cursor := interact_target_i + Vector2(offset_x, offset_y) + var tile_center := Vector2(offset_cursor) + Vector2(0.5, 0.5) if game.get_tile_interactive(offset_cursor): - var tile_center := Vector2(offset_cursor) + Vector2(0.5, 0.5) var cursor_tile_distance := (interact_target - tile_center).length() var player_tile_distance := Vector2( movement_base.position.x - tile_center.x, movement_base.position.z - tile_center.y ).length() - if player_tile_distance < 1.9 && cursor_tile_distance < best_distance: + if player_tile_distance < MAX_PLAYER_INTERACT_DIST && cursor_tile_distance < best_distance: + found_interact_target = true best_distance = cursor_tile_distance - best_cursor = offset_cursor + best_cursor_visual = game.map.get_tile_instance(offset_cursor).item_base.global_position + best_cursor_i = offset_cursor + continue + + # Check if there are any players on this tile. + # If there are multilpe, remember the player closest to the center of the tile + # (They will be the interact target) + var best_player_tile_distance := 100. + var best_player_pos: Vector3 + for p_id: int in player_positions.keys(): + if p_id == game.my_player_id: continue # I can't interact with myself + var p_pos: Vector3 = player_positions[p_id] + var p_pos_2d := Vector2(p_pos.x, p_pos.z) + var distance := p_pos_2d.distance_to(tile_center) + if distance < 0.7: + if distance < best_player_tile_distance: + best_player_tile_distance = distance + best_player_pos = p_pos + if best_player_tile_distance < MAX_PLAYER_INTERACT_DIST && best_player_tile_distance < best_distance: + found_interact_target = true + best_distance = best_player_tile_distance + best_cursor_visual = best_player_pos + best_cursor_i = offset_cursor - return best_cursor + return [best_cursor_visual, best_cursor_i] diff --git a/client/player/player.gd b/client/player/player.gd index 265c1d65..c82cf6e6 100644 --- a/client/player/player.gd +++ b/client/player/player.gd @@ -22,6 +22,7 @@ const PLAYER_SIZE: float = 0.4 const SPEED: float = 25. var game: Game +var id := -1 var rotation_ = 0. var rotation_anim = 0. var position_ = Vector2(0, 0) @@ -37,7 +38,6 @@ var chat_bubble: ChatBubble = preload("res://player/chat_bubble.tscn").instantia var item_bubble: ItemBubble = preload("res://player/item_bubble.tscn").instantiate() var effect: Effect = preload("res://player/particles/effect.tscn").instantiate() var marker: Marker = preload("res://player/marker/marker.tscn").instantiate() -var marker_target = Vector3(0, 0, 0) var clear_timer: Timer = Timer.new() @@ -56,6 +56,7 @@ const DEFAULT_HAND_BASE_POSITION_LEFT: Vector3 = Vector3(.3, .425, .4) const DEFAULT_HAND_BASE_POSITION_RIGHT: Vector3 = Vector3(-.3, .425, .4) func _init(_id: int, name_: String, pos: Vector2, character_style_: Dictionary, player_class_: String, game_: Game): + id = _id character_style = character_style_ player_class = player_class_ game = game_ |