gmp(M02): add 3.3.5 input profile

Work-Package: M02-GMP-INPUT-PROFILE-335-001
Agent: sindo-main-codex
Tests: player input/movement/capability/terrain/camera/presentation, coordinate/streaming, docs/coordination and renderer dry-run passed
Fidelity: build-12340 binding hashes and selected defaults pinned; TrinityCore turn rate and WoWee mouse routing are compatibility references with explicit limits
This commit is contained in:
2026-07-15 00:17:34 +04:00
parent c3094c9413
commit 8776a6b362
14 changed files with 468 additions and 59 deletions
+10 -2
View File
@@ -2,13 +2,17 @@ class_name PlayerInputActions
extends RefCounted
## Stable Input Map action names consumed by the runtime player input adapter.
## Defaults preserve the current render-sandbox controls; users may remap every
## action through Godot's Input Map without changing gameplay code.
## Separate translation actions preserve the renderer sandbox while allowing
## Blizzlike335 defaults to match build-12340 movement bindings.
const MOVE_FORWARD := &"openwc_player_move_forward"
const MOVE_BACKWARD := &"openwc_player_move_backward"
const STRAFE_LEFT := &"openwc_player_strafe_left"
const STRAFE_RIGHT := &"openwc_player_strafe_right"
const BLIZZLIKE_STRAFE_LEFT := &"openwc_player_blizzlike_strafe_left"
const BLIZZLIKE_STRAFE_RIGHT := &"openwc_player_blizzlike_strafe_right"
const TURN_LEFT := &"openwc_player_turn_left"
const TURN_RIGHT := &"openwc_player_turn_right"
const DEBUG_FLY_UP := &"openwc_player_debug_fly_up"
const DEBUG_FLY_DOWN := &"openwc_player_debug_fly_down"
const DEBUG_SPRINT := &"openwc_player_debug_sprint"
@@ -23,6 +27,10 @@ const REQUIRED_ACTIONS: Array[StringName] = [
MOVE_BACKWARD,
STRAFE_LEFT,
STRAFE_RIGHT,
BLIZZLIKE_STRAFE_LEFT,
BLIZZLIKE_STRAFE_RIGHT,
TURN_LEFT,
TURN_RIGHT,
DEBUG_FLY_UP,
DEBUG_FLY_DOWN,
DEBUG_SPRINT,
+76 -11
View File
@@ -5,21 +5,86 @@ extends RefCounted
## This adapter owns no movement state and may be replaced independently of the
## local movement controller.
const RENDER_SANDBOX_PROFILE_ID := &"RenderSandbox"
const BLIZZLIKE_335_PROFILE_ID := &"Blizzlike335"
## Samples the current Input singleton state for one physics tick.
func sample_move_intent() -> MoveIntent:
return compose_move_intent(
Input.get_action_strength(PlayerInputActions.MOVE_FORWARD),
Input.get_action_strength(PlayerInputActions.MOVE_BACKWARD),
Input.get_action_strength(PlayerInputActions.STRAFE_LEFT),
Input.get_action_strength(PlayerInputActions.STRAFE_RIGHT),
Input.get_action_strength(PlayerInputActions.DEBUG_FLY_UP),
Input.get_action_strength(PlayerInputActions.DEBUG_FLY_DOWN),
Input.is_action_pressed(PlayerInputActions.DEBUG_SPRINT)
var input_profile_id: StringName:
get:
return _input_profile_id
var _input_profile_id: StringName
## Selects one supported action layout. Unknown profiles fail closed to Blizzlike335.
func _init(requested_profile_id: StringName = BLIZZLIKE_335_PROFILE_ID) -> void:
_input_profile_id = (
RENDER_SANDBOX_PROFILE_ID
if requested_profile_id == RENDER_SANDBOX_PROFILE_ID
else BLIZZLIKE_335_PROFILE_ID
)
## Builds a normalized intent from action strengths for deterministic tests and
## Samples the current Input singleton state for one physics tick.
func sample_move_intent() -> MoveIntent:
if _input_profile_id == RENDER_SANDBOX_PROFILE_ID:
return compose_move_intent(
Input.get_action_strength(PlayerInputActions.MOVE_FORWARD),
Input.get_action_strength(PlayerInputActions.MOVE_BACKWARD),
Input.get_action_strength(PlayerInputActions.STRAFE_LEFT),
Input.get_action_strength(PlayerInputActions.STRAFE_RIGHT),
Input.get_action_strength(PlayerInputActions.DEBUG_FLY_UP),
Input.get_action_strength(PlayerInputActions.DEBUG_FLY_DOWN),
Input.is_action_pressed(PlayerInputActions.DEBUG_SPRINT)
)
return compose_blizzlike_335_move_intent(
Input.get_action_strength(PlayerInputActions.MOVE_FORWARD),
Input.get_action_strength(PlayerInputActions.MOVE_BACKWARD),
Input.get_action_strength(PlayerInputActions.BLIZZLIKE_STRAFE_LEFT),
Input.get_action_strength(PlayerInputActions.BLIZZLIKE_STRAFE_RIGHT),
Input.get_action_strength(PlayerInputActions.TURN_LEFT),
Input.get_action_strength(PlayerInputActions.TURN_RIGHT),
Input.is_action_pressed(PlayerInputActions.CAMERA_ROTATE)
)
## Builds the compatibility layout: Q/E always strafe; A/D turn unless
## right-mouse camera rotation is active, when A/D also strafe. Default bindings
## come from build 12340; conditional routing is reference-implementation evidence.
static func compose_blizzlike_335_move_intent(
forward_strength: float,
backward_strength: float,
strafe_left_strength: float,
strafe_right_strength: float,
turn_left_strength: float,
turn_right_strength: float,
camera_rotate_active: bool
) -> MoveIntent:
var effective_strafe_left := strafe_left_strength
var effective_strafe_right := strafe_right_strength
var turn_axis := clampf(turn_right_strength, 0.0, 1.0) - clampf(turn_left_strength, 0.0, 1.0)
if camera_rotate_active:
effective_strafe_left += turn_left_strength
effective_strafe_right += turn_right_strength
turn_axis = 0.0
var move_intent := compose_move_intent(
forward_strength,
backward_strength,
effective_strafe_left,
effective_strafe_right,
0.0,
0.0,
false
)
return MoveIntent.new(
move_intent.forward_axis,
move_intent.strafe_axis,
0.0,
false,
turn_axis
)
## Builds a normalized sandbox intent from action strengths for deterministic tests and
## alternative input adapters. Strengths outside `[0, 1]` are clamped.
static func compose_move_intent(
forward_strength: float,
@@ -23,6 +23,7 @@ var _strafe_speed_units_per_second: float
var _flight_vertical_speed_units_per_second: float
var _acceleration_units_per_second_squared: float
var _sandbox_sprint_multiplier: float
var _keyboard_turn_speed_radians_per_second: float
var _movement_capabilities: PlayerMovementCapabilities
var _godot_world_velocity_units_per_second := Vector3.ZERO
var _is_flight_enabled := false
@@ -38,7 +39,8 @@ func _init(
flight_vertical_speed_units_per_second: float,
acceleration_units_per_second_squared: float,
sandbox_sprint_multiplier: float,
movement_capabilities: PlayerMovementCapabilities = null
movement_capabilities: PlayerMovementCapabilities = null,
keyboard_turn_speed_radians_per_second: float = PI
) -> void:
_run_speed_units_per_second = run_speed_units_per_second
_backward_speed_units_per_second = backward_speed_units_per_second
@@ -46,6 +48,10 @@ func _init(
_flight_vertical_speed_units_per_second = flight_vertical_speed_units_per_second
_acceleration_units_per_second_squared = acceleration_units_per_second_squared
_sandbox_sprint_multiplier = sandbox_sprint_multiplier
_keyboard_turn_speed_radians_per_second = maxf(
keyboard_turn_speed_radians_per_second,
0.0
)
_movement_capabilities = (
movement_capabilities
if movement_capabilities != null
@@ -53,6 +59,16 @@ func _init(
)
## Returns the Godot yaw delta for one signed keyboard-turn request.
## Positive intent turns right, which is negative rotation around Godot +Y.
func calculate_yaw_delta_radians(move_intent: MoveIntent, delta_seconds: float) -> float:
return (
-move_intent.turn_axis
* _keyboard_turn_speed_radians_per_second
* maxf(delta_seconds, 0.0)
)
## Toggles sandbox free flight and clears velocity when the profile permits it.
## Returns the resulting state; rejected compatibility-profile requests return false.
func toggle_sandbox_flight() -> bool: