Unlock menu after failed join; remove contact damage; cover clean disconnects
ci / verify (push) Successful in 45s
ci / verify (push) Successful in 45s
A failed connection left the connect buttons disabled forever. _show_menu() returned early when a menu already existed, so the set_busy(false) that re-enables them never ran on the way back from _abort_connect -- the player was locked out of both joining and hosting with no way out but a restart. Also guards against a second attempt stacking on an in-flight one. Contact damage is gone as a concept: nothing in this game hurts you by touching it, because every threat should be a bullet you can see and dodge. The Stalker walked at you and dealt contact damage and nothing else, so it now carries a point-blank shotgun instead -- five pellets, 62 degrees, 18-tick lifetime for about 78px of reach, so it still has to close and leaves nothing lingering. tests/unit/test_content.gd asserts every hostile enemy has an emitter, so a new enemy cannot quietly reintroduce the mechanic. The menu's "Disconnect" DOES get the anti-cheese protection -- verified, not assumed. It calls Net.shutdown(), the socket closes, and the server takes the same linkdead path as a SIGKILL, because the channel is keyed on the socket closing rather than on how it closed. Made permanent: a --leave-after bot flag and two smoke assertions covering the polite exit alongside the hard kill, so a future "clean leave" message that skipped the channel would fail a test. The menu now says so out loud in a dungeon -- the mechanic only reads as fair if the cost is known before clicking. 103 tests, 12 smoke assertions; check.sh, test.sh and smoke.sh all pass.
This commit is contained in:
+25
-6
@@ -12,6 +12,9 @@ signal disconnect_requested
|
||||
|
||||
var _panel: VBoxContainer
|
||||
var _hub_button: Button
|
||||
var _disconnect_button: Button
|
||||
var _note: Label
|
||||
var _in_dungeon: bool = false
|
||||
var _open: bool = false
|
||||
|
||||
|
||||
@@ -42,17 +45,18 @@ func _ready() -> void:
|
||||
title.add_theme_font_size_override("font_size", 26)
|
||||
_panel.add_child(title)
|
||||
|
||||
var note := Label.new()
|
||||
note.text = "The world keeps running. You are not safe here."
|
||||
note.add_theme_font_size_override("font_size", 12)
|
||||
note.add_theme_color_override("font_color", Color(1.0, 0.7, 0.5))
|
||||
_panel.add_child(note)
|
||||
_note = Label.new()
|
||||
_note.add_theme_font_size_override("font_size", 12)
|
||||
_note.add_theme_color_override("font_color", Color(1.0, 0.7, 0.5))
|
||||
_note.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
_note.custom_minimum_size = Vector2(320.0, 0.0)
|
||||
_panel.add_child(_note)
|
||||
|
||||
_hub_button = _button("Return to hub", func() -> void:
|
||||
return_to_hub_requested.emit()
|
||||
close())
|
||||
_button("Resume", func() -> void: close())
|
||||
_button("Disconnect to menu", func() -> void:
|
||||
_disconnect_button = _button("Disconnect to menu", func() -> void:
|
||||
disconnect_requested.emit()
|
||||
close())
|
||||
_button("Quit game", func() -> void: get_tree().quit())
|
||||
@@ -100,4 +104,19 @@ func is_open() -> bool:
|
||||
|
||||
## The hub button is meaningless when you are already in the hub.
|
||||
func set_in_dungeon(in_dungeon: bool) -> void:
|
||||
if in_dungeon == _in_dungeon and not _note.text.is_empty():
|
||||
return
|
||||
_in_dungeon = in_dungeon
|
||||
_hub_button.disabled = not in_dungeon
|
||||
if in_dungeon:
|
||||
# Disconnecting is not an escape: the server keeps the body in the
|
||||
# world, channelling out, for the same second the escape button costs.
|
||||
# Saying so is the difference between a considered choice and a nasty
|
||||
# surprise -- the mechanic only reads as fair if players know about it.
|
||||
_note.text = "The world keeps running while this is open. " \
|
||||
+ "Disconnecting does not save you: your ship stays in the dungeon " \
|
||||
+ "for one second and can still be killed."
|
||||
_disconnect_button.text = "Disconnect to menu (ship stays 1s)"
|
||||
else:
|
||||
_note.text = "The world keeps running while this is open."
|
||||
_disconnect_button.text = "Disconnect to menu"
|
||||
|
||||
Reference in New Issue
Block a user