Implement 40250 classic client port
This commit is contained in:
+51
-4
@@ -18,14 +18,14 @@ const ROLE_ATTACKER := 2
|
||||
const ROLE_TANKER := 3
|
||||
const ROLE_BUFFER := 4
|
||||
const ROLE_SKILL_MASTER := 5
|
||||
const ROLE_BERSERKER := 6
|
||||
const ROLE_HASTE := 6
|
||||
const ROLE_DEFENDER := 7
|
||||
const ROLE_LABEL := {
|
||||
0: "普", 1: "队", 2: "攻", 3: "坦", 4: "辅", 5: "宗", 6: "狂", 7: "防",
|
||||
0: "普", 1: "队", 2: "攻", 3: "坦", 4: "辅", 5: "宗", 6: "速", 7: "防",
|
||||
}
|
||||
const ROLE_MENU := [
|
||||
[ROLE_NORMAL, "普通"], [ROLE_ATTACKER, "攻击"], [ROLE_TANKER, "坦克"],
|
||||
[ROLE_BERSERKER, "狂战"], [ROLE_BUFFER, "辅助"], [ROLE_SKILL_MASTER, "宗师"],
|
||||
[ROLE_HASTE, "迅捷"], [ROLE_BUFFER, "辅助"], [ROLE_SKILL_MASTER, "宗师"],
|
||||
[ROLE_DEFENDER, "防御"],
|
||||
]
|
||||
# Packet.h EPartyExpDistributionType
|
||||
@@ -34,13 +34,15 @@ const EXP_PARITY := 1 # 均分
|
||||
# uiparty.PartyMemberInfoBoard.PARTY_SKILL_*
|
||||
const PARTY_SKILL_HEAL := 1
|
||||
# affects[7] 槽位含义(暂定,按 partymemberinfoboard.py 图标顺序)
|
||||
const AFFECT_LABEL := ["经验", "攻击", "防御", "辅助", "宗师", "时间", "回复"]
|
||||
const AFFECT_LABEL := ["经验", "攻击", "坦克", "辅助", "宗师", "迅捷", "防御"]
|
||||
|
||||
var client: Node
|
||||
var dialogs: Node
|
||||
var _root: Control
|
||||
var _list: VBoxContainer
|
||||
var _dist_btn: Button
|
||||
var _heal_btn: Button
|
||||
var _notice: Label
|
||||
var _role_popup: Control = null
|
||||
|
||||
func setup(m2client: Node, parent: Node, dlg: Node = null) -> void:
|
||||
@@ -51,6 +53,8 @@ func setup(m2client: Node, parent: Node, dlg: Node = null) -> void:
|
||||
client.party_changed.connect(refresh)
|
||||
if client.has_signal("party_invite_ask"):
|
||||
client.party_invite_ask.connect(_on_invite)
|
||||
if client.has_signal("party_request_denied"):
|
||||
client.party_request_denied.connect(_on_request_denied)
|
||||
if client.has_signal("vitals_changed"):
|
||||
client.vitals_changed.connect(func(_v): if is_open(): refresh())
|
||||
refresh()
|
||||
@@ -91,6 +95,37 @@ func _refresh_dist_btn() -> void:
|
||||
var mode := int(client.get_party_distribute_mode()) if client.has_method("get_party_distribute_mode") else 0
|
||||
_dist_btn.text = "EXP:均分" if mode == EXP_PARITY else "EXP:不均分"
|
||||
_dist_btn.disabled = not _local_is_leader()
|
||||
if is_instance_valid(_heal_btn):
|
||||
var leadership := _leadership_level()
|
||||
_heal_btn.disabled = not _local_is_leader() or (leadership >= 0 and leadership < 18)
|
||||
_heal_btn.tooltip_text = "队长 Leadership 达到 18 级后可用" if _heal_btn.disabled and leadership >= 0 and leadership < 18 else "组队治疗"
|
||||
|
||||
func _leadership_level() -> int:
|
||||
# The server's CParty::Update gates party roles/heal using the leader's
|
||||
# Leadership skill. -1 means that the snapshot has not arrived yet; in
|
||||
# that case the server remains authoritative and the controls stay usable.
|
||||
if client == null or not client.has_method("get_skills"):
|
||||
return -1
|
||||
var skills: Array = client.get_skills()
|
||||
for skill in skills:
|
||||
if int(skill.get("id", -1)) == 121: # SKILL_LEADERSHIP in 40250
|
||||
return int(skill.get("level", 0))
|
||||
return -1
|
||||
|
||||
func _role_unlock_level(role: int) -> int:
|
||||
match role:
|
||||
ROLE_ATTACKER: return 10
|
||||
ROLE_TANKER, ROLE_HASTE: return 20
|
||||
ROLE_BUFFER: return 25
|
||||
ROLE_SKILL_MASTER: return 35
|
||||
ROLE_DEFENDER: return 40
|
||||
_: return 0
|
||||
|
||||
func _role_allowed(role: int, current_role: int = -1) -> bool:
|
||||
if role == ROLE_NORMAL or role == current_role:
|
||||
return true
|
||||
var leadership := _leadership_level()
|
||||
return leadership < 0 or leadership >= _role_unlock_level(role)
|
||||
|
||||
# --- 한 명 strip ------------------------------------------------------
|
||||
|
||||
@@ -178,6 +213,9 @@ func _open_role_popup(anchor: Control, pid: int, cur_role: int) -> void:
|
||||
var b := Button.new()
|
||||
b.text = entry[1] + (" ✓" if r == cur_role else "")
|
||||
b.custom_minimum_size = Vector2(84, 22)
|
||||
b.disabled = not _role_allowed(r, cur_role)
|
||||
if b.disabled:
|
||||
b.tooltip_text = "Leadership %d 级解锁" % _role_unlock_level(r)
|
||||
b.pressed.connect(func() -> void:
|
||||
if r == ROLE_NORMAL:
|
||||
# OnSelectState(-1): 清掉当前角色
|
||||
@@ -213,6 +251,10 @@ func _on_invite(leader_pid: int) -> void:
|
||||
else:
|
||||
accept.call()
|
||||
|
||||
func _on_request_denied() -> void:
|
||||
if is_instance_valid(_notice):
|
||||
_notice.text = "组队请求被拒绝"
|
||||
|
||||
# --- EXP 분배 / 组队治疗 --------------------------------------------
|
||||
|
||||
func _toggle_distribute() -> void:
|
||||
@@ -255,7 +297,12 @@ func _build(parent: Node) -> void:
|
||||
heal.text = "组队治疗"
|
||||
heal.add_theme_font_size_override("font_size", 11)
|
||||
heal.pressed.connect(_party_heal)
|
||||
_heal_btn = heal
|
||||
header.add_child(heal)
|
||||
_notice = Label.new()
|
||||
_notice.add_theme_font_size_override("font_size", 10)
|
||||
_notice.add_theme_color_override("font_color", Color(1, 0.65, 0.55))
|
||||
header.add_child(_notice)
|
||||
|
||||
_list = VBoxContainer.new()
|
||||
_list.position = Vector2(8, 32)
|
||||
|
||||
Reference in New Issue
Block a user