- 桥梁与静态物体高度采样修复: - 严格对齐 40250 CMapOutdoor::GetHeight 与 CAttributeInstance::GetHeight - 解析 .mdatr 中的 AttributeHeight 网格,使用 is_in_triangle_2d 准确计算桥面多边形平面方程 - sample_height 查询邻近区块并返回 fMAX(fObjectHeight, fTerrainHeight),彻底解决走上桥面穿透掉入水底/河床的问题 - 新增 test_bridge_height_parity.gd 自动化对拍测试 - 40250 怪物击杀经验动效: - 1:1 实现 FLY_EXP(0) / FLY_HP / FLY_SP 粒子轨迹与爆炸吸附 - 40250 客户端全系统功能对齐(Batches 1-31): - 包含公会、交易、骑乘、变身、钓鱼、采矿、商城、信件、结婚、地牢等 134 套对拍系统与自动化回归测试 - 文档沉淀: - 新增 docs/CLIENT-PARITY-AUDIT-AND-FIX-GUIDE.md 客户端对拍缺陷发现与修复工程指南
170 lines
5.6 KiB
GDScript
170 lines
5.6 KiB
GDScript
# messenger_system.gd —— 40250 官方好友与行会联络人面板系统 1:1
|
|
# 严格对照:
|
|
# ClientVS22/source/UserInterface/PythonMessenger.h, PythonMessenger.cpp
|
|
# Client/Eternexus/root/uimessenger.py
|
|
extends RefCounted
|
|
|
|
const GROUP_FRIEND := 0 # 好友分组 (MESSENGER_GRUOP_INDEX_FRIEND)
|
|
const GROUP_GUILD := 1 # 行会分组 (MESSENGER_GRUOP_INDEX_GUILD)
|
|
const GROUP_FAMILY := 2 # 家族/伴侣分组 (MessengerFamilyGroup)
|
|
|
|
const STATE_OFFLINE := 0 # 离线
|
|
const STATE_ONLINE := 1 # 在线
|
|
const STATE_MOBILE := 2 # 移动短信/挂机状态
|
|
|
|
# 联络人数据结构
|
|
class MessengerContact:
|
|
var name: String
|
|
var group: int
|
|
var state: int
|
|
var love_point: int = -1 # 伴侣爱心值 (0~100)
|
|
var rank: String = "" # 行会职位
|
|
var last_seen: int = 0
|
|
|
|
func _init(p_name: String, p_group: int, p_state: int = STATE_OFFLINE) -> void:
|
|
name = p_name
|
|
group = p_group
|
|
state = p_state
|
|
love_point = -1
|
|
rank = ""
|
|
last_seen = 0
|
|
|
|
# 分组存储
|
|
var friends: Dictionary = {} # name -> MessengerContact
|
|
var guild_members: Dictionary = {} # name -> MessengerContact
|
|
var family_partner: MessengerContact = null
|
|
|
|
# 事件日志回调缓冲(模拟 PythonMessenger 向上层回调)
|
|
var event_logs: Array = []
|
|
|
|
var main_player_name: String = "Player"
|
|
|
|
func _init(player_name: String = "Player") -> void:
|
|
main_player_name = player_name
|
|
friends.clear()
|
|
guild_members.clear()
|
|
family_partner = null
|
|
event_logs.clear()
|
|
|
|
# 1. 好友添加 (PythonMessenger::AppendFriend)
|
|
func add_friend(friend_name: String, initial_state: int = STATE_ONLINE) -> Dictionary:
|
|
var res := { "success": false, "error_code": "OK", "message": "" }
|
|
|
|
if friend_name.is_empty():
|
|
res["error_code"] = "EMPTY_NAME"
|
|
res["message"] = "好友名称不能为空。"
|
|
return res
|
|
|
|
if friend_name == main_player_name:
|
|
res["error_code"] = "CANNOT_ADD_SELF"
|
|
res["message"] = "无法将自己添加为好友。"
|
|
return res
|
|
|
|
if friends.has(friend_name):
|
|
res["error_code"] = "ALREADY_FRIEND"
|
|
res["message"] = "该玩家已在您的好友列表中。"
|
|
return res
|
|
|
|
var contact = MessengerContact.new(friend_name, GROUP_FRIEND, initial_state)
|
|
friends[friend_name] = contact
|
|
|
|
event_logs.append({ "type": "ADD_FRIEND", "name": friend_name, "state": initial_state })
|
|
res["success"] = true
|
|
res["message"] = "成功添加 %s 为好友。" % friend_name
|
|
return res
|
|
|
|
# 2. 好友移除 (PythonMessenger::RemoveFriend)
|
|
func remove_friend(friend_name: String) -> bool:
|
|
if not friends.has(friend_name):
|
|
return false
|
|
friends.erase(friend_name)
|
|
event_logs.append({ "type": "REMOVE_FRIEND", "name": friend_name })
|
|
return true
|
|
|
|
# 3. 登录/登出/移动短信状态同步 (OnFriendLogin / OnFriendLogout / SetMobile)
|
|
func set_friend_state(friend_name: String, new_state: int) -> bool:
|
|
if not friends.has(friend_name):
|
|
return false
|
|
|
|
var c: MessengerContact = friends[friend_name]
|
|
var old_state: int = c.state
|
|
c.state = new_state
|
|
|
|
if new_state == STATE_ONLINE and old_state != STATE_ONLINE:
|
|
event_logs.append({ "type": "FRIEND_LOGIN", "name": friend_name })
|
|
elif new_state == STATE_OFFLINE and old_state != STATE_OFFLINE:
|
|
event_logs.append({ "type": "FRIEND_LOGOUT", "name": friend_name })
|
|
elif new_state == STATE_MOBILE:
|
|
event_logs.append({ "type": "FRIEND_MOBILE", "name": friend_name })
|
|
|
|
return true
|
|
|
|
# 4. 行会成员同步 (AppendGuildMember / RemoveGuildMember / RemoveAllGuildMember)
|
|
func append_guild_member(member_name: String, member_rank: String = "Member", state: int = STATE_ONLINE) -> void:
|
|
if guild_members.has(member_name):
|
|
var existing: MessengerContact = guild_members[member_name]
|
|
existing.state = state
|
|
existing.rank = member_rank
|
|
return
|
|
|
|
var contact = MessengerContact.new(member_name, GROUP_GUILD, state)
|
|
contact.rank = member_rank
|
|
guild_members[member_name] = contact
|
|
event_logs.append({ "type": "GUILD_MEMBER_ADD", "name": member_name, "rank": member_rank })
|
|
|
|
func remove_guild_member(member_name: String) -> bool:
|
|
if not guild_members.has(member_name):
|
|
return false
|
|
guild_members.erase(member_name)
|
|
event_logs.append({ "type": "GUILD_MEMBER_REMOVE", "name": member_name })
|
|
return true
|
|
|
|
func clear_all_guild_members() -> void:
|
|
guild_members.clear()
|
|
event_logs.append({ "type": "GUILD_MEMBER_CLEAR_ALL" })
|
|
|
|
# 5. 家族/配偶联系人绑定 (MessengerFamilyGroup)
|
|
func set_family_partner(partner_name: String, love_points: int = 100, state: int = STATE_ONLINE) -> void:
|
|
family_partner = MessengerContact.new(partner_name, GROUP_FAMILY, state)
|
|
family_partner.love_point = clamp(love_points, 0, 100)
|
|
event_logs.append({ "type": "FAMILY_PARTNER_SET", "name": partner_name, "love": family_partner.love_point })
|
|
|
|
func update_partner_love_points(points: int) -> void:
|
|
if family_partner != null:
|
|
family_partner.love_point = clamp(points, 0, 100)
|
|
|
|
func remove_family_partner() -> void:
|
|
family_partner = null
|
|
event_logs.append({ "type": "FAMILY_PARTNER_REMOVE" })
|
|
|
|
# 6. 查询与过滤工具方法
|
|
func is_friend(name: String) -> bool:
|
|
return friends.has(name)
|
|
|
|
func get_friend_state(name: String) -> int:
|
|
if friends.has(name):
|
|
return friends[name].state
|
|
return STATE_OFFLINE
|
|
|
|
func get_group_members(group_index: int) -> Array:
|
|
var list: Array = []
|
|
match group_index:
|
|
GROUP_FRIEND:
|
|
for k in friends:
|
|
list.append(friends[k])
|
|
GROUP_GUILD:
|
|
for k in guild_members:
|
|
list.append(guild_members[k])
|
|
GROUP_FAMILY:
|
|
if family_partner != null:
|
|
list.append(family_partner)
|
|
return list
|
|
|
|
func get_online_count(group_index: int) -> int:
|
|
var members := get_group_members(group_index)
|
|
var online := 0
|
|
for m in members:
|
|
if m.state == STATE_ONLINE or m.state == STATE_MOBILE:
|
|
online += 1
|
|
return online
|