b0c83af092
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>
101 lines
3.2 KiB
GDScript
101 lines
3.2 KiB
GDScript
# This file is generated by Vest!
|
|
# Do not modify!
|
|
# source: res://addons/vest/test/mixins/gather-suite-mixin.gd
|
|
extends "res://addons/vest/test/vest-test-base.gd"
|
|
|
|
|
|
|
|
# Automatically gathers tests defined in the test class
|
|
|
|
func _get_ignored_methods() -> Array[String]:
|
|
return [
|
|
"get_suite_name",
|
|
"before_suite", "before_case", "before_benchmark", "before_each",
|
|
"after_suite", "after_case", "after_benchmark", "after_each"
|
|
]
|
|
|
|
func _get_suite_name() -> String:
|
|
# Check if callback is implemented
|
|
if has_method("get_suite_name"):
|
|
return call("get_suite_name")
|
|
|
|
# Check if class_name is set
|
|
var script := get_script() as Script
|
|
var pattern := RegEx.create_from_string("class_name\\s+([^\n\\s]+)")
|
|
var hit := pattern.search(script.source_code)
|
|
|
|
if hit:
|
|
return hit.get_string(1)
|
|
|
|
# Fall back to script path
|
|
return script.resource_path
|
|
|
|
func _get_suite() -> VestDefs.Suite:
|
|
var script := get_script() as Script
|
|
var ignored_methods := _get_ignored_methods()
|
|
var inherited_methods := (script.get_base_script()
|
|
.get_script_method_list()
|
|
.map(func(it): return it["name"])
|
|
)
|
|
|
|
var methods := (script.get_script_method_list()
|
|
.filter(func(it): return not it["name"].begins_with("_"))
|
|
.filter(func(it): return not inherited_methods.has(it["name"]))
|
|
.filter(func(it): return not ignored_methods.has(it["name"]))
|
|
)
|
|
|
|
var define_methods: Array[Dictionary] = []
|
|
var case_methods: Array[Dictionary] = []
|
|
var parametric_methods: Array[Dictionary] = []
|
|
|
|
for method in methods:
|
|
if method["name"].begins_with("suite"):
|
|
define_methods.append(method)
|
|
elif method["name"].begins_with("test") and not method["default_args"].is_empty() and method["default_args"][0] is String:
|
|
parametric_methods.append(method)
|
|
elif method["name"].begins_with("test"):
|
|
case_methods.append(method)
|
|
|
|
return await define(_get_suite_name(), func():
|
|
for method in define_methods:
|
|
await call(method["name"])
|
|
|
|
for method in case_methods:
|
|
var method_name := method["name"] as String
|
|
var test_name := method_name.trim_prefix("test").trim_suffix("__only").capitalize()
|
|
var callback := func(): await call(method["name"])
|
|
var is_only := _is_only(method_name)
|
|
|
|
test(test_name, callback, is_only, method_name)
|
|
|
|
for method in parametric_methods:
|
|
var method_name := method["name"] as String
|
|
var test_name := method_name.trim_prefix("test").trim_suffix("__only").capitalize()
|
|
var is_only := _is_only(method_name)
|
|
|
|
var param_provider_name := method["default_args"][0] as String
|
|
if not has_method(param_provider_name):
|
|
push_warning(
|
|
"Can't run parametrized test \"%s\", provider method \"%s\" is missing!" % \
|
|
[method["name"], param_provider_name]
|
|
)
|
|
|
|
var params = await call(param_provider_name)
|
|
if not params is Array or not params.all(func(it): return it is Array):
|
|
push_warning(
|
|
"Can't run parametrized test \"%s\", provider \"%s\" didn't return array or arrays: %s" % \
|
|
[method["name"], param_provider_name, params]
|
|
)
|
|
|
|
for i in range(params.size()):
|
|
test(
|
|
"%s#%d %s" % [test_name, i+1, params[i]],
|
|
func(): await callv(method["name"], params[i]),
|
|
is_only,
|
|
method_name
|
|
)
|
|
)
|
|
|
|
func _is_only(name: String) -> bool:
|
|
return name.ends_with("__only")
|