Files
mtgodot-poc/project/alignment_system.gd
T
shenandshen 66d217b313 feat(client): 完成40250客户端核心功能1:1对齐与桥梁高度采样修复
- 桥梁与静态物体高度采样修复:
  - 严格对齐 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 客户端对拍缺陷发现与修复工程指南
2026-09-19 08:51:25 -07:00

129 lines
4.4 KiB
GDScript

# alignment_system.gd —— 人物善恶道德与红名系统(40250 官方 1:1 对齐)
# 对齐源码:
# - 40250 server/game/src/char.cpp:1190-1205 (UpdateAlignment, 自然恢复公式)
# - 40250 server/game/src/char.cpp:3300 (UpdateAlignment)
# - 40250 ClientVS22/source/UserInterface/InstanceBaseEffect.cpp:609 (GetTitleColor)
# - 40250 ClientVS22/source/UserInterface/InstanceBase.h:262 (TITLE_NUM=9, TITLE_NONE=4)
# - 40250 text_tail.gd (title_color, title_name_key)
class_name AlignmentSystem
extends RefCounted
const MIN_ALIGNMENT := -20000
const MAX_ALIGNMENT := 20000
# 9 档善恶称号常量定义
const TITLE_HEROIC := 0 # 英雄 (Heroic, >= 12000)
const TITLE_NOBLE := 1 # 尊者 (Noble, 8000..11999)
const TITLE_GOOD := 2 # 善良 (Good, 4000..7999)
const TITLE_FRIENDLY := 3 # 友好 (Friendly, 1000..3999)
const TITLE_NEUTRAL := 4 # 普通 (Neutral, 0..999)
const TITLE_AGGRESSIVE := 5 # 无赖 (Aggressive, -1..-3999)
const TITLE_FRAUDULENT := 6 # 欺诈 (Fraudulent, -4000..-7999)
const TITLE_MALICIOUS := 7 # 邪恶 (Malicious, -8000..-11999)
const TITLE_CRUEL := 8 # 魔头 (Cruel, <= -12000)
const VNUM_ZEN_BEAN := 70102 # 禅定豆 / 清恶豆
const GRADE_NAMES := {
TITLE_HEROIC: "英雄",
TITLE_NOBLE: "尊者",
TITLE_GOOD: "善良",
TITLE_FRIENDLY: "友好",
TITLE_NEUTRAL: "普通",
TITLE_AGGRESSIVE: "无赖",
TITLE_FRAUDULENT: "欺诈",
TITLE_MALICIOUS: "邪恶",
TITLE_CRUEL: "魔头",
}
const GRADE_COLORS := {
TITLE_HEROIC: Color8(0, 204, 255),
TITLE_NOBLE: Color8(0, 144, 255),
TITLE_GOOD: Color8(92, 110, 255),
TITLE_FRIENDLY: Color8(155, 155, 255),
TITLE_NEUTRAL: Color8(255, 255, 255),
TITLE_AGGRESSIVE: Color8(207, 117, 0),
TITLE_FRAUDULENT: Color8(235, 83, 0),
TITLE_MALICIOUS: Color8(227, 0, 0),
TITLE_CRUEL: Color8(255, 0, 0),
}
## 获取善恶值对应的 40250 称号等级 (0..8)
static func get_alignment_grade(alignment: int) -> int:
if alignment >= 12000:
return TITLE_HEROIC
elif alignment >= 8000:
return TITLE_NOBLE
elif alignment >= 4000:
return TITLE_GOOD
elif alignment >= 1000:
return TITLE_FRIENDLY
elif alignment >= 0:
return TITLE_NEUTRAL
elif alignment > -4000:
return TITLE_AGGRESSIVE
elif alignment > -8000:
return TITLE_FRAUDULENT
elif alignment > -12000:
return TITLE_MALICIOUS
else:
return TITLE_CRUEL
## 获取善恶称号中文名
static func get_title_name(grade: int) -> String:
return GRADE_NAMES.get(grade, "普通")
## 获取善恶称号颜色
static func get_title_color(grade: int) -> Color:
return GRADE_COLORS.get(grade, Color.WHITE)
## 检查是否为红名(罪恶状态)
static func is_red_name(alignment: int) -> bool:
return alignment < 0
## 检查是否为蓝名(正义状态)
static func is_blue_name(alignment: int) -> bool:
return alignment >= 1000
## 40250 char.cpp:1197 在线自然恢复善恶计算
## minutes: 在线分钟数;has_fast_item: 是否佩戴禅定香囊等加速道具
static func calculate_time_recovery(cur_alignment: int, minutes: int, has_fast_item := false) -> int:
if minutes <= 0:
return cur_alignment
var updated := cur_alignment
if cur_alignment < 0:
# 恶名状态:基础每分钟 +60 点,带香囊每分钟 +120 点
var rate: int = 120 if has_fast_item else 60
updated = mini(0, cur_alignment + rate * minutes)
else:
# 善良状态:每分钟 +5 点
updated = mini(MAX_ALIGNMENT, cur_alignment + 5 * minutes)
return updated
## 击杀怪物增加善恶值 (40250 char_battle.cpp: UpdateAlignment)
## 击杀野外怪物根据怪物等级恢复善恶(红名时恢复极快)
static func on_kill_monster(cur_alignment: int, mob_level: int, player_level: int) -> int:
var delta := maxi(1, mob_level - player_level / 2)
if cur_alignment < 0:
delta *= 2 # 红名击杀怪物恢复加倍
return mini(MAX_ALIGNMENT, cur_alignment + delta)
## 使用禅定豆 (Zen Bean 70102)
## 40250 原生逻辑:仅在红名 (alignment < 0) 时可使用,一次清除 500 点罪恶
static func use_zen_bean(cur_alignment: int) -> Dictionary:
if cur_alignment >= 0:
return {
"ok": false,
"code": "CANNOT_USE_NOT_EVIL",
"msg": "你未处于恶名状态,无需使用禅定豆。"
}
var new_align: int = mini(0, cur_alignment + 500)
return {
"ok": true,
"code": "SUCCESS",
"old_alignment": cur_alignment,
"new_alignment": new_align,
"consumed": true,
"msg": "使用了禅定豆,洗清了 500 点罪恶值!(当前善恶: %d)" % new_align
}