- 桥梁与静态物体高度采样修复: - 严格对齐 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 客户端对拍缺陷发现与修复工程指南
100 lines
4.1 KiB
GDScript
100 lines
4.1 KiB
GDScript
# emotion_action_system.gd —— 角色情绪动作与表情快捷键(40250 官方 1:1 对齐)
|
|
# 对齐源码:
|
|
# - 40250 root/emotion.py (EMOTION_DICT, EMOTION_CLAP..DANCE_6)
|
|
# - 40250 server/game/src/cmd_emotion.cpp
|
|
# - 40250 root/game.py: __PressNumKey (Ctrl + 1..9)
|
|
class_name EmotionActionSystem
|
|
extends RefCounted
|
|
|
|
# 40250 官方情绪动作常量
|
|
const EMOTION_CLAP := 1
|
|
const EMOTION_CONGRATULATION := 2
|
|
const EMOTION_FORGIVE := 3
|
|
const EMOTION_ANGRY := 4
|
|
const EMOTION_ATTRACTIVE := 5
|
|
const EMOTION_SAD := 6
|
|
const EMOTION_SHY := 7
|
|
const EMOTION_CHEERUP := 8
|
|
const EMOTION_BANTER := 9
|
|
const EMOTION_JOY := 10
|
|
const EMOTION_CHEERS_1 := 11
|
|
const EMOTION_CHEERS_2 := 12
|
|
const EMOTION_DANCE_1 := 13
|
|
const EMOTION_DANCE_2 := 14
|
|
const EMOTION_DANCE_3 := 15
|
|
const EMOTION_DANCE_4 := 16
|
|
const EMOTION_DANCE_5 := 17
|
|
const EMOTION_DANCE_6 := 18
|
|
|
|
# 情绪字典表 (对齐 emotion.py)
|
|
const EMOTION_TABLE := {
|
|
EMOTION_CLAP: {"name": "鼓掌", "command": "/clap", "motion": "clap"},
|
|
EMOTION_CONGRATULATION: {"name": "祝贺", "command": "/congratulation", "motion": "congratulation"},
|
|
EMOTION_FORGIVE: {"name": "原谅", "command": "/forgive", "motion": "forgive"},
|
|
EMOTION_ANGRY: {"name": "愤怒", "command": "/angry", "motion": "angry"},
|
|
EMOTION_ATTRACTIVE: {"name": "飞吻", "command": "/attractive", "motion": "attractive"},
|
|
EMOTION_SAD: {"name": "悲伤", "command": "/sad", "motion": "sad"},
|
|
EMOTION_SHY: {"name": "害羞", "command": "/shy", "motion": "shy"},
|
|
EMOTION_CHEERUP: {"name": "加油", "command": "/cheerup", "motion": "cheerup"},
|
|
EMOTION_BANTER: {"name": "嘲讽", "command": "/banter", "motion": "banter"},
|
|
EMOTION_JOY: {"name": "喜悦", "command": "/joy", "motion": "joy"},
|
|
EMOTION_CHEERS_1: {"name": "欢呼1", "command": "/cheer1", "motion": "cheers_1"},
|
|
EMOTION_CHEERS_2: {"name": "欢呼2", "command": "/cheer2", "motion": "cheers_2"},
|
|
EMOTION_DANCE_1: {"name": "跳舞1", "command": "/dance1", "motion": "dance_1"},
|
|
EMOTION_DANCE_2: {"name": "跳舞2", "command": "/dance2", "motion": "dance_2"},
|
|
EMOTION_DANCE_3: {"name": "跳舞3", "command": "/dance3", "motion": "dance_3"},
|
|
EMOTION_DANCE_4: {"name": "跳舞4", "command": "/dance4", "motion": "dance_4"},
|
|
EMOTION_DANCE_5: {"name": "跳舞5", "command": "/dance5", "motion": "dance_5"},
|
|
EMOTION_DANCE_6: {"name": "跳舞6", "command": "/dance6", "motion": "dance_6"},
|
|
}
|
|
|
|
## 检查是否为有效的情绪动作 ID
|
|
static func is_valid_emotion(emotion_id: int) -> bool:
|
|
return EMOTION_TABLE.has(emotion_id)
|
|
|
|
## 通过聊天命令解析情绪 (例如 "/clap" -> 1)
|
|
static func get_emotion_from_command(cmd_text: String) -> int:
|
|
var clean := cmd_text.strip_edges().to_lower()
|
|
for id in EMOTION_TABLE.keys():
|
|
if EMOTION_TABLE[id]["command"] == clean:
|
|
return id
|
|
return 0
|
|
|
|
## 通过快捷键序号获取情绪 (0..8 对应 Ctrl + 1..9)
|
|
static func get_hotkey_emotion(hotkey_idx: int) -> int:
|
|
# 40250 官方快捷栏默认前 9 个动作
|
|
var list := [
|
|
EMOTION_CLAP,
|
|
EMOTION_CONGRATULATION,
|
|
EMOTION_FORGIVE,
|
|
EMOTION_ANGRY,
|
|
EMOTION_ATTRACTIVE,
|
|
EMOTION_SAD,
|
|
EMOTION_SHY,
|
|
EMOTION_CHEERUP,
|
|
EMOTION_BANTER,
|
|
]
|
|
if hotkey_idx >= 0 and hotkey_idx < list.size():
|
|
return list[hotkey_idx]
|
|
return 0
|
|
|
|
## 执行情绪动作
|
|
static func perform_emotion(emotion_id: int, is_fighting := false, is_mounted := false) -> Dictionary:
|
|
if not is_valid_emotion(emotion_id):
|
|
return {"ok": false, "code": "INVALID_EMOTION", "msg": "未知的动作!"}
|
|
if is_fighting:
|
|
return {"ok": false, "code": "CANNOT_IN_BATTLE", "msg": "战斗中无法做出情绪动作!"}
|
|
if is_mounted:
|
|
return {"ok": false, "code": "CANNOT_ON_MOUNT", "msg": "骑乘状态下无法做出该动作!"}
|
|
|
|
var em: Dictionary = EMOTION_TABLE[emotion_id]
|
|
return {
|
|
"ok": true,
|
|
"code": "SUCCESS",
|
|
"emotion_id": emotion_id,
|
|
"name": em["name"],
|
|
"motion": em["motion"],
|
|
"command": em["command"],
|
|
"msg": "执行了【%s】动作。" % em["name"]
|
|
}
|