花糕的Tool——drag_tool(拖拽放置overlay并输出pos)
花糕__
2026年02月26日 02:07
收录于文集
共1篇

#骑砍战团mod制作#​

已经将代码模块化了,可以一键复用到任意 presentation 中,这个工具是方便mod开发者对prsnt快速布局并定位、调整overlay,适配所有按规范要求书写的prsnt。


需要注意几点:

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

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

代码块
Python
自动换行
复制代码
("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列表外部加

代码块
Python
自动换行
复制代码
#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
复制成功

直接上代码

代码块
PlainText
自动换行
复制代码
#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的自己调整位置)。

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