完善客户端功能并同步差距文档

This commit is contained in:
shenlei
2026-09-03 18:40:01 +09:00
parent f93a172296
commit 13ccb8d02d
135 changed files with 21881 additions and 1259 deletions
+175
View File
@@ -0,0 +1,175 @@
# name_color.gd —— CInstanceBase::GetNameColorIndex / GetNameColor 的 1:1 迁移(§8.8)
#
# 参考(REF/ = /Users/shenlei/Work/mt/40250/ClientVS22/source/):
# UserInterface/InstanceBaseEffect.cpp:525 GetNameColorIndex —— 逐行照抄
# UserInterface/InstanceBaseEffect.cpp:520 GetNameColor
# UserInterface/InstanceBaseEffect.cpp:52 SetEmpireNameMode
# UserInterface/InstanceBaseEffect.cpp:75 GetIndexedNameColor
# UserInterface/InstanceBase.h:216 NAMECOLOR_* 枚举(EMPIRE_NUM = 4)
# UserInterface/PythonCharacterManagerModule.cpp:767 chrmgr.NAMECOLOR_* -> C++ 枚举重映射
# assets/root/introloading.py:264 IntroLoading.__RegisterColor(RGB 注册)
# assets/root/colorInfo.py:11 CHR_NAME_RGB_*
# assets/root/constinfo.py:126 SET_DEFAULT_CHRNAME_COLOR(默认 CHRNAME_COLOR_INDEX = 0 → 帝国名色关)
#
# 纯静态。调用方把网络快照拼成 self_e(目标实例)/ main_e(主角,空 = 无主角实例)/
# ctx,语义与 entity_rules.gd 完全一致(net_play._attack_ctx / net_world._name_color_ctx
# 同款 ctx:main_vid / duel_mode / duel_opponents / pvp_pairs / gvg_pairs / party_vids)。
extends RefCounted
const EntityRules = preload("res://entity_rules.gd")
# InstanceBase.h 的匿名枚举,EMPIRE_NUM = 4(EMPIRE_NONE/A/B/C)。
const EMPIRE_NUM := 4
# NAMECOLOR_*(EMPIRE_NUM 展开后的实际序号)
const NAMECOLOR_MOB := 0
const NAMECOLOR_NPC := 1
const NAMECOLOR_PC := 2 # + GetEmpireID()(0..3)→ 2..5
const NAMECOLOR_PC_END := 6
const NAMECOLOR_NORMAL_MOB := 7
const NAMECOLOR_NORMAL_NPC := 8
const NAMECOLOR_NORMAL_PC := 9
const NAMECOLOR_NORMAL_PC_END := 13
const NAMECOLOR_EMPIRE_MOB := 14
const NAMECOLOR_EMPIRE_NPC := 15
const NAMECOLOR_EMPIRE_PC := 16 # + uEmpire → 16..20
const NAMECOLOR_EMPIRE_PC_END := 20
const NAMECOLOR_FUNC := 21
const NAMECOLOR_PK := 22
const NAMECOLOR_PVP := 23
const NAMECOLOR_PARTY := 24
const NAMECOLOR_WARP := 25
const NAMECOLOR_WAYPOINT := 26
const NAMECOLOR_NUM := 41
const _WHITE := Color(1, 1, 1)
# IntroLoading.__RegisterColor 通过 chrmgr.RegisterNameColor 写进 g_akD3DXClrName 的槽。
# chrmgr.NAMECOLOR_PC/NPC/MOB 三个常量经 PythonCharacterManagerModule.cpp:767 重映射
# 到 NORMAL_PC/NORMAL_NPC/NORMAL_MOB,其余(PK/PVP/PARTY/WARP/WAYPOINT/EMPIRE_*)直通。
# 未在此表里的索引 = D3DXCOLOR() 默认(透明黑),但 GetNameColorIndex 不会命中它们。
static func _registered_slots() -> Dictionary:
return {
NAMECOLOR_NORMAL_MOB: Color8(235, 22, 9),
NAMECOLOR_NORMAL_NPC: Color8(122, 231, 93),
NAMECOLOR_NORMAL_PC: Color8(255, 215, 76),
NAMECOLOR_PK: Color8(180, 100, 0),
NAMECOLOR_PVP: Color8(238, 54, 223),
NAMECOLOR_PARTY: Color8(128, 192, 255),
NAMECOLOR_WARP: Color8(136, 218, 241),
NAMECOLOR_WAYPOINT: Color8(255, 255, 255),
NAMECOLOR_EMPIRE_MOB: Color8(235, 22, 9),
NAMECOLOR_EMPIRE_NPC: Color8(122, 231, 93),
NAMECOLOR_EMPIRE_PC + 1: Color8(157, 0, 0),
NAMECOLOR_EMPIRE_PC + 2: Color8(222, 160, 47),
NAMECOLOR_EMPIRE_PC + 3: Color8(23, 30, 138),
}
# g_akD3DXClrName 的当前解析态(SetEmpireNameMode 重写 MOB/NPC + PC..PC+3 槽)。
static var _palette := {}
static var _empire_name_mode := false
static func _ensure_palette() -> void:
if _palette.is_empty():
set_empire_name_mode(false)
static func is_empire_name_mode() -> bool:
_ensure_palette()
return _empire_name_mode
# CInstanceBase::SetEmpireNameMode(InstanceBaseEffect.cpp:52)。默认关(constinfo
# .CHRNAME_COLOR_INDEX == 0 → SET_DEFAULT_CHRNAME_COLOR → SetEmpireNameMode(0))。
static func set_empire_name_mode(enabled: bool) -> void:
_empire_name_mode = enabled
var p := _registered_slots()
if enabled:
p[NAMECOLOR_MOB] = p[NAMECOLOR_EMPIRE_MOB]
p[NAMECOLOR_NPC] = p[NAMECOLOR_EMPIRE_NPC]
p[NAMECOLOR_PC] = p[NAMECOLOR_NORMAL_PC]
for u in range(1, EMPIRE_NUM):
p[NAMECOLOR_PC + u] = p.get(NAMECOLOR_EMPIRE_PC + u, _WHITE)
else:
p[NAMECOLOR_MOB] = p[NAMECOLOR_NORMAL_MOB]
p[NAMECOLOR_NPC] = p[NAMECOLOR_NORMAL_NPC]
for u in range(0, EMPIRE_NUM):
p[NAMECOLOR_PC + u] = p[NAMECOLOR_NORMAL_PC]
_palette = p
# CInstanceBase::GetIndexedNameColor(InstanceBaseEffect.cpp:75)
static func indexed_name_color(index: int) -> Color:
_ensure_palette()
if index < 0 or index >= NAMECOLOR_NUM:
return _WHITE
return _palette.get(index, _WHITE)
# --- 类别谓词(entity_rules 已有 _is_pc/_is_enemy/_is_poly;NPC 这里补) ---------
static func _is_npc(e: Dictionary) -> bool:
return EntityRules._kind(e) == EntityRules.KIND_NPC
static func _empire_id(e: Dictionary) -> int:
# GetEmpireID() → m_dwEmpireID(0 = 无,1..3)。防御性 clamp 到合法槽。
return clampi(int(e.get("empire", 0)), 0, EMPIRE_NUM - 1)
# --- CInstanceBase::GetNameColorIndex(InstanceBaseEffect.cpp:525)—— 逐行 --------
static func name_color_index(self_e: Dictionary, main_e: Dictionary, ctx: Dictionary) -> int:
if EntityRules._is_pc(self_e):
# if (m_isKiller) return NAMECOLOR_PK;
if EntityRules._is_killer(self_e):
return NAMECOLOR_PK
var self_vid := int(self_e.get("vid", 0))
var main_vid := int(ctx.get("main_vid", int(main_e.get("vid", 0))))
var is_main := self_vid != 0 and self_vid == main_vid
# if (__IsExistMainInstance() && !__IsMainInstance())
if not main_e.is_empty() and not is_main:
var vid_main := int(main_e.get("vid", main_vid))
# if (pkInstMain->GetDuelMode()) switch(...)
var duel := int(ctx.get("duel_mode", 0))
if duel != 0:
match duel:
EntityRules.DUEL_CANNOTATTACK:
return NAMECOLOR_PC + _empire_id(self_e)
EntityRules.DUEL_START:
if EntityRules._find_duel_key(vid_main, self_vid, ctx):
return NAMECOLOR_PVP
return NAMECOLOR_PC + _empire_id(self_e)
# if (pkInstMain->IsSameEmpire(*this))
if EntityRules._is_same_empire(main_e, self_e):
if EntityRules._pair_in(ctx.get("pvp_pairs", []), vid_main, self_vid):
return NAMECOLOR_PVP
var guild_main := int(main_e.get("guild", 0))
var guild_self := int(self_e.get("guild", 0))
# __FindGVGKey:guild 0 的 PVPKEY 恒为 0,参考端集合里不会有 →
# 这里与 entity_rules._is_pvp_instance 一样加 !=0 防御。
if guild_main != 0 and guild_self != 0 \
and EntityRules._pair_in(ctx.get("gvg_pairs", []), guild_main, guild_self):
return NAMECOLOR_PVP
# __FindDUELKey 分支在参考端此处被 /* */ 注释掉,故不实现。
else:
return NAMECOLOR_PVP
# IAbstractPlayer::IsPartyMemberByVID(GetVirtualID())
if self_vid in ctx.get("party_vids", []):
return NAMECOLOR_PARTY
return NAMECOLOR_PC + _empire_id(self_e)
elif _is_npc(self_e):
return NAMECOLOR_NPC
elif EntityRules._is_enemy(self_e):
return NAMECOLOR_MOB
elif EntityRules._is_poly(self_e):
return NAMECOLOR_MOB
# 参考端 fallthrough:`return D3DXCOLOR(0xffffffff);` 被当成 UINT 传给
# GetIndexedNameColor → 越界 → 白。这里用 -1 表达同一含义。
return -1
# CInstanceBase::GetNameColor(InstanceBaseEffect.cpp:520)
static func name_color(self_e: Dictionary, main_e: Dictionary, ctx: Dictionary) -> Color:
return indexed_name_color(name_color_index(self_e, main_e, ctx))