本帖最后由 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
- ("test", 0, mesh_load_window,
- [
- (load,
- [
- (presentation_set_duration, 9999999),
- ]),
- (run,[]),
- (enter_or_leave,[]),
- (button,[]),
- (click,[]),
- ] + 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列表外部加 - #huagao: triggers id rename
- load = ti_on_presentation_load
- run = ti_on_presentation_run
- button = ti_on_presentation_event_state_change
- enter_or_leave = ti_on_presentation_mouse_enter_leave
- click = ti_on_presentation_mouse_press
复制代码
话不多嗦,上代码
- #huagao: tool
- drag_tool = [
- (load, [
- # 输出坐标按钮
- (create_game_button_overlay, "$drag_output_btn", "@输 出 坐 标 "),
- (position_set_x, pos1, 80),
- (position_set_y, pos1, 680),
- (overlay_set_position, "$drag_output_btn", pos1),
- # 创建对齐线(水平/垂直),初始隐藏
- (create_mesh_overlay, "$drag_hline", "mesh_white_plane"),
- (create_mesh_overlay, "$drag_vline", "mesh_white_plane"),
- (overlay_set_color, "$drag_hline", 0xFF0000),
- (overlay_set_color, "$drag_vline", 0xFF0000),
- #(overlay_set_alpha, "$drag_hline", 0x80),
- #(overlay_set_alpha, "$drag_vline", 0x80),
- (overlay_set_display, "$drag_hline", 0),
- (overlay_set_display, "$drag_vline", 0),
- # 初始化拖拽状态
- (assign, "$drag_active", 0),
- (assign, "$drag_current", -1),
- (assign, "$drag_current_index", -1),
- # 计算 overlay 总数:$drag_output_btn 的值就是应用界面所有实际 overlay 的数量
- (assign, "$drag_overlay_count", "$drag_output_btn"),
- ]),
- (run, [
- (set_fixed_point_multiplier, 1000),
- (mouse_get_position, pos63),
- (position_get_x, "$drag_mouse_x", pos63),
- (position_get_y, "$drag_mouse_y", pos63),
- # 拖拽处理
- (try_begin),
- (eq, "$drag_active", 1),
- (key_is_down, key_left_mouse_button),
- (ge, "$drag_current", 0),
- # 更新被拖拽对象的位置到鼠标
- (overlay_set_position, "$drag_current", pos63),
- # 获取当前对象坐标
- (overlay_get_position, pos0, "$drag_current"),
- (position_get_x, ":cur_x", pos0),
- (position_get_y, ":cur_y", pos0),
- # 寻找最近的对齐线
- (assign, ":best_dx", 9999),
- (assign, ":best_dy", 9999),
- (assign, ":align_x", -1),
- (assign, ":align_y", -1),
- (try_for_range, ":i", 0, "$drag_overlay_count"),
- (neq, ":i", "$drag_current"), # 排除自身
- (overlay_get_position, pos1, ":i"),
- (position_get_x, ":ox", pos1),
- (position_get_y, ":oy", pos1),
- # X轴差值
- (store_sub, ":dx", ":ox", ":cur_x"),
- (val_abs, ":dx"),
- (try_begin),
- (le, ":dx", 50),
- (lt, ":dx", ":best_dx"),
- (assign, ":best_dx", ":dx"),
- (assign, ":align_x", ":ox"),
- (try_end),
- # Y轴差值
- (store_sub, ":dy", ":oy", ":cur_y"),
- (val_abs, ":dy"),
- (try_begin),
- (le, ":dy", 50),
- (lt, ":dy", ":best_dy"),
- (assign, ":best_dy", ":dy"),
- (assign, ":align_y", ":oy"),
- (try_end),
- (try_end),
- # 显示垂直线
- (try_begin),
- (ge, ":align_x", 0),
- (position_set_x, pos1, ":align_x"),
- (position_set_y, pos1, 0),
- (overlay_set_position, "$drag_vline", pos1),
- (position_set_x, pos1, 20),
- (position_set_y, pos1, 50000),
- (overlay_set_size, "$drag_vline", pos1),
- (overlay_set_display, "$drag_vline", 1),
- (else_try),
- (overlay_set_display, "$drag_vline", 0),
- (try_end),
- # 显示水平线
- (try_begin),
- (ge, ":align_y", 0),
- (position_set_x, pos1, 0),
- (position_set_y, pos1, ":align_y"),
- (overlay_set_position, "$drag_hline", pos1),
- (position_set_x, pos1, 50000),
- (position_set_y, pos1, 20),
- (overlay_set_size, "$drag_hline", pos1),
- (overlay_set_display, "$drag_hline", 1),
- (else_try),
- (overlay_set_display, "$drag_hline", 0),
- (try_end),
- (else_try),
- # 无拖拽时隐藏对齐线
- (overlay_set_display, "$drag_vline", 0),
- (overlay_set_display, "$drag_hline", 0),
- (try_end),
- # 检测左键松开,结束拖拽
- (try_begin),
- (eq, "$drag_active", 1),
- (neg|key_is_down, key_left_mouse_button),
- (assign, "$drag_active", 0),
- (assign, "$drag_current", -1),
- (assign, "$drag_current_index", -1),
- (try_end),
- ]),
- (click, [
- (store_trigger_param_1, ":clicked_obj"),
- (store_trigger_param_2, ":mouse_button"),
- # Ctrl + 左键 开始拖拽
- (try_begin),
- (eq, ":mouse_button", 0), # 0 = 左键
- (this_or_next|key_is_down, key_left_control),
- (key_is_down, key_right_control),
- (assign, "$drag_current", ":clicked_obj"),
- (assign, "$drag_active", 1),
- (assign, "$drag_current_index", ":clicked_obj"), # 索引直接就是 ID
- (try_end),
- ]),
- (button, [
- (store_trigger_param_1, ":clicked_obj"),
- (eq, ":clicked_obj", "$drag_output_btn"),
- (display_log_message,"@##开 始 输 出 当 前 prsnt 所 有 overlay 重 定 位 pos"),
- # 输出所有overlay的坐标
- (try_for_range, ":i", 0, "$drag_overlay_count"),
- (overlay_get_position, pos1, ":i"),
- (position_get_x, ":x", pos1),
- (position_get_y, ":y", pos1),
- # 将索引(从1开始)存入reg0,用于生成变量名$g_presentation_obj_{reg0}
- (assign, reg0, ":i"),
- (val_add, reg0, 1),
- # 输出定位代码
- (str_store_string, s0, "@(init_position,pos1),"),
- (display_log_message, s0),
- (assign, reg0, ":x"),
- (str_store_string, s0, "@(position_set_x,pos1,{reg0}),"),
- (display_log_message, s0),
- (assign, reg0, ":y"),
- (str_store_string, s0, "@ (position_set_y,pos1,{reg0}),"),
- (display_log_message, s0),
- (assign, reg0, ":i"),
- (val_add, reg0, 1),
- (str_store_string, s0, "@(overlay_set_position,$g_presentation_obj_{reg0},pos1),^"),#末尾多加了一个换行符
- (display_log_message, s0),
- (try_end),
- ]),
- ]
复制代码 实际使用参考上面注意事项里面的参考代码,直接加在prsnt内部方括号后就可以实现一键部署,进入界面后Ctrl加左键即可实现对overlay的拖拽,最后点击左上方输出坐标,去战团根目录的rgl log日志文件中将输出的代码复制出来批量将空格替换成下划线,就可以粘贴到prsnt源码的load末尾了(有在其他触发器定义overlay的自己调整位置)。
(定位时自动吸附对齐功能有点难写,抽空再补)
|