骑马与砍杀中文站论坛

 找回密码
 注册(Register!)

QQ登录

只需一步,快速开始

搜索
购买CDKEY 小黑盒加速器
查看: 2332|回复: 3

[功能与代码] 流水线化boss战AI(先行测试)

[复制链接]

41

主题

94

回帖

221

积分

见习骑士

Rank: 3

UID
3199602
第纳尔
1162
精华
0
互助
36
荣誉
0
贡献
1
魅力
227
注册时间
2020-9-4
鲜花(60) 鸡蛋(0)
发表于 2024-8-8 09:07:56 | 显示全部楼层 |阅读模式
本帖最后由 奥杜因阿卡托什 于 2024-8-8 09:17 编辑

之前加过各种各样的主动技能,但是一直没让AI用上,现在终于是把波士战的AI搓出来了。而且用了一些手段把这个AI封装了,能够流水线化地设置。效果看视频。


下面放代码。注意这次的代码不是可以直接拿去用的,因为有很多我自己的系统和技能。看看框架即可。
先看slot
  1. #AI相关
  2. #下述的各种信息都是在获取信息的触发器里分析的,除此之外还有血量、盾量、弹药量等能直接获取的信息。
  3. slot_ai_battle_mode      = 100#根据目前装备分析自己的战斗模式,分为剑盾1、枪兵2、双手3、步射4、混战骑5、枪骑6、游骑7。
  4. slot_ai_action_number      = 101#当前正在执行的行为,序号每个ai的都不尽相同。
  5. slot_ai_target      = 102#目标,主要用于各种位移类技能。索敌范围暂定为30米,超过这个范围就会丢失目标,需要重新索敌。boss战无距离限制。
  6. slot_ai_target_distance      = 103#目标的距离(单位米)
  7. slot_ai_target_battle_mode      = 104#目标战斗模式

  8. slot_ai_ally_number      = 105#友军总数
  9. slot_ai_ally_number_5m      = 106#五米内友军总数
  10. slot_ai_enemy_number      = 107#敌军总数
  11. slot_ai_enemy_number_5m      = 108#五米内敌军总数
复制代码
header我也加了,加在header_mission_template里
  1. #ai战斗模式分析
  2. ai_saber    = 1    #剑盾(带盾+单手武器/双手武器+步行)
  3. ai_pikeman    = 2    #矛兵(带盾+长杆武器+步行)
  4. ai_berserker    = 3    #双手豪杰(不带盾+近战+步行)
  5. ai_archer    = 4    #步射(远程+步行)
  6. ai_cavalry    = 5    #混战骑兵(骑马+非长杆近战)
  7. ai_lancer    = 6    #枪骑兵(骑马+长杆/或可以骑枪冲锋)
  8. ai_ranger    = 7    #游骑兵(骑马+远程)

复制代码
触发器其实一共也就两个,核心的就一个,可以说是非常轻量化集成化了。
  1. #第一个触发器,刷出agent的时候储存一下波士信息。
  2.      (ti_on_agent_spawn, 0, 0,
  3.        [],
  4.        [
  5.        (store_trigger_param_1, ":agent_no"),
  6.        (agent_is_human, ":agent_no"),
  7.        (agent_is_alive, ":agent_no"),

  8.        (agent_set_slot, ":agent_no", slot_ai_target, -1),#清空
  9.        (agent_get_troop_id, ":troop_no", ":agent_no"),
  10.        (eq, ":troop_no", "trp_starkhook_megalith_berserker"),#岩雷狂战士
  11.        (assign, "$mission_boss_1", ":agent_no"),
  12. #$mission_boss_1这里可以填123,最多支持三人组波士(腐败结晶人x),不过目前来说不能把两个波士设置成同一个兵种,不然AI触发器就没法控制了。
  13.        ]),
复制代码
  1. #boss战AI
  2. #要用在哪个mt里,就把boss_trigger_starkhook_megalith_berserker这个写在这个mt的common trigger之后,一键装载了属于是。
  3. boss_trigger_starkhook_megalith_berserker =    (1, 0, 0,#斯塔胡克岩雷狂战士
  4.        [
  5.           (assign, "$mission_boss_agent", -1),
  6.           (try_begin),
  7.              (ge, "$mission_boss_1", 0),
  8.              (agent_is_alive, "$mission_boss_1"),
  9.              (agent_get_troop_id, ":troop_no", "$mission_boss_1"),
  10.              (eq, ":troop_no", "trp_starkhook_megalith_berserker"),#岩雷狂战士
  11.              (assign, "$mission_boss_agent", "$mission_boss_1"),
  12.           (else_try),
  13.              (ge, "$mission_boss_2", 0),
  14.              (agent_is_alive, "$mission_boss_2"),
  15.              (agent_get_troop_id, ":troop_no", "$mission_boss_2"),
  16.              (eq, ":troop_no", "trp_starkhook_megalith_berserker"),#岩雷狂战士
  17.              (assign, "$mission_boss_agent", "$mission_boss_2"),
  18.           (else_try),
  19.              (ge, "$mission_boss_3", 0),
  20.              (agent_is_alive, "$mission_boss_3"),
  21.              (agent_get_troop_id, ":troop_no", "$mission_boss_3"),
  22.              (eq, ":troop_no", "trp_starkhook_megalith_berserker"),#岩雷狂战士
  23.              (assign, "$mission_boss_agent", "$mission_boss_3"),
  24.           (try_end),
  25.           (ge, "$mission_boss_agent", 0),
  26.        ],
  27.        [
  28. #AI状态获取(主要获取距离相关的信息),信息储存进slot里
  29. #—————————————————————————————————获取—————————————————————————————————
  30.        (call_script, "script_agent_ai_battle_mode", "$mission_boss_agent"),#战斗模式分析
  31.        (assign, ":agent_battle_mode", reg1),

  32.        #目标
  33.        (agent_get_slot, ":target_agent_no", "$mission_boss_agent", slot_ai_target),
  34.        (try_begin),
  35.           (lt, ":target_agent_no", 0),#boss战特供锁定玩家
  36.           (assign, ":target_agent_no", "$mission_player_agent"),
  37.           (agent_set_slot, "$mission_boss_agent", slot_ai_target, ":target_agent_no"),
  38.        (try_end),

  39.        (agent_get_position, pos1, "$mission_boss_agent"),
  40.        (try_begin),
  41.           (ge, ":target_agent_no", 0),
  42.           (call_script, "script_agent_ai_battle_mode", ":target_agent_no"),#战斗模式分析
  43.           (assign, ":target_battle_mode", reg1),
  44.           (agent_get_position, pos2, ":target_agent_no"),
  45.           (get_distance_between_positions_in_meters, ":distance_no", pos1, pos2),#距离
  46.        (try_end),


  47. #AI行为处理
  48. #使用权重进行分析,每一种状态都会影响特定行为的权重,最后执行权重更高的行为。权重和状态的关系另外见表。
  49. #—————————————————————————————————分析—————————————————————————————————
  50.        (assign, ":action_observe", 1000),#观察
  51.        (assign, ":action_sprint", 1000),#冲刺
  52.        (call_script, "script_agent_ai_weight_input", 6, 1000, 1000, 1000, 1000, 1000, 1000),#slot0野盲击,slot1旋刃斩,slot2血星冲击,slot3赤潮战号,slot4血涌战号,slot5血钢战吼

  53.        (try_begin),
  54.        (eq, ":agent_battle_mode", ai_berserker),#双手
  55.           (val_sub, ":action_observe", 20),
  56.           (val_add, ":action_sprint", 60),
  57.        (else_try),
  58.           (eq, ":agent_battle_mode", ai_archer),#步射
  59.           (val_add, ":action_observe", 80),
  60.           (val_sub, ":action_sprint", 10),
  61.           (call_script, "script_agent_ai_weight_input", 6, -1000, -1000, -1000, 70, 70, 70),
  62.        (try_end),

  63.        (try_begin),
  64.           (agent_get_ammo, ":cur_ammo", "$mission_boss_agent", 0),#弹药量
  65.           (ge, ":cur_ammo", 3),
  66.           (val_add, ":action_observe", 10),
  67.           (val_sub, ":action_sprint", 10),
  68.        (try_end),

  69.        (call_script, "script_get_state_count", "$mission_boss_agent", "itm_state_blood_burst"),#血潮汹涌
  70.        (assign, ":bloodburst_count", reg1),
  71.        (try_begin),
  72.           (lt, ":bloodburst_count", 2),
  73.           (call_script, "script_agent_ai_weight_input", 6, 0, 0, -1000, 60, -10, -40),
  74.        (else_try),
  75.           (is_between, ":bloodburst_count", 2, 5),
  76.           (call_script, "script_agent_ai_weight_input", 6, 0, 0, 20, 10, 10, 10),
  77.        (else_try),
  78.           (ge, ":bloodburst_count", 5),
  79.           (call_script, "script_agent_ai_weight_input", 6, -10, -10, 50, -1000, 70, 50),
  80.        (try_end),

  81.        (call_script, "script_get_state_timer", "$mission_boss_agent", "itm_state_war_anger"),#血脉偾张
  82.        (try_begin),
  83.           (gt, reg1, 2),#还剩两秒以上
  84.           (call_script, "script_agent_ai_weight_input", 6, 0, 0, 0, 0, 0, -1000),
  85.        (try_end),

  86.        (try_begin),
  87.           (lt, ":distance_no", 2),
  88.           (val_sub, ":action_observe", 40),
  89.           (call_script, "script_agent_ai_weight_input", 6, 100, 120, 0, -50, -80, -1000),
  90.        (else_try),
  91.           (lt, ":distance_no", 4),
  92.           (call_script, "script_agent_ai_weight_input", 6, 120, 100, 30, 0, 30, 20),
  93.        (else_try),
  94.           (is_between, ":distance_no", 4, 6),
  95.           (call_script, "script_agent_ai_weight_input", 6, -10, -10, 0, 40, 40, 50),
  96.        (else_try),
  97.           (is_between, ":distance_no", 6, 10),
  98.           (val_add, ":action_observe", 10),
  99.           (call_script, "script_agent_ai_weight_input", 6, -1000, -1000, 20, -30, 40, 50),
  100.        (else_try),
  101.           (ge, ":distance_no", 11),
  102.           (val_add, ":action_sprint", 30),
  103.           (call_script, "script_agent_ai_weight_input", 6, -1000, -1000, 50, -60, 40, 50),
  104.        (try_end),

  105.        (try_begin),
  106.           (this_or_next|eq, ":target_battle_mode", ai_archer),
  107.           (eq, ":target_battle_mode", ai_ranger),
  108.           (val_sub, ":action_observe", 70),
  109.           (val_add, ":action_sprint", 80),
  110.           (call_script, "script_agent_ai_weight_input", 3, 0, 0, 70),
  111.        (try_end),

  112.        (try_begin),
  113.           (agent_slot_ge, "$mission_boss_agent", slot_agent_skill_timer, 1),#技能后摇
  114.           (call_script, "script_agent_ai_weight_input", 6, -1000, -1000, -1000, -1000, -1000, -1000),
  115.        (try_end),
  116. #—————————————————————————————————执行—————————————————————————————————
  117.        (try_begin),#下半身
  118.           (gt, ":action_observe", ":action_sprint"),#观察
  119.           (agent_set_speed_limit, "$mission_boss_agent", 5),
  120.        (else_try),
  121.           (agent_set_speed_limit, "$mission_boss_agent", 114514),
  122.        (try_end),

  123.        (call_script, "script_agent_ai_weight_output"),
  124.        (assign, ":chosen_action", reg1),
  125.        (try_begin),
  126.           (agent_slot_eq, "$mission_boss_agent", slot_ai_action_number, ":chosen_action"),#避免反复执行同一个行动
  127.           (assign, ":chosen_action", 0),
  128.        (try_end),
  129.        (try_begin),#上半身
  130.           (eq, ":chosen_action", 1),#重盲击
  131.           (call_script, "script_cf_close_combat_technique", "$mission_boss_agent", "itm_active_heavy_casual_attack"),
  132.        (else_try),
  133.           (eq, ":chosen_action", 2),#旋刃斩
  134.           (call_script, "script_cf_close_combat_technique", "$mission_boss_agent", "itm_active_sweep_away"),
  135.        (else_try),
  136.           (eq, ":chosen_action", 3),#血星冲击
  137.           (call_script, "script_cf_close_combat_technique", "$mission_boss_agent", "itm_active_blood_strike"),
  138.        (else_try),
  139.           (eq, ":chosen_action", 4),#赤潮战誓
  140.           (call_script, "script_sorcery_chant_technique", "$mission_boss_agent", "itm_active_warcy_red_tide"),
  141.        (else_try),
  142.           (eq, ":chosen_action", 5),#血涌战誓
  143.           (call_script, "script_sorcery_chant_technique", "$mission_boss_agent", "itm_active_warcy_bloodburst"),
  144.        (else_try),
  145.           (eq, ":chosen_action", 6),#血钢战吼
  146.           (call_script, "script_sorcery_chant_technique", "$mission_boss_agent", "itm_active_warcy_bloodsteel"),
  147.        (try_end),
  148.        (agent_set_slot, "$mission_boss_agent", slot_ai_action_number, ":chosen_action"),#记录本次执行的动作
  149.        (call_script, "script_agent_ai_weight_clear", 6),#清空

  150. (display_message, "@————————————————————————————————"),
  151.        ]),
复制代码
用到的脚本
  1. #分析当前装备模式
  2. #剑盾1、枪兵2、双手3、步射4、混战骑5、枪骑6、游骑7,标签定义在header_mission_template里。
  3. #输入对象agent,返回装备模式序号,返回后储存进slot_ai_battle_mode
  4.   ("agent_ai_battle_mode", [
  5.       (store_script_param_1, ":agent_no"),

  6.       (assign, ":battle_mode_no", 0),
  7.       (agent_get_wielded_item, ":weapon_no_1", ":agent_no", 0),#右手
  8.       (agent_get_wielded_item, ":weapon_no_2", ":agent_no", 1),#左手
  9.       (agent_get_horse, ":horse_no", ":agent_no"),
  10.       (try_begin),
  11.          (ge, ":horse_no", 0),#骑马
  12.          (gt, ":weapon_no_1", 0),
  13.          (item_get_type, ":type_no", ":weapon_no_1"),
  14.          (this_or_next|eq, ":type_no", itp_type_bow),#远程
  15.          (this_or_next|eq, ":type_no", itp_type_crossbow),
  16.          (this_or_next|eq, ":type_no", itp_type_thrown),
  17.          (this_or_next|eq, ":type_no", itp_type_pistol),
  18.          (eq, ":type_no", itp_type_musket),
  19.          (assign, ":battle_mode_no", ai_ranger),        #游骑兵
  20.       (else_try),
  21.          (ge, ":horse_no", 0),#骑马
  22.          (gt, ":weapon_no_1", 0),
  23.          (item_get_type, ":type_no", ":weapon_no_1"),
  24.          (this_or_next|eq, ":type_no", itp_type_polearm),#长杆
  25.          (item_has_property, ":weapon_no_1", itp_couchable),#骑枪冲锋
  26.          (assign, ":battle_mode_no", ai_lancer),        #枪骑兵
  27.       (else_try),
  28.          (ge, ":horse_no", 0),#骑马
  29.          (gt, ":weapon_no_1", 0),
  30.          (assign, ":battle_mode_no", ai_cavalry),        #混战骑兵
  31.      (else_try),
  32.          (lt, ":horse_no", 0),#步行
  33.          (gt, ":weapon_no_1", 0),
  34.          (item_get_type, ":type_no", ":weapon_no_1"),
  35.          (this_or_next|eq, ":type_no", itp_type_bow),#远程
  36.          (this_or_next|eq, ":type_no", itp_type_crossbow),
  37.          (this_or_next|eq, ":type_no", itp_type_thrown),
  38.          (this_or_next|eq, ":type_no", itp_type_pistol),
  39.          (eq, ":type_no", itp_type_musket),
  40.          (assign, ":battle_mode_no", ai_archer),        #步射手
  41.      (else_try),
  42.          (lt, ":horse_no", 0),#步行
  43.          (gt, ":weapon_no_1", 0),
  44.          (item_get_type, ":type_no", ":weapon_no_1"),
  45.          (neg|eq, ":type_no", itp_type_bow),#近战
  46.          (neg|eq, ":type_no", itp_type_crossbow),
  47.          (neg|eq, ":type_no", itp_type_thrown),
  48.          (neg|eq, ":type_no", itp_type_pistol),
  49.          (neg|eq, ":type_no", itp_type_musket),
  50.          (le, ":weapon_no_2", 0),#不带盾
  51.          (assign, ":battle_mode_no", ai_berserker),        #双手豪杰
  52.      (else_try),
  53.          (lt, ":horse_no", 0),#步行
  54.          (gt, ":weapon_no_1", 0),
  55.          (item_get_type, ":type_no", ":weapon_no_1"),
  56.          (eq, ":type_no", itp_type_polearm),#长杆
  57.          (gt, ":weapon_no_2", 0),#带盾
  58.          (assign, ":battle_mode_no", ai_pikeman),        #长矛兵
  59.      (else_try),
  60.          (lt, ":horse_no", 0),#步行
  61.          (gt, ":weapon_no_2", 0),#带盾
  62.          (gt, ":weapon_no_1", 0),
  63.          (item_get_type, ":type_no", ":weapon_no_1"),
  64.          (this_or_next|eq, ":type_no", itp_type_one_handed_wpn),#单手武器
  65.          (eq, ":type_no", itp_type_two_handed_wpn),#单双手武器
  66.          (assign, ":battle_mode_no", ai_saber),        #剑盾兵
  67.      (try_end),
  68.      (assign, reg1, ":battle_mode_no"),
  69.     ]),

  70. #录入权重,将其储存进trp_temp_array_ai的slot里,便于统计与调用
  71. #输入数值,加权为正,减权为负。可以不填。
  72. #param输入录入数据的数量
  73.   ("agent_ai_weight_input", [
  74.       (store_script_param, ":total_num", 1),#录入数据的数量
  75.       (try_for_range, ":slot_no", 0, ":total_num"),
  76.          (store_add, ":param_no", ":slot_no", 2),
  77.          (store_script_param, ":cur_weight", ":param_no"),
  78.          (neq, ":cur_weight", 0),
  79.          (troop_get_slot, ":weight_count", "trp_temp_array_ai", ":slot_no"),
  80.          (val_add, ":weight_count", ":cur_weight"),
  81.          (troop_set_slot, "trp_temp_array_ai", ":slot_no", ":weight_count"),
  82.       (try_end),
  83.     ]),

  84. #获取权重最高的一项,返回序号
  85. #权重最高的一项必须大于500才能执行,否则认定为所有项目都不应执行,不下指令,由原有AI自行普通攻击
  86.   ("agent_ai_weight_output", [
  87.       (assign, ":weight_range", 500),
  88.       (assign, ":chosen_action", 0),
  89.       (try_for_range, ":slot_no", 0, 10),
  90.          (troop_get_slot, ":weight_count", "trp_temp_array_ai", ":slot_no"),
  91.          (gt, ":weight_count", ":weight_range"),
  92.          (assign, ":weight_range", ":weight_count"),
  93.          (assign, ":chosen_action", ":slot_no"),
  94.          (val_add, ":chosen_action", 1),
  95.       (try_end),
  96.       (assign, reg1, ":chosen_action"),
  97.     ]),

  98. #清空权重
  99.   ("agent_ai_weight_clear", [
  100.       (store_script_param, ":total_num", 1),#录入数据的数量
  101.       (try_for_range, ":slot_no", 0, ":total_num"),
  102.          (troop_set_slot, "trp_temp_array_ai", ":slot_no", 0),
  103.       (try_end),
  104.     ]),
复制代码


这个系统的核心思想就是先把波士的可能行动都列出来,再把需要读取的条件都写一遍,像附图那样列一个excel,然后依次填入对应的权重。如果该条件促进该行动就加,反之就减,如果必不能做那就-1000(比如拿着远程不能近战攻击)。思路还是非常简单明了的。


不过,目前这个系统有个最大的问题是,会闪退。挺没道理的,我踏马连try for agent都省了,一共就两个人,模型也就是最朴素的那种,也没什么特别华丽的特效,怎么会闪退呢?怎么能给我闪退呢?请大佬们啃啃这个代码有没有什么问题?想当小白鼠的也可以自己用用看看,会不会出现同样的情况。

波士行为权重.png
岩雷狂战士.jpg

评分

参与人数 1第纳尔 +11 互助 +2 魅力 +10 收起 理由
幼稚园殺手 + 11 + 2 + 10 您的帖子很有价值!

查看全部评分

31

主题

209

回帖

187

积分

见习骑士

Rank: 3

UID
2462463
第纳尔
1582
精华
0
互助
23
荣誉
0
贡献
0
魅力
83
注册时间
2015-3-3
鲜花(57) 鸡蛋(0)
发表于 2024-8-8 09:13:32 | 显示全部楼层
沙发!!!!

1

主题

9

回帖

3

积分

平民

Rank: 1

UID
3683912
第纳尔
5
精华
0
互助
0
荣誉
0
贡献
0
魅力
0
注册时间
2024-8-2
鲜花(1) 鸡蛋(0)
发表于 2024-8-8 09:17:31 来自手机 | 显示全部楼层
支持666666来自: Android客户端

13

主题

81

回帖

28

积分

随仆

Rank: 1

UID
1510093
第纳尔
526
精华
0
互助
0
荣誉
0
贡献
0
魅力
0
注册时间
2013-8-28
鲜花(0) 鸡蛋(0)
发表于 2024-8-29 09:17:11 | 显示全部楼层
看不懂看不懂
您需要登录后才可以回帖 登录 | 注册(Register!)

本版积分规则

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

GMT+8, 2024-11-19 08:33 , Processed in 0.141910 second(s), 30 queries , Gzip On, MemCached On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

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