aboutsummaryrefslogtreecommitdiff
path: root/client/player
diff options
context:
space:
mode:
authortpart <tpart120@proton.me>2025-06-18 22:29:59 +0200
committertpart <tpart120@proton.me>2025-06-18 22:30:03 +0200
commit05fe59c831a5f1b7f0666d617f275a86a6ce4d35 (patch)
tree9f0e0c16e390486611dbbbe3b7ac2748339d011c /client/player
parentdc86da97ca960ce2ecebb3fde3c4122a56529bb8 (diff)
downloadhurrycurry-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.gd82
-rw-r--r--client/player/player.gd3
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_