Files
tactical-shooter/examples/forest-brawl/scripts/brawler-input.gd
T
shawn b0c83af092 Fresh start: replace with naxIO/netfox-cs-sample foundation
Complete replacement of the tactical-shooter project with the
netfox-cs-sample (MIT) — a CS 1.6 inspired multiplayer FPS built
with Godot 4 and netfox.

## What's new
- Full CS-style gameplay: teams (T/CT), rounds, economy, buy menu
- 6 weapons: Knife, Glock, USP, AK-47, M4A1, AWP
- Bomb plant/defuse with 2 bombsites
- Flashbang & smoke grenades
- Proper netfox rollback netcode at 64 tick
- Network popup UI for host/join
- HUD, crosshair, round timer, scoreboard
- All netfox singletons registered as autoloads (works in exported builds)

## Architecture
- Listen-server (host from client, no dedicated server binary)
- Multiplayer-fps game lives at examples/multiplayer-fps/
- Netfox addons registered as autoloads for exported build compat
- Godot 4.7 with Forward+ renderer

## Removed
- Old headless-server architecture (client_main, server_main, player.gd, etc.)
- Custom netfox bootstrap with ENet fallback
- Old ChaffGames FPS template (2,420 lines, 844 KB)
- SimulationServer GDExtension stub
- Godot-jolt physics (netfox sample uses default Godot physics)
- Duplicate weapon_data.gd, anti_cheat.gd, round_manager.gd, etc.
- Server browser API Python venv (87 MB)
- test_range map and modular assets

## Preserved
- Git history
- Server config at config/default_server_config.cfg
- Windows export preset
- Build directory (gitignored)

Co-authored-by: naxIO <naxIO@users.noreply.github.com>
2026-07-02 20:55:20 -04:00

92 lines
2.5 KiB
GDScript

extends BaseNetInput
class_name BrawlerInput
@export var switch_time: float = 1.0
var camera: Camera3D
@onready var _player: Node3D = get_parent()
@onready var _confine_mouse: bool = DisplayServer.mouse_get_mode() == DisplayServer.MOUSE_MODE_CONFINED
var movement: Vector3 = Vector3.ZERO
var aim: Vector3 = Vector3.ZERO
var is_firing: bool = false
var _last_mouse_input: float = 0.0
var _aim_target: Vector3
var _projected_target: Vector3
var _has_aim: bool = false
func _input(event):
if event is InputEventMouse:
_last_mouse_input = NetworkTime.local_time
func _gather():
# Movement
movement = Vector3(
Input.get_axis("move_west", "move_east"),
Input.get_action_strength("move_jump"),
Input.get_axis("move_north", "move_south")
)
# Aim
aim = Vector3(
Input.get_axis("aim_west", "aim_east"),
0.0,
Input.get_axis("aim_north", "aim_south")
)
if aim.length():
# Prefer gamepad
# Reset timeout for mouse motion
_last_mouse_input = NetworkTime.local_time - switch_time
elif NetworkTime.local_time - _last_mouse_input > switch_time:
# Use movement if no mouse motion recently
aim = movement
elif _has_aim:
# Use mouse raycast
aim = (_aim_target - _player.global_position).normalized()
else:
# Fall back to mouse projected to player height
aim = (_projected_target - _player.global_position).normalized()
# Always aim horizontally, never up or down
aim.y = 0
aim = aim.normalized()
# Hide mouse if inactive
if NetworkTime.local_time - _last_mouse_input >= switch_time:
DisplayServer.mouse_set_mode(
DisplayServer.MOUSE_MODE_CONFINED_HIDDEN if _confine_mouse else DisplayServer.MOUSE_MODE_HIDDEN
)
else:
DisplayServer.mouse_set_mode(
DisplayServer.MOUSE_MODE_CONFINED if _confine_mouse else DisplayServer.MOUSE_MODE_VISIBLE
)
is_firing = Input.is_action_pressed("weapon_fire")
func _physics_process(_delta):
if not camera:
camera = get_viewport().get_camera_3d()
# Aim
var mouse_pos = get_viewport().get_mouse_position()
var ray_origin = camera.project_ray_origin(mouse_pos)
var ray_normal = camera.project_ray_normal(mouse_pos)
var ray_length = 128
var space = camera.get_world_3d().direct_space_state
var hit = space.intersect_ray(PhysicsRayQueryParameters3D.create(
ray_origin, ray_origin + ray_normal * ray_length
))
if not hit.is_empty():
# Aim at raycast hit
_aim_target = hit.position
_has_aim = true
else:
# Project to player's height
var height_diff = _player.global_position.y - ray_origin.y
_projected_target = ray_origin + ray_normal * (height_diff / ray_normal.y)
_has_aim = false