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>
150 lines
4.5 KiB
GDScript
150 lines
4.5 KiB
GDScript
class_name VestResult
|
|
|
|
## Grouping class for test result primitives.
|
|
##
|
|
## See [VestResult.Suite][br]
|
|
## See [VestResult.Case][br]
|
|
|
|
enum { ## Result status enum
|
|
TEST_VOID, ## Test ran no assertions
|
|
TEST_TODO, ## Test is not implemented yet
|
|
TEST_FAIL, ## Test has failed
|
|
TEST_SKIP, ## Test was skipped
|
|
TEST_PASS, ## Test passed
|
|
TEST_MAX ## Represents the size of the result status enum
|
|
}
|
|
|
|
## Test suite results.
|
|
class Suite:
|
|
## The test suite this result describes
|
|
var suite: VestDefs.Suite
|
|
|
|
## The results of the test cases belonging to the suite
|
|
var cases: Array[Case] = []
|
|
|
|
## The results of the suite's nested suites
|
|
var subsuites: Array[Suite] = []
|
|
|
|
## Get the number of test cases in the suite.[br]
|
|
## Includes the number of test cases in the suite, and recursively sums up
|
|
## the test cases in any of the nested suites.[br]
|
|
## To count only the direct descendants, see [method plan_size].
|
|
func size() -> int:
|
|
return cases.size() + subsuites.reduce(func(acc, it): return acc + it.size(), 0)
|
|
|
|
## Return the number of items in the test plan.[br]
|
|
## Includes the number of test cases and subsuites in the suite. As opposed
|
|
## to [method size], this method doesn't include the test cases of the
|
|
## subsuites.
|
|
func plan_size() -> int:
|
|
return cases.size() + subsuites.size()
|
|
|
|
## Get the aggregate result of the test cases and suites contained in the
|
|
## suite.
|
|
func get_aggregate_status() -> int:
|
|
var result: int = TEST_PASS
|
|
if not cases.is_empty():
|
|
result = mini(result, cases.map(func(it): return it.status).min())
|
|
if not subsuites.is_empty():
|
|
result = mini(result, subsuites.map(func(it): return it.get_aggregate_status()).min())
|
|
return result
|
|
|
|
## Get the aggregate result of the test suite, as a string.
|
|
func get_aggregate_status_string() -> String:
|
|
return VestResult.get_status_string(get_aggregate_status())
|
|
|
|
## Get an array of result statuses contained in the suite.
|
|
func get_unique_statuses() -> Array[int]:
|
|
var result := [] as Array[int]
|
|
for kase in cases:
|
|
if not result.has(kase.status):
|
|
result.push_back(kase.status)
|
|
for subsuite in subsuites:
|
|
for status in subsuite.get_unique_statuses():
|
|
if not result.has(status):
|
|
result.push_back(status)
|
|
return result
|
|
|
|
## Get the count of test cases and nested suites with the given result
|
|
## status.
|
|
## [br][br]
|
|
## [b]Note:[/b] This method doesn't do recursive summation.
|
|
func get_count_by_status(p_status: int) -> int:
|
|
return (
|
|
cases.filter(func(it): return it.status == p_status).size() +
|
|
subsuites.filter(func(it): return it.get_aggregate_status() == p_status).size()
|
|
)
|
|
|
|
func _to_wire() -> Dictionary:
|
|
return {
|
|
"suite": suite._to_wire(),
|
|
"cases": cases.map(func(it): return it._to_wire()),
|
|
"subsuites": subsuites.map(func(it): return it._to_wire())
|
|
}
|
|
|
|
static func _from_wire(data: Dictionary) -> Suite:
|
|
var result := Suite.new()
|
|
|
|
result.suite = VestDefs.Suite._from_wire(data["suite"])
|
|
result.cases.assign(data["cases"].map(func(it): return Case._from_wire(it)))
|
|
result.subsuites.assign(data["subsuites"].map(func(it): return Suite._from_wire(it)))
|
|
|
|
return result
|
|
|
|
## Test case result.
|
|
class Case:
|
|
## The test case this result describes.
|
|
var case: VestDefs.Case
|
|
|
|
## The resulting status of the test run.
|
|
var status: int = TEST_VOID
|
|
|
|
# The messages attached to this result
|
|
var messages: Array[String] = []
|
|
|
|
## Custom data attached to this result.
|
|
var data: Dictionary = {}
|
|
|
|
## The resource path where the last assertion ran.
|
|
var assert_file: String = ""
|
|
|
|
## The line index where the last assertion ran.[br]
|
|
## Set to -1 for undetermined.
|
|
var assert_line: int = -1
|
|
|
|
## Get the test result status as a string.
|
|
func get_status_string() -> String:
|
|
return VestResult.get_status_string(status)
|
|
|
|
func _to_wire() -> Dictionary:
|
|
return {
|
|
"case": case._to_wire(),
|
|
"status": status,
|
|
"messages": messages.duplicate(),
|
|
"data": Vest.__.Serializer.serialize(data),
|
|
"assert_file": assert_file,
|
|
"assert_line": assert_line
|
|
}
|
|
|
|
static func _from_wire(p_data: Dictionary) -> Case:
|
|
var result := Case.new()
|
|
|
|
result.case = VestDefs.Case._from_wire(p_data["case"])
|
|
result.status = p_data["status"]
|
|
result.messages.assign(p_data["messages"])
|
|
result.data = p_data["data"]
|
|
result.assert_file = p_data["assert_file"]
|
|
result.assert_line = p_data["assert_line"]
|
|
|
|
return result
|
|
|
|
## Convert a test result status into string.
|
|
static func get_status_string(p_status: int) -> String:
|
|
match p_status:
|
|
TEST_VOID: return "VOID"
|
|
TEST_TODO: return "TODO"
|
|
TEST_FAIL: return "FAIL"
|
|
TEST_SKIP: return "SKIP"
|
|
TEST_PASS: return "PASS"
|
|
_: return "?"
|