fix: 装备属性面板避让逻辑 + 多项功能更新
- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
This commit is contained in:
+57
-33
@@ -84,6 +84,61 @@ static void combat_data(const Node& root, Msa& out) {
|
||||
}
|
||||
}
|
||||
|
||||
static void motion_event(const Node& ev, MotionEvent& e) {
|
||||
e.type = ev.inum("MotionEventType");
|
||||
e.start_time = ev.num("StartingTime");
|
||||
e.duration_time = ev.num("DuringTime");
|
||||
e.effect_file = ev.str("EffectFileName");
|
||||
e.sound_file = ev.str("SoundFileName");
|
||||
e.attaching_bone = ev.str("AttachingBoneName");
|
||||
e.attaching = ev.inum("AttachingEnable") != 0;
|
||||
e.following = ev.inum("FollowingEnable") != 0;
|
||||
e.independent = ev.inum("IndependentFlag") != 0;
|
||||
e.fishing_effect = ev.inum("FishingEffectFlag") != 0;
|
||||
vec3(ev.find("EffectPosition"), e.position);
|
||||
|
||||
// 40250 TMotionEventDataFly has its own resource and offset fields.
|
||||
e.fly_file = ev.str("FlyFileName");
|
||||
e.fly_attaching_bone = ev.str("AttachingBoneName");
|
||||
e.fly_attaching = ev.inum("AttachingEnable") != 0;
|
||||
vec3(ev.find("FlyPosition"), e.fly_position);
|
||||
|
||||
// 40250 TScreenWavingEventData defaults AffectingRange to zero and reads
|
||||
// DuringTime/Power from the event itself.
|
||||
e.power = ev.inum("Power");
|
||||
e.affecting_range = ev.inum("AffectingRange");
|
||||
|
||||
// 40250 TMotionAttackingEventData defaults EnableHitProcess to TRUE.
|
||||
e.enable_hit_process = ev.inum("EnableHitProcess", 1) != 0;
|
||||
e.attack_type = ev.inum("AttackType", ev.inum("AttackingType"));
|
||||
e.hitting_type = ev.inum("HittingType");
|
||||
e.stiffen_time = ev.num("StiffenTime");
|
||||
e.invisible_time = ev.num("InvisibleTime");
|
||||
e.external_force = ev.num("ExternalForce");
|
||||
e.hit_limit_count = ev.inum("HitLimitCount");
|
||||
e.collision_type = ev.inum("CollisionType");
|
||||
for (const Node& g : ev.groups) {
|
||||
if (g.name.size() < 10 || g.name.compare(0, 10, "SphereData") != 0)
|
||||
continue;
|
||||
MotionEvent::CollisionSphere sphere;
|
||||
sphere.radius = g.num("Radius");
|
||||
vec3(g.find("Position"), sphere.position);
|
||||
e.collision_spheres.push_back(sphere);
|
||||
}
|
||||
}
|
||||
|
||||
static void motion_events(const Node& root, Msa& out) {
|
||||
const Node* med = root.group("MotionEventData");
|
||||
if (!med) return;
|
||||
int count = med->inum("MotionEventDataCount", int(med->groups.size()));
|
||||
(void)count;
|
||||
for (const Node& ev : med->groups) {
|
||||
MotionEvent e;
|
||||
motion_event(ev, e);
|
||||
out.events.push_back(std::move(e));
|
||||
}
|
||||
}
|
||||
|
||||
bool parse_msa(const std::string& text, Msa& out, std::string* err) {
|
||||
Node root;
|
||||
if (!parse_textscript(text, root, err)) return false;
|
||||
@@ -95,24 +150,7 @@ bool parse_msa(const std::string& text, Msa& out, std::string* err) {
|
||||
loop_data(root, out);
|
||||
combat_data(root, out);
|
||||
|
||||
if (const Node* med = root.group("MotionEventData")) {
|
||||
int count = med->inum("MotionEventDataCount", int(med->groups.size()));
|
||||
(void)count;
|
||||
for (const Node& ev : med->groups) {
|
||||
MotionEvent e;
|
||||
e.type = ev.inum("MotionEventType");
|
||||
e.start_time = ev.num("StartingTime");
|
||||
e.effect_file = ev.str("EffectFileName");
|
||||
e.sound_file = ev.str("SoundFileName");
|
||||
e.attaching_bone = ev.str("AttachingBoneName");
|
||||
e.attaching = ev.inum("AttachingEnable") != 0;
|
||||
e.following = ev.inum("FollowingEnable") != 0;
|
||||
e.independent = ev.inum("IndependentFlag") != 0;
|
||||
e.fishing_effect = ev.inum("FishingEffectFlag") != 0;
|
||||
vec3(ev.find("EffectPosition"), e.position);
|
||||
out.events.push_back(std::move(e));
|
||||
}
|
||||
}
|
||||
motion_events(root, out);
|
||||
|
||||
if (out.motion_gr2.empty()) { if (err) *err = "msa: 缺 MotionFileName"; return false; }
|
||||
return true;
|
||||
@@ -128,21 +166,7 @@ bool parse_msa_file(const std::string& path, Msa& out, std::string* err) {
|
||||
vec3(root.find("Accumulation"), out.accumulation);
|
||||
loop_data(root, out);
|
||||
combat_data(root, out);
|
||||
if (const Node* med = root.group("MotionEventData"))
|
||||
for (const Node& ev : med->groups) {
|
||||
MotionEvent e;
|
||||
e.type = ev.inum("MotionEventType");
|
||||
e.start_time = ev.num("StartingTime");
|
||||
e.effect_file = ev.str("EffectFileName");
|
||||
e.sound_file = ev.str("SoundFileName");
|
||||
e.attaching_bone = ev.str("AttachingBoneName");
|
||||
e.attaching = ev.inum("AttachingEnable") != 0;
|
||||
e.following = ev.inum("FollowingEnable") != 0;
|
||||
e.independent = ev.inum("IndependentFlag") != 0;
|
||||
e.fishing_effect = ev.inum("FishingEffectFlag") != 0;
|
||||
vec3(ev.find("EffectPosition"), e.position);
|
||||
out.events.push_back(std::move(e));
|
||||
}
|
||||
motion_events(root, out);
|
||||
if (out.motion_gr2.empty()) { if (err) *err = "msa: 缺 MotionFileName (" + path + ")"; return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user