fix(client): address PR #36 re-review — 7 items from Hoshe + Tyre
Warnings: facing indicator tests use Godot-normalized rotation range (-PI, PI] instead of raw addition (SW/W/NW in test_rendering, West in test_client_p3). Suggestions: cache font in world_radial _draw(), fix docstring on deactivate_insert() trigger, document tile-coordinate system on _eval_player_near (D-066), add public reset_facing_state() to InputMapper (D-030 testability). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -120,6 +120,13 @@ func flush_queue() -> Array[Dictionary]:
|
||||
return queue
|
||||
|
||||
|
||||
## Reset facing state to default (North). Use in tests per D-030 testability.
|
||||
func reset_facing_state() -> void:
|
||||
facing_angle = -PI / 2.0
|
||||
facing_octant = "North"
|
||||
_last_sent_octant = "North"
|
||||
|
||||
|
||||
# D-054: Compute facing angle from mouse position relative to player screen position.
|
||||
# Uses viewport canvas transform to convert world coords to screen coords.
|
||||
# Intentional coupling: reads GameState.player_position directly — InputMapper is an
|
||||
|
||||
@@ -160,6 +160,9 @@ func _evaluate_condition(cond: Dictionary) -> bool:
|
||||
return false
|
||||
|
||||
|
||||
## x/y and radius are in tile coordinates (matching GameState.player_position),
|
||||
## not pixels. D-066 dual-scale: YAML authors write tile coords, pixel conversion
|
||||
## happens only at render time.
|
||||
func _eval_player_near(cond: Dictionary) -> bool:
|
||||
var tx: float = float(cond.get("x", 0))
|
||||
var ty: float = float(cond.get("y", 0))
|
||||
|
||||
@@ -267,7 +267,7 @@ func test_facing_indicator_rotation_matches_input_mapper_angle() -> void:
|
||||
-PI / 2.0: 0.0, # North
|
||||
0.0: PI / 2.0, # East
|
||||
PI / 2.0: PI, # South
|
||||
PI: 3.0 * PI / 2.0, # West
|
||||
PI: -PI / 2.0, # West (3PI/2 normalized to -PI/2 by Godot)
|
||||
}
|
||||
for angle in angles:
|
||||
InputMapper.facing_angle = angle
|
||||
|
||||
@@ -116,7 +116,4 @@ func test_wasd_strafe_right_facing_west() -> void:
|
||||
|
||||
|
||||
func after_test() -> void:
|
||||
# Reset facing to default
|
||||
InputMapper.facing_angle = -PI / 2.0
|
||||
InputMapper.facing_octant = "North"
|
||||
InputMapper._last_sent_octant = "North"
|
||||
InputMapper.reset_facing_state()
|
||||
|
||||
@@ -310,9 +310,9 @@ func test_entity_renderer_facing_indicator_rotation_accuracy() -> void:
|
||||
0.0: PI / 2.0, # East
|
||||
PI / 4.0: 3.0 * PI / 4.0, # Southeast
|
||||
PI / 2.0: PI, # South
|
||||
3.0 * PI / 4.0: 5.0 * PI / 4.0, # Southwest
|
||||
PI: 3.0 * PI / 2.0, # West
|
||||
-3.0 * PI / 4.0: 7.0 * PI / 4.0, # Northwest (note: -PI/2 wraps)
|
||||
3.0 * PI / 4.0: -3.0 * PI / 4.0, # Southwest (Godot normalizes to (-PI, PI])
|
||||
PI: -PI / 2.0, # West (3PI/2 normalized to -PI/2)
|
||||
-3.0 * PI / 4.0: -PI / 4.0, # Northwest (-3PI/4 + PI/2 = -PI/4)
|
||||
}
|
||||
renderer.update_entities(_test_entities_v2)
|
||||
var player_node = renderer.entity_nodes[1]
|
||||
|
||||
@@ -5,8 +5,8 @@ extends Control
|
||||
## Renders on InsertOverlay (CanvasLayer 10).
|
||||
## Drag-release for power users, click-click for newcomers.
|
||||
## Insert spoke sends PauseSimulation on activate (#518/D-058).
|
||||
## Selecting any other spoke (or re-opening the radial) calls deactivate_insert()
|
||||
## which sends ResumeSimulation. Pause/resume are idempotent.
|
||||
## Selecting any non-Insert spoke, cancelling, or pressing Escape calls
|
||||
## deactivate_insert() which sends ResumeSimulation. Pause/resume are idempotent.
|
||||
|
||||
signal spoke_selected(spoke_name: String)
|
||||
|
||||
@@ -37,6 +37,7 @@ var _origin: Vector2 = Vector2.ZERO
|
||||
var _hovered_spoke: int = Spoke.NONE
|
||||
var _drag_mode: bool = false
|
||||
var _insert_active: bool = false
|
||||
var _cached_font: Font = null
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -45,6 +46,7 @@ func _ready() -> void:
|
||||
size = custom_minimum_size
|
||||
visible = false
|
||||
mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
_cached_font = get_theme_default_font()
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
@@ -192,10 +194,9 @@ func _draw() -> void:
|
||||
|
||||
# Label
|
||||
var label: String = SPOKE_NAMES.get(spoke, "")
|
||||
var font := get_theme_default_font()
|
||||
var text_size := font.get_string_size(label, HORIZONTAL_ALIGNMENT_CENTER, -1, 11)
|
||||
var text_size := _cached_font.get_string_size(label, HORIZONTAL_ALIGNMENT_CENTER, -1, 11)
|
||||
var label_pos := icon_center + Vector2(-text_size.x / 2.0, ICON_SIZE + 14.0)
|
||||
draw_string(font, label_pos, label, HORIZONTAL_ALIGNMENT_LEFT, -1, 11, color)
|
||||
draw_string(_cached_font, label_pos, label, HORIZONTAL_ALIGNMENT_LEFT, -1, 11, color)
|
||||
|
||||
|
||||
func _draw_spoke_icon(spoke: int, center: Vector2, color: Color) -> void:
|
||||
|
||||
Reference in New Issue
Block a user