骑马与砍杀中文站论坛

 找回密码
 注册(Register!)

QQ登录

只需一步,快速开始

搜索
购买霸主CDKEY 购买战帆CDKEY
查看: 594|回复: 1

[功能与代码] 花糕的Tool——drag_tool(拖拽放置overlay并输出pos)

[复制链接]

22

主题

738

回帖

393

积分

见习骑士

Rank: 3

UID
3102512
第纳尔
2465
精华
0
互助
33
荣誉
0
贡献
0
魅力
85
注册时间
2019-9-6

骑砍中文站APP会员勋章战团正版勋章霸主正版勋章

鲜花(69) 鸡蛋(0)
发表于 2026-2-26 09:51:14 | 显示全部楼层 |阅读模式
本帖最后由 huagao 于 2026-2-26 10:50 编辑

    关于骑砍战团的prsnt一节,事实上rubik的十字座标是这么多年只要做prsnt的modder都会用的定位方法,但弊端在于需要在实际prsnt界面中对照坐标参数重新set pos,并且对于一些形状大小不规则的overlay通常需要反复调试。即使在有热重载和txt修正的加持下我经常也浪费了很多时间。    所以这个拖拽放置并自动输出到log的功能是我很久之前一直想弄的,正好许久没搓ms了,今天抽空把这个想法实现了。已经将代码模块化了,可以一键复用到任意 presentation 中,这个工具是方便mod开发者对prsnt快速布局并定位、调整overlay,适配所有按规范要求书写的prsnt。


    很无语的是中文站的代码粘贴又把我的缩进吞了,有强迫症的可以去B站看B站展示




需要注意几点
1.适配的prsnt中所有的overlay定义的时候需要严格按照$g_presentation_obj_X的格式按1开始的顺序书写。原因很简单因为我无法获取到其他人源代码中overlay的命名,只能按照ms通用的来实现输出代码到log。

2.tool的使用一定要加到prsnt的末尾并且保证这个tool在其他tool之前,例如下面的test

  1. ("test", 0, mesh_load_window,
  2.    [
  3.     (load,
  4.     [
  5.     (presentation_set_duration, 9999999),
  6.     ]),
  7.     (run,[]),
  8.     (enter_or_leave,[]),
  9.     (button,[]),
  10.     (click,[]),
  11. ] + drag_tool + pos_tool + quit_tool + ……),
复制代码


原因也很简单因为我实际获取prsnt中所有overlay的数量是通过这个drag_tool的第一个overlay的索引序号掌握的,所以需要保证该tool一定要在所应用的prsnt的最后以保证没有遗漏的overlay。并且放在tool序列最前端以保证其他的tool生成的overlay不会干扰到输出结果

3.ID被覆盖的overlay都可以获取到,只是输出因为没有存储地方,所以从第一个id被覆盖的overlay之后的输出都会有问题。这个是没有办法的,只能自己规范书写或者把所有会被覆盖id的overlay都丢到后面到时候手动赋值。因为用的是ti_on_presentation_mouse_press,所有overlay都可以互动到(只要鼠标能点到),同样的互动event_state_change只能和button类互动。


4.因为骑砍引擎的问题,所有输出的下划线都会被强制换成空格,日志里的代码需要自己单独找个txt批量替换一下。


5.还没有用过我的简化书写触发器名的需要重新定义一下,因为我用习惯了懒得改。在prsnt列表外部加

  1. #huagao: triggers id rename
  2. load = ti_on_presentation_load
  3. run = ti_on_presentation_run
  4. button = ti_on_presentation_event_state_change
  5. enter_or_leave = ti_on_presentation_mouse_enter_leave
  6. click = ti_on_presentation_mouse_press
复制代码

话不多嗦,上代码
  1. #huagao: tool

  2. drag_tool = [

  3.     (load, [
  4.         # 输出坐标按钮
  5.         (create_game_button_overlay, "$drag_output_btn", "@输 出 坐 标 "),
  6.         (position_set_x, pos1, 80),
  7.         (position_set_y, pos1, 680),
  8.         (overlay_set_position, "$drag_output_btn", pos1),

  9.         # 创建对齐线(水平/垂直),初始隐藏
  10.         (create_mesh_overlay, "$drag_hline", "mesh_white_plane"),

  11.         (create_mesh_overlay, "$drag_vline", "mesh_white_plane"),

  12.         (overlay_set_color, "$drag_hline", 0xFF0000),
  13.         (overlay_set_color, "$drag_vline", 0xFF0000),
  14.         #(overlay_set_alpha, "$drag_hline", 0x80),
  15.         #(overlay_set_alpha, "$drag_vline", 0x80),
  16.         (overlay_set_display, "$drag_hline", 0),
  17.         (overlay_set_display, "$drag_vline", 0),

  18.         # 初始化拖拽状态
  19.         (assign, "$drag_active", 0),
  20.         (assign, "$drag_current", -1),
  21.         (assign, "$drag_current_index", -1),

  22.         # 计算 overlay 总数:$drag_output_btn 的值就是应用界面所有实际 overlay 的数量
  23.         (assign, "$drag_overlay_count", "$drag_output_btn"),
  24.     ]),

  25.     (run, [
  26.         (set_fixed_point_multiplier, 1000),
  27.         (mouse_get_position, pos63),
  28.         (position_get_x, "$drag_mouse_x", pos63),
  29.         (position_get_y, "$drag_mouse_y", pos63),

  30.         # 拖拽处理
  31.         (try_begin),
  32.             (eq, "$drag_active", 1),
  33.             (key_is_down, key_left_mouse_button),
  34.             (ge, "$drag_current", 0),

  35.             # 更新被拖拽对象的位置到鼠标
  36.             (overlay_set_position, "$drag_current", pos63),

  37.             # 获取当前对象坐标
  38.             (overlay_get_position, pos0, "$drag_current"),
  39.             (position_get_x, ":cur_x", pos0),
  40.             (position_get_y, ":cur_y", pos0),

  41.             # 寻找最近的对齐线
  42.             (assign, ":best_dx", 9999),
  43.             (assign, ":best_dy", 9999),
  44.             (assign, ":align_x", -1),
  45.             (assign, ":align_y", -1),

  46.             (try_for_range, ":i", 0, "$drag_overlay_count"),
  47.                 (neq, ":i", "$drag_current"),   # 排除自身
  48.                 (overlay_get_position, pos1, ":i"),
  49.                 (position_get_x, ":ox", pos1),
  50.                 (position_get_y, ":oy", pos1),

  51.                 # X轴差值
  52.                 (store_sub, ":dx", ":ox", ":cur_x"),
  53.                 (val_abs, ":dx"),
  54.                 (try_begin),
  55.                     (le, ":dx", 50),
  56.                     (lt, ":dx", ":best_dx"),
  57.                     (assign, ":best_dx", ":dx"),
  58.                     (assign, ":align_x", ":ox"),
  59.                 (try_end),

  60.                 # Y轴差值
  61.                 (store_sub, ":dy", ":oy", ":cur_y"),
  62.                 (val_abs, ":dy"),
  63.                 (try_begin),
  64.                     (le, ":dy", 50),
  65.                     (lt, ":dy", ":best_dy"),
  66.                     (assign, ":best_dy", ":dy"),
  67.                     (assign, ":align_y", ":oy"),
  68.                 (try_end),
  69.             (try_end),

  70.             # 显示垂直线
  71.             (try_begin),
  72.                 (ge, ":align_x", 0),
  73.                 (position_set_x, pos1, ":align_x"),
  74.                 (position_set_y, pos1, 0),
  75.                 (overlay_set_position, "$drag_vline", pos1),
  76.                 (position_set_x, pos1, 20),
  77.                 (position_set_y, pos1, 50000),
  78.                 (overlay_set_size, "$drag_vline", pos1),
  79.                 (overlay_set_display, "$drag_vline", 1),
  80.             (else_try),
  81.                 (overlay_set_display, "$drag_vline", 0),
  82.             (try_end),

  83.             # 显示水平线
  84.             (try_begin),
  85.                 (ge, ":align_y", 0),
  86.                 (position_set_x, pos1, 0),
  87.                 (position_set_y, pos1, ":align_y"),
  88.                 (overlay_set_position, "$drag_hline", pos1),
  89.                 (position_set_x, pos1, 50000),
  90.                 (position_set_y, pos1, 20),
  91.                 (overlay_set_size, "$drag_hline", pos1),
  92.                 (overlay_set_display, "$drag_hline", 1),
  93.             (else_try),
  94.                 (overlay_set_display, "$drag_hline", 0),
  95.             (try_end),

  96.         (else_try),
  97.             # 无拖拽时隐藏对齐线
  98.             (overlay_set_display, "$drag_vline", 0),
  99.             (overlay_set_display, "$drag_hline", 0),
  100.         (try_end),

  101.         # 检测左键松开,结束拖拽
  102.         (try_begin),
  103.             (eq, "$drag_active", 1),
  104.             (neg|key_is_down, key_left_mouse_button),
  105.             (assign, "$drag_active", 0),
  106.             (assign, "$drag_current", -1),
  107.             (assign, "$drag_current_index", -1),
  108.         (try_end),
  109.     ]),

  110.     (click, [
  111.         (store_trigger_param_1, ":clicked_obj"),
  112.         (store_trigger_param_2, ":mouse_button"),

  113.         # Ctrl + 左键 开始拖拽
  114.         (try_begin),
  115.             (eq, ":mouse_button", 0),   # 0 = 左键
  116.             (this_or_next|key_is_down, key_left_control),
  117.             (key_is_down, key_right_control),

  118.             (assign, "$drag_current", ":clicked_obj"),
  119.             (assign, "$drag_active", 1),
  120.             (assign, "$drag_current_index", ":clicked_obj"),   # 索引直接就是 ID
  121.         (try_end),
  122.     ]),

  123.     (button, [
  124.         (store_trigger_param_1, ":clicked_obj"),
  125.         (eq, ":clicked_obj", "$drag_output_btn"),
  126.         (display_log_message,"@##开 始 输 出 当 前  prsnt  所 有 overlay 重 定 位 pos"),
  127.         # 输出所有overlay的坐标
  128.         (try_for_range, ":i", 0, "$drag_overlay_count"),
  129.             (overlay_get_position, pos1, ":i"),
  130.             (position_get_x, ":x", pos1),
  131.             (position_get_y, ":y", pos1),

  132.             # 将索引(从1开始)存入reg0,用于生成变量名$g_presentation_obj_{reg0}
  133.             (assign, reg0, ":i"),
  134.             (val_add, reg0, 1),

  135.             # 输出定位代码
  136.             (str_store_string, s0, "@(init_position,pos1),"),
  137.             (display_log_message, s0),

  138.             (assign, reg0, ":x"),
  139.             (str_store_string, s0, "@(position_set_x,pos1,{reg0}),"),
  140.             (display_log_message, s0),

  141.             (assign, reg0, ":y"),
  142.             (str_store_string, s0, "@ (position_set_y,pos1,{reg0}),"),
  143.             (display_log_message, s0),

  144.             (assign, reg0, ":i"),
  145.             (val_add, reg0, 1),
  146.             (str_store_string, s0, "@(overlay_set_position,$g_presentation_obj_{reg0},pos1),^"),#末尾多加了一个换行符
  147.             (display_log_message, s0),
  148.         (try_end),
  149.     ]),
  150. ]
复制代码
   实际使用参考上面注意事项里面的参考代码,直接加在prsnt内部方括号后就可以实现一键部署,进入界面后Ctrl加左键即可实现对overlay的拖拽,最后点击左上方输出坐标,去战团根目录的rgl log日志文件中将输出的代码复制出来批量将空格替换成下划线,就可以粘贴到prsnt源码的load末尾了(有在其他触发器定义overlay的自己调整位置)。

(定位时自动吸附对齐功能有点难写,抽空再补)





鲜花鸡蛋

路过的罗格  在2026-3-2 22:13  送朵鲜花  并说:我非常同意你的观点,送朵鲜花鼓励一下
解解解解解解解解解解解解解解解解解解

38

主题

259

回帖

204

积分

见习骑士

Rank: 3

UID
2462463
第纳尔
1632
精华
0
互助
23
荣誉
0
贡献
0
魅力
86
注册时间
2015-3-3
鲜花(67) 鸡蛋(0)
发表于 2026-3-2 16:26:54 | 显示全部楼层
解解解解解解解解解解解解解解解解解解侠天下第一!
您需要登录后才可以回帖 登录 | 注册(Register!)

本版积分规则

Archiver|手机版|小黑屋|骑马与砍杀中文站

GMT+8, 2026-3-20 05:57 , Processed in 0.091827 second(s), 21 queries , Gzip On, MemCached On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表