M2.6: server rules (PvP, raiding, locks and friends, death penalty, difficulty, wolf grace), chat, admin commands, server console
This commit is contained in:
@@ -109,6 +109,7 @@ func bind(p: CharacterBody3D) -> void:
|
||||
root.move_child(_hurt, 0)
|
||||
player.survival.hurt.connect(_on_hurt)
|
||||
Actions.notify.connect(toast)
|
||||
_build_chat(root)
|
||||
ItemDB.icons_ready.connect(_refresh)
|
||||
_refresh()
|
||||
|
||||
@@ -175,6 +176,7 @@ func _build_stats(root: Control) -> void:
|
||||
root.add_child(_clock)
|
||||
|
||||
func _process(_d: float) -> void:
|
||||
_fade_chat()
|
||||
var s = player.survival
|
||||
for k in _bars:
|
||||
_bars[k].value = s.get(k)
|
||||
@@ -211,6 +213,70 @@ func fade(mid: Callable) -> void:
|
||||
|
||||
var _death: Control
|
||||
|
||||
# --- chat (online: T to talk) ----------------------------------------------------------
|
||||
|
||||
const CHAT_LINES := 8
|
||||
const CHAT_FADE := 14.0 ## seconds a line stays up (all show while typing)
|
||||
var _chat_log: VBoxContainer
|
||||
var _chat_input: LineEdit
|
||||
|
||||
func _build_chat(root: Control) -> void:
|
||||
_chat_log = VBoxContainer.new()
|
||||
_chat_log.position = Vector2(16, 64)
|
||||
_chat_log.custom_minimum_size = Vector2(520, 0)
|
||||
_chat_log.add_theme_constant_override("separation", 2)
|
||||
_chat_log.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
root.add_child(_chat_log)
|
||||
_chat_input = LineEdit.new()
|
||||
_chat_input.position = Vector2(16, 64 + CHAT_LINES * 24 + 6)
|
||||
_chat_input.custom_minimum_size = Vector2(520, 34)
|
||||
_chat_input.placeholder_text = "Say something (Enter), or /help for commands. Esc to cancel"
|
||||
_chat_input.max_length = 200
|
||||
_chat_input.visible = false
|
||||
_chat_input.text_submitted.connect(func(t):
|
||||
Chat.say(t)
|
||||
close_chat())
|
||||
root.add_child(_chat_input)
|
||||
Chat.message.connect(chat_line)
|
||||
|
||||
func chat_line(text: String, kind: String) -> void:
|
||||
var col := UITheme.TEXT
|
||||
if kind == "server":
|
||||
col = Color(0.95, 0.82, 0.45)
|
||||
elif kind == "reply":
|
||||
col = UITheme.TEXT_DIM
|
||||
var l := UITheme.label(text, 15, col)
|
||||
l.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
l.custom_minimum_size = Vector2(520, 0)
|
||||
l.set_meta("t", Time.get_ticks_msec())
|
||||
_chat_log.add_child(l)
|
||||
while _chat_log.get_child_count() > CHAT_LINES:
|
||||
var old := _chat_log.get_child(0)
|
||||
_chat_log.remove_child(old)
|
||||
old.queue_free()
|
||||
|
||||
func open_chat() -> void:
|
||||
_chat_input.text = ""
|
||||
_chat_input.visible = true
|
||||
player.ui_open = true
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
_chat_input.grab_focus()
|
||||
|
||||
func close_chat() -> void:
|
||||
_chat_input.visible = false
|
||||
_chat_input.release_focus()
|
||||
player.ui_open = false
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
|
||||
func _fade_chat() -> void:
|
||||
if _chat_log == null:
|
||||
return
|
||||
var typing := _chat_input.visible
|
||||
var now := Time.get_ticks_msec()
|
||||
for l in _chat_log.get_children():
|
||||
var age := (now - int(l.get_meta("t", now))) / 1000.0
|
||||
l.modulate.a = 1.0 if typing else clampf((CHAT_FADE - age) / 2.0, 0.0, 1.0)
|
||||
|
||||
## The death screen: the world fades to dark red, it says what killed you
|
||||
## and where your things are, and after `delay` seconds Respawn (or Enter)
|
||||
## calls `respawn`.
|
||||
@@ -286,6 +352,16 @@ func _on_inventory_requested(container: Node) -> void:
|
||||
|
||||
## ESC: close the inventory if it's open, otherwise toggle the pause menu.
|
||||
func _input(event: InputEvent) -> void:
|
||||
if _chat_input != null and _chat_input.visible:
|
||||
if event is InputEventKey and event.pressed and event.keycode == KEY_ESCAPE:
|
||||
close_chat()
|
||||
get_viewport().set_input_as_handled()
|
||||
return # (typing: keys go to the chat line)
|
||||
if event is InputEventKey and event.pressed and not event.echo and event.physical_keycode == KEY_T \
|
||||
and Net.state == "connected" and not player.ui_open and not is_dead_screen():
|
||||
open_chat()
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
if event is InputEventKey and event.pressed and not event.echo and event.keycode == KEY_ESCAPE:
|
||||
if is_dead_screen():
|
||||
return # (respawn first)
|
||||
|
||||
Reference in New Issue
Block a user