骑马与砍杀中文站论坛

标题: 【代码】自动生成完美对称的3分支树形图 [打印本页]

作者: rubik    时间: 2016-9-15 09:29
标题: 【代码】自动生成完美对称的3分支树形图
本帖最后由 rubik 于 2016-9-15 09:43 编辑

先上图:


这个帖子的代码是我写的自动生成兵种升级树图谱的拓展,从2分支拓展到3分支的情况。
自动生成兵种升级树图谱的帖子:
http://bbs.mountblade.com.cn/thread-520151-1-1.html

代码如下:
这一段作为一个菜单项加入某个菜单里,比如module_game_menus.py里的"reports"菜单。
      ("action_view_tri_branch",[],"Tri-Branch.",
      [
        (call_script, "script_tri_branch_troop_data_test"),
        (start_presentation, "prsnt_tri_branch"),
      ]
       ), # test code

这一段代码是一个完整的presentation,加入到module_presentations.py里面。
  ("tri_branch",0,0,[
    (ti_on_presentation_load,
      [
        (presentation_set_duration, 999999),
        (set_fixed_point_multiplier, 1000),
        
        (assign, ":root_troop", 0),
        
        (create_mesh_overlay, reg1, "mesh_load_window"),
        (position_set_x, pos1, 0),
        (position_set_y, pos1, 0),
        (overlay_set_position, reg1, pos1),
        
        ## back
        (create_game_button_overlay, "$g_presentation_obj_admin_panel_1", "@Done"),
        (position_set_x, pos1, 900),
        (position_set_y, pos1, 25),
        (overlay_set_position, "$g_presentation_obj_admin_panel_1", pos1),

        (str_clear, s0),
        (create_text_overlay, reg1, s0, tf_scrollable),
        (position_set_x, pos1, 15),
        (position_set_y, pos1, 80),
        (overlay_set_position, reg1, pos1),
        (position_set_x, pos1, 950),
        (position_set_y, pos1, 600),
        (overlay_set_area_size, reg1, pos1),
        (set_container_overlay, reg1),
        
        (assign, reg2, 100),
        (call_script, "script_tri_branch_recursive_backtracking", ":root_troop", 50, reg2, 150),
        
        (set_container_overlay, -1),

      ]),
         
    (ti_on_presentation_event_state_change,
      [
        (store_trigger_param_1, ":object"),
        
        (try_begin),
          (eq, ":object", "$g_presentation_obj_admin_panel_1"),
          (presentation_set_duration, 0),
        (try_end),
      ]),
    ]),

这2个script加入到module_scripts.py里面。
前一个是定义树形图的分支关系,后一个就是核心的“递归-回溯”逻辑代码。
  ("tri_branch_troop_data_test",
    [
      (troop_set_slot, 0, 0, 1),
      (troop_set_slot, 0, 1, 2),
      (troop_set_slot, 0, 2, 3),
      
      (troop_set_slot, 1, 0, 4),
      (troop_set_slot, 1, 1, 5),
      (troop_set_slot, 1, 2, 0),
      
      (troop_set_slot, 2, 0, 6),
      (troop_set_slot, 2, 1, 7),
      (troop_set_slot, 2, 2, 8),
      
      (troop_set_slot, 3, 0, 0),
      (troop_set_slot, 3, 1, 0),
      (troop_set_slot, 3, 2, 0),
      
      (troop_set_slot, 4, 0, 0),
      (troop_set_slot, 4, 1, 0),
      (troop_set_slot, 4, 2, 0),
      
      (troop_set_slot, 5, 0, 9),
      (troop_set_slot, 5, 1, 10),
      (troop_set_slot, 5, 2, 0),
      
      (troop_set_slot, 6, 0, 0),
      (troop_set_slot, 6, 1, 0),
      (troop_set_slot, 6, 2, 0),
      
      (troop_set_slot, 7, 0, 0),
      (troop_set_slot, 7, 1, 0),
      (troop_set_slot, 7, 2, 0),
      
      (troop_set_slot, 8, 0, 0),
      (troop_set_slot, 8, 1, 0),
      (troop_set_slot, 8, 2, 0),
      
      (troop_set_slot, 9, 0, 0),
      (troop_set_slot, 9, 1, 0),
      (troop_set_slot, 9, 2, 0),
      
      (troop_set_slot, 10, 0, 0),
      (troop_set_slot, 10, 1, 0),
      (troop_set_slot, 10, 2, 0),
    ]),
   
   ("tri_branch_recursive_backtracking",
    [
      (store_script_param, ":troop_no", 1),
      (store_script_param, ":cur_x", 2),
      (store_script_param, ":cur_y", 3),
      (store_script_param, ":offset_x", 4),
      
      (store_add, ":next_x", ":cur_x", ":offset_x"),
      # upgrade_troop
      (troop_get_slot, ":upgrade_troop_1", ":troop_no", 0),
      (troop_get_slot, ":upgrade_troop_2", ":troop_no", 1),
      (troop_get_slot, ":upgrade_troop_3", ":troop_no", 2),
      (try_begin),
        (gt,  ":upgrade_troop_3", 0),
        (call_script, "script_tri_branch_recursive_backtracking", ":upgrade_troop_3", ":next_x", reg2, ":offset_x"),
        (assign, ":upgrade_troop_3_y", reg0),
        (val_add, reg2, 50), # current global y
        (call_script, "script_tri_branch_recursive_backtracking", ":upgrade_troop_2", ":next_x", reg2, ":offset_x"),
        (assign, ":upgrade_troop_2_y", reg0),
        (val_add, reg2, 50), # current global y
        (call_script, "script_tri_branch_recursive_backtracking", ":upgrade_troop_1", ":next_x", reg2, ":offset_x"),
        (assign, ":upgrade_troop_1_y", reg0),
      (else_try),
        (gt,  ":upgrade_troop_2", 0),
        (call_script, "script_tri_branch_recursive_backtracking", ":upgrade_troop_2", ":next_x", reg2, ":offset_x"),
        (assign, ":upgrade_troop_2_y", reg0),
        (val_add, reg2, 50), # current global y
        (call_script, "script_tri_branch_recursive_backtracking", ":upgrade_troop_1", ":next_x", reg2, ":offset_x"),
        (assign, ":upgrade_troop_1_y", reg0),
      (else_try),
        (gt,  ":upgrade_troop_1", 0),
        (call_script, "script_tri_branch_recursive_backtracking", ":upgrade_troop_1", ":next_x", reg2, ":offset_x"),
        (assign, ":upgrade_troop_1_y", reg0),
      (try_end),
      
      # troop_tree_line
      (try_begin),
        (gt,  ":upgrade_troop_3", 0),
        (store_add, reg0, ":upgrade_troop_1_y", ":upgrade_troop_3_y"),
        (val_div, reg0, 2),
        #               ---- upgrade_troop_1
        #              |
        # troop_no --------- upgrade_troop_2
        #              |
        #               ---- upgrade_troop_3
        (store_div, ":half_offset_x", ":offset_x", 2),
        (store_add, ":middle_x", ":cur_x", ":half_offset_x"),
        (call_script, "script_prsnt_line", ":half_offset_x", 4, ":cur_x", reg0, 0),
        (call_script, "script_prsnt_line", ":half_offset_x", 4, ":middle_x", ":upgrade_troop_1_y", 0),
        (call_script, "script_prsnt_line", ":half_offset_x", 4, ":middle_x", ":upgrade_troop_2_y", 0),
        (call_script, "script_prsnt_line", ":half_offset_x", 4, ":middle_x", ":upgrade_troop_3_y", 0),
        (store_sub, ":size_y", ":upgrade_troop_1_y", ":upgrade_troop_3_y"),
        (val_add, ":size_y", 4),
        (call_script, "script_prsnt_line", 4, ":size_y", ":middle_x", ":upgrade_troop_3_y", 0),
      (else_try),
        (gt,  ":upgrade_troop_2", 0),
        (store_add, reg0, ":upgrade_troop_1_y", ":upgrade_troop_2_y"),
        (val_div, reg0, 2),
        #               ---- upgrade_troop_1
        #              |
        # troop_no ----
        #              |
        #               ---- upgrade_troop_2
        (store_div, ":half_offset_x", ":offset_x", 2),
        (store_add, ":middle_x", ":cur_x", ":half_offset_x"),
        (call_script, "script_prsnt_line", ":half_offset_x", 4, ":cur_x", reg0, 0),
        (call_script, "script_prsnt_line", ":half_offset_x", 4, ":middle_x", ":upgrade_troop_1_y", 0),
        (call_script, "script_prsnt_line", ":half_offset_x", 4, ":middle_x", ":upgrade_troop_2_y", 0),
        (store_sub, ":size_y", ":upgrade_troop_1_y", ":upgrade_troop_2_y"),
        (val_add, ":size_y", 4),
        (call_script, "script_prsnt_line", 4, ":size_y", ":middle_x", ":upgrade_troop_2_y", 0),
      (else_try),
        (gt,  ":upgrade_troop_1", 0),
        (assign, reg0, ":upgrade_troop_1_y"),
        #
        # troop_no -------- upgrade_troop_1
        #
        (call_script, "script_prsnt_line", ":offset_x", 4, ":cur_x", ":upgrade_troop_1_y", 0),
      (else_try),
        (assign, reg0, ":cur_y"),
      (try_end),
      
      # troop block
      (create_mesh_overlay, reg1, "mesh_white_plane"),
      (position_set_x, pos0, 40*50),
      (position_set_y, pos0, 40*50),
      (overlay_set_size, reg1, pos0),
      (store_sub, ":block_x", ":cur_x", 20),
      (store_sub, ":block_y", reg0, 20),
      (position_set_x, pos0, ":block_x"),
      (position_set_y, pos0, ":block_y"),
      (overlay_set_position, reg1, pos0),
      
      # troop id
      (assign, reg3, ":troop_no"),
      (create_text_overlay, reg1, "@{reg3}", tf_center_justify|tf_vertical_align_center),
      (position_set_x, pos0, ":cur_x"),
      (position_set_y, pos0, reg0),
      (overlay_set_position, reg1, pos0),
    ]),


作者: rubik    时间: 2016-9-15 09:37
本帖最后由 rubik 于 2016-9-15 10:05 编辑

截图和代码已经把实际的效果演示出来。 这段代码并没有特指对象的类型,虽然用的是troop的slot,但适应于任何类型,比如技能升级树,建筑升级树等等。各MOD制作者把代码复制回去之后,需要套上自己MOD相关的分支设定,行距什么的也可能需要调整。这里的对象外在表现形式是方块,具体到MOD里面就换成某种图标。 名字这里是数字,具体到MOD里面就换成对象的名字,坐标也需要调一下。

这里是横向形式,稍作修改就可以变成纵向形式。 另外,这段代码也很容易拓展到4分支的情况,只是“递归-回溯”逻辑的代码看起来就不那么精炼,多一个分支就多两段else_try分支代码,有点简单铺陈的感觉。但3~4个分支就用循环来处理,必要性也不大。
作者: sunary100    时间: 2016-9-15 17:32
R大又脑洞大开了
作者: hushuailiner2    时间: 2016-9-15 19:51
引擎指导的 升级 线路不是只有两条吗?  虽然图可以这画,但是实际的升级线路却不能选多条吧!
作者: rubik    时间: 2016-9-15 21:57
hushuailiner2 发表于 2016-9-15 19:51
引擎指导的 升级 线路不是只有两条吗?  虽然图可以这画,但是实际的升级线路却不能选多条吧!

2楼已经解释了。所以标题里用的是树形图这个词,而不是兵种升级树。树形图可以应用于很多方面,比如技能升级树,换兵的分支树等。
作者: 心微凉27    时间: 2016-9-15 23:51
R大辛苦了  ~

作者: yk199810    时间: 2016-9-16 13:59
R大辛苦了
作者: 蛋清    时间: 2016-9-16 20:06
我在想这东西能不能通过try for range一步到位




欢迎光临 骑马与砍杀中文站论坛 (https://bbs.mountblade.com.cn/) Powered by Discuz! X3.4