Files

110 lines
5.3 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# chat_tail —— §8.8 头顶「聊天 / 信息」尾标 1:1CPythonTextTail::RegisterChatTail /
# RegisterInfoTail 的纯静态镜像(与 name_color.gd / text_tail.gd 同套路)。
#
# REF 40250/ClientVS22/source/UserInterface/PythonTextTail.cpp
# :16 c_TextTail_Chat_Color = D3DXCOLOR(1,1,1,1) —— 普通聊天气泡=白
# :17 c_TextTail_Info_Color = D3DXCOLOR(1, 0.785f, 0.785f, 1) —— 信息气泡=淡红
# :26 gs_TextTail_LivingTime = 5000 —— TEXTTAIL_LIVINGTIME_CONTROL
# :28 TextTail_GetLivingTime() assert(gs_TextTail_LivingTime > 1000)
# :34 TextTail_SetLivingTime(livingTime)
# :581 RegisterChatTail(vid, szChat)m_ChatTailMap 已有该 vid → 改文本 + Color=Chat +
# LivingTime = now + GetLivingTime() + bNameFlag=TRUE,直接 return
# 否则新建(高度 = 角色高 + 10),LivingTime = now + GetLivingTime()bNameFlag=TRUE
# SetOutline(true)VERTICAL_ALIGN_BOTTOM,插入 m_ChatTailMap
# :624 RegisterInfoTail(vid, szChat):同上,但 Color=Info、bNameFlag=FALSE
# :328 UpdateAllTextTail:遍历 m_ChatTailMapLivingTime < now 即 DeleteTextTail + erase
# (每 vid 只有一条 chat/info 尾标,chat 与 info 共用同一张 m_ChatTailMap
# :74 UpdateAllTextTailchat 尾标若 bNameFlag → ShowCharacterTextTail(vid)(名字也一起顶出来)
# :105 UpdateShowingTextTailchat 尾标若 bNameFlag → 名字尾标 y = chatTail.y - 17(名字挪到气泡下方)
# :684 IsChatTextTail(vid)m_ChatTailMap.find(vid) != end
#
# REF 40250/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp
# :1301 CHAT_TYPE_COMMAND → ServerCommand,提前 return(不进尾标)
# :1321 TALKING/PARTY/GUILD/SHOUT/WHISPERline = strchr(buf,':') ? p + 2 : buf(去掉 "名字: " 前缀)
# :1363 INFO/NOTICE/BIG_NOTICE/defaultline = buf(原样)
# :1372 if (CHAT_TYPE_SHOUT != kChat.type) RegisterChatTail(kChat.dwVID, line);
# → 带 VID 的聊天里,除 SHOUT / COMMAND 外都进「聊天尾标」;RegisterInfoTail 仅
# game.py:930 / :936 技能 / 射击错误尾标显式调。
#
# seam ⑨:参考端聊天尾标由 Render() 与名字尾标同屏排布(气泡在上、名字下移 17px,bNameFlag 决定
# 名字是否强制显示);本移植是 net_world 里名字 Label3D 与 "bubble" Label3D 各自 billboard 并存,
# 名字不强制顶出、不随气泡下移——差异记入 §8.8。
extends RefCounted
const CHAT_COLOR := Color(1.0, 1.0, 1.0)
const INFO_COLOR := Color(1.0, 0.785, 0.785)
const LIVING_TIME_DEFAULT := 5000 # msgs_TextTail_LivingTime
const LIVING_TIME_MIN := 1000 # assert 下界(TextTail_GetLivingTime
const HEIGHT_ADD := 10.0 # 角色高 + 10RegisterChatTail 新建分支)
# CHAT_TYPE_*Packet.h:1410 enum EChatType
const CT_TALKING := 0
const CT_INFO := 1
const CT_NOTICE := 2
const CT_PARTY := 3
const CT_GUILD := 4
const CT_COMMAND := 5
const CT_SHOUT := 6
const CT_WHISPER := 7
const CT_BIG_NOTICE := 8
static var _living_time := LIVING_TIME_DEFAULT
static func set_living_time(ms: int) -> void:
# TextTail_SetLivingTime —— 参考端不在此断言(断言在 GetLivingTime
_living_time = ms
static func living_time() -> int:
# TextTail_GetLivingTimeassert(gs_TextTail_LivingTime > 1000)
assert(_living_time > LIVING_TIME_MIN)
return _living_time
static func strip_name_prefix(raw: String) -> String:
# strchr(buf, ':') ? p + 2 : buf —— 有冒号则取 ": " 之后正文,否则整串原样
var i := raw.find(":")
return raw.substr(i + 2) if i != -1 else raw
static func line_for_tail(chat_type: int, raw: String) -> String:
# RecvChatPacket 的 switchTALKING/PARTY/GUILD/SHOUT/WHISPER 去前缀;其余原样
match chat_type:
CT_TALKING, CT_PARTY, CT_GUILD, CT_SHOUT, CT_WHISPER:
return strip_name_prefix(raw)
_:
return raw
static func wants_chat_tail(chat_type: int) -> bool:
# RecvChatPacketCOMMAND 提前 returnSHOUT 显式排除;其余带 VID 聊天都进尾标
return chat_type != CT_SHOUT and chat_type != CT_COMMAND
static func _register(tails: Dictionary, vid: int, text: String, now_ms: int, col: Color, name_flag: bool) -> Dictionary:
var e := {
"text": text,
"color": col,
"name_flag": name_flag,
"living_time": now_ms + living_time(),
}
tails[vid] = e
return e
static func register_chat(tails: Dictionary, vid: int, text: String, now_ms: int) -> Dictionary:
# CPythonTextTail::RegisterChatTail —— 白 + bNameFlag TRUE,已存在则原地替换
return _register(tails, vid, text, now_ms, CHAT_COLOR, true)
static func register_info(tails: Dictionary, vid: int, text: String, now_ms: int) -> Dictionary:
# CPythonTextTail::RegisterInfoTail —— 淡红 + bNameFlag FALSE,与 chat 共用同一张表
return _register(tails, vid, text, now_ms, INFO_COLOR, false)
static func is_chat_text_tail(tails: Dictionary, vid: int) -> bool:
# CPythonTextTail::IsChatTextTail
return tails.has(vid)
static func expire(tails: Dictionary, now_ms: int) -> Array:
# UpdateAllTextTailLivingTime < now 即删除;返回被清掉的 vid 列表
var dead: Array = []
for vid in tails.keys():
if int(tails[vid].get("living_time", 0)) < now_ms:
dead.append(vid)
for vid in dead:
tails.erase(vid)
return dead