fix: 装备属性面板避让逻辑 + 多项功能更新
- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
This commit is contained in:
@@ -22,6 +22,12 @@ extends RefCounted
|
||||
var _by_id := {}
|
||||
var count := 0
|
||||
|
||||
# PythonSkill.h: SKILL_EFFECT_COUNT / SKILL_GRADEGAP;当前 assets/root/constinfo.py
|
||||
# 的 USE_SKILL_EFFECT_UPGRADE_ENABLE=1,故本地与远端动作都必须保留等级偏移。
|
||||
const SKILL_EFFECT_COUNT := 4
|
||||
const SKILL_GRADEGAP := 25
|
||||
var skill_effect_upgrade_enabled := true
|
||||
|
||||
const JOB_DIR := {
|
||||
"WARRIOR": "warrior",
|
||||
"ASSASSIN": "assassin",
|
||||
@@ -228,15 +234,46 @@ func name_of(id: int) -> String:
|
||||
func motion_idx_of(id: int) -> int:
|
||||
return int(_by_id.get(id, {}).get("motion_idx", 0))
|
||||
|
||||
func set_skill_effect_upgrade_enabled(enabled: bool) -> void:
|
||||
skill_effect_upgrade_enabled = enabled
|
||||
|
||||
# CPythonSkill::SSkillData::GetSkillMotionIndex(iGrade)。grade 超出该技能实际
|
||||
# 注册的 grade 数量时回退基础 motion index,和 RegisterSkillDesc 的空槽填 base 一致。
|
||||
func motion_idx_for_grade(id: int, grade: int = -1) -> int:
|
||||
var base := motion_idx_of(id)
|
||||
if not skill_effect_upgrade_enabled or grade < 0 or grade >= SKILL_EFFECT_COUNT:
|
||||
return base
|
||||
var grade_count := clampi(int(_by_id.get(id, {}).get("grades", 1)), 1, SKILL_EFFECT_COUNT)
|
||||
return base + grade * SKILL_GRADEGAP if grade < grade_count else base
|
||||
|
||||
func motion_name_of(id: int) -> String:
|
||||
return String(_by_id.get(id, {}).get("motion", ""))
|
||||
|
||||
func motion_name_by_idx(motion_idx: int) -> String:
|
||||
# 先保留基础索引的精确匹配;没有基础项时,再解析等级偏移索引。
|
||||
for id in _by_id:
|
||||
if int(_by_id[id].get("motion_idx", 0)) == motion_idx:
|
||||
return String(_by_id[id].get("motion", ""))
|
||||
for id in _by_id:
|
||||
var base := int(_by_id[id].get("motion_idx", 0))
|
||||
var grade_count := clampi(int(_by_id[id].get("grades", 1)), 1, SKILL_EFFECT_COUNT)
|
||||
for grade in range(1, grade_count):
|
||||
if skill_effect_upgrade_enabled and base + grade * SKILL_GRADEGAP == motion_idx:
|
||||
return String(_by_id[id].get("motion", ""))
|
||||
return ""
|
||||
|
||||
func motion_grade_by_idx(motion_idx: int) -> int:
|
||||
for id in _by_id:
|
||||
if int(_by_id[id].get("motion_idx", 0)) == motion_idx:
|
||||
return 0
|
||||
for id in _by_id:
|
||||
var base := int(_by_id[id].get("motion_idx", 0))
|
||||
var grade_count := clampi(int(_by_id[id].get("grades", 1)), 1, SKILL_EFFECT_COUNT)
|
||||
for grade in range(1, grade_count):
|
||||
if skill_effect_upgrade_enabled and base + grade * SKILL_GRADEGAP == motion_idx:
|
||||
return grade
|
||||
return 0
|
||||
|
||||
func _attrs(id: int) -> String:
|
||||
return String(_by_id.get(id, {}).get("attrs", ""))
|
||||
|
||||
@@ -281,6 +318,28 @@ func is_horse_skill(id: int) -> bool: # IsHorseSkill
|
||||
func is_moving_skill(id: int) -> bool: # IsMovingSkill
|
||||
return _has_attr(id, "MOVING_SKILL")
|
||||
|
||||
# CPythonSkill::GetMotionLoopCount(fSkillPoint): the value is calculated from
|
||||
# the same efficiency percentage as cooldown/SP and packed into OnUseSkill's
|
||||
# uArg low nibble by CActorInstance::__OnUseSkill.
|
||||
func motion_loop_count_of(id: int, level: int) -> int:
|
||||
var formula := String(_by_id.get(id, {}).get("motion_loop_count_formula", ""))
|
||||
if formula == "":
|
||||
return 0
|
||||
var expression := Expression.new()
|
||||
if expression.parse(formula, ["SkillPoint"]) != OK:
|
||||
return 0
|
||||
var value: Variant = expression.execute([_skill_point(level)])
|
||||
if expression.has_execute_failed() or not (value is float or value is int):
|
||||
return 0
|
||||
return maxi(0, int(value))
|
||||
|
||||
# CActorInstance::__OnUseSkill: uArg = loop count | (isMovingSkill ? 1<<4 : 0).
|
||||
func motion_state_arg(id: int, level: int) -> int:
|
||||
var arg := motion_loop_count_of(id, level) & 0x0f
|
||||
if is_moving_skill(id):
|
||||
arg |= 1 << 4
|
||||
return arg
|
||||
|
||||
func is_melee(id: int) -> bool: # IsMeleeSkill
|
||||
return _has_attr(id, "MELEE_ATTACK")
|
||||
|
||||
@@ -437,6 +496,9 @@ func _load_msk(entry: Dictionary) -> void:
|
||||
var tcf := _ascii_field(bytes, "TargetCountFormula")
|
||||
if tcf != "":
|
||||
entry["target_count_formula"] = tcf.trim_prefix("\"").trim_suffix("\"")
|
||||
var mlcf := _ascii_field(bytes, "MotionLoopCountFormula")
|
||||
if mlcf != "":
|
||||
entry["motion_loop_count_formula"] = mlcf.trim_prefix("\"").trim_suffix("\"")
|
||||
var trange := _ascii_field(bytes, "Range")
|
||||
if trange != "":
|
||||
entry["target_range"] = max(0, int(trange.trim_prefix("\"").trim_suffix("\"")))
|
||||
|
||||
Reference in New Issue
Block a user