翔鹰帝国网|帝国时代论坛|帝国时代系列|神话时代
 找回密码
 注册翔鹰会员(昵称)
搜索
查看: 1215|回复: 5

[教程] [UP1.5] AI体系第一弹:搜索·筛选·指派体系及DUC应用 (上)

[复制链接]

183

主题

9

精华

2万

积分

教皇

耕战
3325
鹰币
15240
天龙币
0
回帖
1200

翔鹰建站十周年纪念章

附庸关系3
 楼主| 发表于 2020-8-28 02:03:26 | 显示全部楼层 |阅读模式

前排提示:UserPatch 1.5 的AI脚本体系同时适用于UP1.5、WK、DE。



导语
UserPatch 1.5的AI是成体系的,有几个比较丰富的体系。如搜索·筛选·指派(含DUC)体系、目标&焦点玩家体系、点体系、计算体系、控制建造系统、sn策略值体系、军事经济运营体系……

今天我先来聊聊搜索·筛选·指派体系。这个体系允许AI寻找单位/建筑,并对他们发出特定的命令,就像人类玩家点选控制单位一样,甚至可以实现比人类还变态的微操、拉扯、多线操作。



首先,什么是“搜索·筛选·指派”?

不妨先从我们人类玩家的操作来思考——我们人类玩家是如何控制单位行动的呢?
  • 第1步:首先在地图上以某种条件来寻找己方的单位。比如:“空闲的村民”“距离敌人最近的部队”“残血士兵”“闲置的建筑”。
  • 第2步:如果是一次性框选一大片单位,就可能需要进行筛选。比如:“去掉近战,只控制远程部队”“去掉士兵,只控制村民”。
  • 第3步:然后要寻找行动目标。可以是“找最近的敌军”“找敌方城堡”“找敌方侧翼点”“找野外的黄金”“找需要保护的己方建筑”
  • 第4步:有必要的话,还得再对行动目标进行筛选。
  • 第5步:最后指派框选的单位/建筑去攻击目标、移动到目的地、训练单位之类。


而AI的搜索·筛选·指派体系,或者说DUC(直接单位控制),也大概是这么做的:
  • 第1步:以一定的条件找己方单位。不过AI没法像人类那样用鼠标框选一片,而是遍历全图单位,把满足条件的单位逐个记录到一个 [搜索结果列表] 里备用。
  • 第2步:这样找到的单位可能东一个西一个,于是我们得再筛选剔除一下,留下真正需要的单位。比如“剔除距离敌方超过30格的单位”。
  • 第3步:然后要寻找行动目标。(同第1步)
  • 第4步:有必要的话,还得再对行动目标进行筛选。(同第2步)
  • 第5步:最后指派“框选*的单位/建筑去攻击目标、移动到目的地、训练单位之类。
    *注意:虽然AI没有“框选”这种说法,但为了方便理解,我们不妨把 [搜索结果列表里的己方单位] 视为 [被框选的单位]。接受这一点,对接下来的学习会很有帮助!)




搜索·筛选·指派是成体系的,它包含很多语句,我们不妨一步一步来,先从最简单的实例开始。

实例1——最简单的DUC效果
假设AI玩家P2拥有了一个步弓手,远处有一个玩家P1(也就是人类玩家)的敌方村民,现在我们要让步弓手去攻击村民,我们要怎么做呢?

(defconst action-default 0)     ; 常数。代表默认的指派行动:效果相当于右键点击目标单位或目标点地面。

(defrule
    ; 姑且先给一个恒成立的条件
    (true)
=>
    ; 搜索前例行清空搜索结果列表、搜索索引和搜索筛选。(什么是结果列表和索引我们稍后再解释)
    (up-full-reset-search)
    ; 找1个己方的步弓手(archer, 单位ID为4),把其地图ID储存在本地结果列表里。
    (up-find-local c: archer c: 1)
    ; 搜索远程单位前,需要先设置焦点玩家,这里暂且设为了玩家1
    (set-strategic-number sn-focus-player-number 1)
    ; 找1个焦点玩家的村民 (904表示种属#4,村民都是种属#4的)。
    (up-find-remote c: 904 c: 1)
    ; 指派本地结果里的己方步弓手,右键(action-default)远程结果里的敌方村民。
    ;(本地结果、远程结果稍后解释。0、-1也先不管)
    (up-target-objects 0 action-default -1 -1)
)


于是,本来会去射哨站的P2步弓手会径直去攻击P1的村民。


这样,一个最简单的DUC效果就做出来了,是不是很简单呢!

现在我们来解释一下上面的新词汇——
焦点玩家你可以理解为“注视/观察XX玩家”,是通过sn-focus-player-number设定的玩家编号,可以是1~8。up-find-remote语句会只搜索焦点玩家的单位。
单位ID在帝国内置数据库(.dat)里,每种单位都有独特的单位ID,步弓手为4,弩手为24,而AI脚本系统给一些常用的单位预设了单位代号,如步弓手为archer,弩手为crossbowman。二者在AI里是等效的。
地图ID每个存在在地图上的单位都分配了唯一的地图ID。第一个出现的单位为0,第二个是1,以此类推。AI搜索时,会把满足条件的单位的地图ID逐个罗列到本地/远程结果列表里。
本地搜索本地搜索只能对AI玩家自己进行。
远程搜索远程搜索则可以对任何一个玩家进行(由焦点玩家决定)。
搜索结果(列表)AI会把地图上满足条件的单位的地图ID,逐个储存到某个内部数据里,我们称之为搜索结果的列表。
本地结果(列表)储存本地搜索结果的列表,容量240个。位于这个结果列表里的单位,是通过up-target-objects进行操控的单位(如上面的P2步弓手。这也可以理解为被“框选”的单位)。
远程结果(列表)储存远程搜索结果的列表,容量40个。位于这个结果列表里的单位,是作为up-target-objects行动命令的目标对象(如上面的P1村民)。
搜索索引每个单位都有一个特定的索引值,AI会从0或者上次结束处开始搜索……啊,这个可能有点抽象,而且目前也用不上,在接下来的系列中我们慢慢讲。




实例2——检验搜索结果数量
有时我们会遇到这种情况:让AI搜索单位,但几轮下来单位没有行动。
这大概率是因为没有找到单位。UP-AI体系提供了获取搜索结果数量、并报告出来的语句,利用它们我们就可以实时掌握搜索的情况。
而且,我们还可以把“找到了单位/N个单位”作为动作的条件,比如下面这段代码——

(defconst action-default 0)

(defconst gl-local-total 50)    ; 变量。储存 当前本地搜索结果总数。变量ID需大于40,下同。
(defconst gl-local-last 51)     ; 变量。储存 最近一次本地搜索结果新增数量
(defconst gl-remote-total 52)   ; 变量。储存 当前远程搜索结果总数
(defconst gl-remote-last 53)    ; 变量。储存 最近一次远程搜索结果新增数量

(defrule
    (true)
=>
    ; 下面4条与实例1相同。尝试做本地和远程搜索。
    (up-full-reset-search)
    (up-find-local c: archer c: 1)
    (set-strategic-number sn-focus-player-number 1)
    (up-find-remote c: 904 c: 1)
    ; 将搜索状态数据依次存储于以gl-local-total为首的连续4个变量中。
    ;   当前本地搜索结果总数 → gl-local-total
    ;   最近一次本地搜索结果新增数量 →gl-local-last(“最近一次”就是在up-get-search-state之前的那次本地搜索。由于我们每次搜索前都用up-full-reset-search清空了搜索结果,所以这与[当前本地搜索结果总数]总是相等的)
    ;   当前远程搜索结果总数 → gl-remote-total
    ;   最近一次远程搜索结果新增数量 →gl-remote-last(“最近一次”就是在up-get-search-state之前的那次远程搜索。同理,此数值与[当前远程搜索结果总数]总是相等的)
    (up-get-search-state gl-local-total)
    ; 将本地和远程结果数量报告给所有玩家。(实战中可以用up-chat-data-to-self只发给AI自己)
    (up-chat-data-to-all "本地结果当前 %d 个" g: gl-local-total)
    (up-chat-data-to-all "远程结果当前 %d 个" g: gl-remote-total)
)
(defrule
    ; 比较数据。仅当本地和远程都找到单位时(变量>0),才下达攻击指令。
    (up-compare-goal gl-local-total c:> 0)
    (up-compare-goal gl-remote-total c:> 0)
=>
    (up-target-objects 0 action-default -1 -1)
    (chat-to-all "已找到敌我单位,攻击!")
)


如图,由于P2的视野中没有出现村民,而搜索敌人时必须有视野,因此P2没有找到任何P1的村民,于是攻击指令并没有下达(没有出现“已找到敌我单位,攻击!”的聊天)

而有视野时,AI就能正常搜索到P1的村民,并指派步弓手去攻击了。


扩展阅读 - 新出现语句详解:



【注:接下来的实例会出现很多新的语句,篇幅有限,我没法逐一说明。如果想弄清楚各个语句的详细作用,推荐去查阅 UserPatch 1.5 脚本编写参考  和  帝国时代II征服者 官方AI参考教程中文版



实例3——筛选、排序与剔除

1、筛选。
up-find-*语句是默认在全图范围内搜索的,通常情况下,你搜索到的单位会东一个西一个,而且种类也不尽相同;
如果你想只在地图中心附近搜索敌人的经济建筑,应该如何做呢?

up-filter-*系列语句就是用来添加筛选条件的。设置好若干个筛选条件后,再进行up-find-*搜索,就可以只搜索满足条件的单位了。

示例:
; 载入UserPatchConst.per,里面已经定义好了大部分常数,这样我们就不用手动定义常数了。
; 这个UserPatchConst.per应该存在于你当前AI的.per文件的相同目录里,否则会报错。
; 如果没有,请到这里下载→ UP1.5 AI常数清单 UserPatchConst.per
(load "UserPatchConst")

(defconst gl-local-total 50)    ; 变量。储存 当前本地搜索结果总数
(defconst gl-local-last 51)     ; 变量。储存 最近一次本地搜索结果新增数量
(defconst gl-remote-total 52)   ; 变量。储存 当前远程搜索结果总数
(defconst gl-remote-last 53)    ; 变量。储存 最近一次远程搜索结果新增数量

(defconst point-center-x 100)   ; 变量。储存 地图中心X坐标。变量ID需大于40,下同。
(defconst point-center-y 101)   ; 变量。储存 地图中心Y坐标

(defrule
    (true)
=>
    (up-full-reset-search)
    (up-find-local c: archer c: 80)
    (set-strategic-number sn-focus-player-number 1)
    ; 获取地图中心坐标,储存到以point-center-x为首的连续两个变量中(即100和101号变量)
    (up-get-point position-center point-center-x)
    ; 设置目标点(target-point)为地图中心坐标。(只需给X坐标即可,语句会自动读取下一ID的变量值作为Y坐标)
    (up-set-target-point point-center-x)
    ; 设置筛选条件 - 应在离目标点0~10格的范围内。
    (up-filter-distance c: 0 c: 10)
    ; 设置筛选条件 - 应具有[经济建筑]的命令编号(亦即必须为经济建筑)。
    (up-filter-include cmdid-civilian-building -1 -1 -1)
    ; 远程搜索。-1表示忽略[单位ID]这个参数。毕竟我们要找所有经济建筑嘛。
    (up-find-remote c: -1 c: 40)
    ; 获取搜索计数,并报告。
    (up-get-search-state gl-local-total)
    (up-chat-data-to-all "本地结果当前 %d 个" g: gl-local-total)
    (up-chat-data-to-all "远程结果当前 %d 个" g: gl-remote-total)
)
(defrule
    (up-compare-goal gl-local-total c:> 0)
    (up-compare-goal gl-remote-total c:> 0)
=>
    (up-target-objects 0 action-default -1 -1)
    (chat-to-all "已找到敌我单位,攻击!")
)


这样,在地图中心10格范围内的P1经济建筑就会被搜索到,而哨站、垛墙、兵营属于军事建筑,所以不会被搜索。

另外,你应该还发现了一个有趣的现象,15个步弓手分成了3、4、4、4人,分别去攻击四个经济建筑。所以说,up-target-objects是会把 [本地结果中的单位] 自动平均分配给 [远程结果中的单位] 的。



2、排序。
实战中我们会遇到这种情况:
敌人的长枪兵、弩手在冲车和雄鹰战士的掩护下冲锋过来,而AI方有一座城堡和若干防御塔。
城堡和箭塔会默认优先攻击距离最近的冲车、雄鹰战士,而对脆弱的长枪、弩手没有任何杀伤。
我们得让AI手动控制城堡和箭塔,优先攻击 [远程护甲] 较低的单位。

换而言之,我们需要搜索城堡附近的敌人,然后进行排序,远程护甲低的靠前,再利用平均分配的特性来攻击
up-clean-search 就有依据物件数据来排序的功能:(另外还有去除重复结果的作用,不过目前用不到)


示例:
(为了方便观察,我把箭矢换成了火球,P1全部设为不还击姿态)
我的大致思路为:
找城堡和箭塔→设城堡为搜索中心(如果找到的话)→找城堡周围的敌军→以远程护甲排序敌军,护甲弱的放前面→指派城堡和箭塔攻击敌军

(load "UserPatchConst")

(defconst gl-local-total 50)    ; 变量。储存搜索计数,下同。
(defconst gl-local-last 51)     ; 变量。
(defconst gl-remote-total 52)   ; 变量。
(defconst gl-remote-last 53)    ; 变量。

(defconst point-castle-x 102)   ; 变量。储存 城堡X坐标。变量ID需大于40,下同。
(defconst point-castle-y 103)   ; 变量。储存 城堡Y坐标

(defrule
    (true)
=>
    (up-full-reset-search)
    ; 先找城堡,这样本地结果里的第一个单位就是城堡。
    (up-find-local c: castle c: 1)
    (up-find-local c: tower-class c: 10)
    ; 获取搜索计数。
    (up-get-search-state gl-local-total)
)
(defrule
    ; 本地搜索有结果时,才执行下面的代码。(否则up-set-target-object会定位到地图ID最靠前的单位)
    (up-compare-goal gl-local-total c:> 0)
=>
    ;——————获取城堡,并设为目标点——————
    ; 设置目标物件(target-object)为本地结果(search-local)里的首个单位(结果索引为0),亦即城堡。(稍后我会解释什么是索引)
    (up-set-target-object search-local c: 0)
    ; 获取目标物件(即城堡)的坐标,储存到point-castle-x和point-castle-y中。
    (up-get-point position-object point-castle-x)
    ; 设置目标点(target-point)为城堡坐标。
    (up-set-target-point point-castle-x)

    ;——————筛选,搜索敌人——————
    (set-strategic-number sn-focus-player-number 1)
    ; 设置筛选条件 - 应在离目标点(即城堡)0~8格的范围内。
    (up-filter-distance c: 0 c: 8)
    ; 设置筛选条件 - 应具有[军事单位]的命令编号(亦即必须为军事单位)。
    (up-filter-include cmdid-military -1 -1 -1)
    ; 远程搜索。
    (up-find-remote c: -1 c: 40)

    ;——————排序——————
    ; 对远程结果(search-remote),以远程护甲值升序排列(较小值排到前面)
    (up-clean-search search-remote object-data-pierce-armor search-order-asc)

    ; 获取搜索计数,并报告。
    (up-get-search-state gl-local-total)
    (up-chat-data-to-all "本地结果当前 %d 个" g: gl-local-total)
    (up-chat-data-to-all "远程结果当前 %d 个" g: gl-remote-total)
)
(defrule
    ; 本地、远程都找到单位时,才执行攻击。
    (up-compare-goal gl-local-total c:> 0)
    (up-compare-goal gl-remote-total c:> 0)
=>
    (up-target-objects 0 action-default -1 -1)
    (chat-to-all "已找到敌我单位,攻击!")
)

效果如图。城堡和箭塔并没有攻击距离最近的冲车和雄鹰战士,而是分别攻击着脆皮的敌人。(偶尔也会抽风去攻击冲车和鹰勇士)
而且,当有生力量全部被消灭后,城堡和箭塔还会继续去攻击冲车,因为我们并没有把冲车剔除掉。


现在,我来解释一下“(结果)索引”是什么:
      当我们搜索完一次后,搜索结果列表可能是这样的(见下表↓↓↓)
      第一个搜到的单位被记为0,第二个记为1,以此类推。
      如果不清空搜索结果列表,那么再次搜索时 (比如上面 搜完城堡后又搜索箭塔),新搜到的单位会从空索引开始追加。
      如果清空搜索结果列表 (比如AI下一轮遍历时,先up-full-reset-search了一次),那么再次搜索时,新搜到的单位当然又从索引0开始追加啦。

本地结果列表远程结果列表
索引地图ID索引地图ID
0560<无>
1571<无>
2892<无>
31353<无>
4<无>4<无>

      而up-set-target-object是以索引值来定位搜索结果的,(up-set-target-object search-local c: 0) 就是定位到了本地结果列表中的索引0,也就是地图ID为56的城堡。



3、剔除。
大部分情况下,攻击残血单位比攻击满血单位的效益更高,因为敌人只要还活着就能继续输出,尽快减少敌人数量我方受到的伤害就会减少。所以我们有时能看到,职业选手在射手对射时,会快速逐个点击、查看敌人的血量,然后控制射手集火残血敌人。
那么我们的AI要如何实现这个操作呢?

示例:
我的思路:
找己方射手→找敌方射手→对找到的敌人排序: HP低的靠前→按索引剔除敌军: 只保留前几个→指派射手集火这几个残血敌人。

(load "UserPatchConst")

(defconst gl-local-total 50)    ; 变量。储存搜索计数,下同。
(defconst gl-local-last 51)     ; 变量。
(defconst gl-remote-total 52)   ; 变量。
(defconst gl-remote-last 53)    ; 变量。

(defrule
    (true)
=>
    ; 激活并初始化10号定时器。后面会用到
    (enable-timer 10 0)
    (disable-self)
)

(defrule
    (true)
=>
    (up-full-reset-search)
    ; archery-class包含了步弓手、弩手、劲弩手、(精锐)掷矛手等等。
    (up-find-local c: archery-class c: 40)
    ; 剔除掉本地结果中,下次攻击时间 > 1300ms的己方射手,避免因切换目标导致射击中止。
    ;(攻击抬手瞬间,下次攻击时间 会重新从攻击间隔倒数。大部分射手能在抬手700ms内射出箭矢。)
    (up-remove-objects search-local object-data-next-attack c:> 1300)
)
(defrule
    (true)
=>
    (set-strategic-number sn-focus-player-number 1)
    (up-find-remote c: archery-class c: 40)
    ; 获取搜索计数。
    (up-get-search-state gl-local-total)

    ;——————排序——————
    ; 对远程结果,以剩余生命值升序排列(较小值排到前面)
    (up-clean-search search-remote object-data-hitpoints search-order-asc)

    ;——————剔除——————
    (up-modify-goal gl-local-total c:/ 5)
    ; 对远程结果,剔除索引值大于 (本地结果 / 5) 的结果,只保留前面几个血量最低的。
    ; 如果 (本地结果 / 5) 为0,就说明我方射手不足5个,那就会集火于索引为0的单个敌人。
    (up-remove-objects search-remote object-data-index g:> gl-local-total)

    ; 获取剔除后的搜索计数,并报告出来。
    (up-get-search-state gl-local-total)
    (up-chat-data-to-all "本地结果当前 %d 个" g: gl-local-total)
    (up-chat-data-to-all "远程结果当前 %d 个" g: gl-remote-total)
)
(defrule
    ; 本地、远程都找到单位时,才执行攻击。
    (up-compare-goal gl-local-total c:> 0)
    (up-compare-goal gl-remote-total c:> 0)
    ; 2秒执行一次,否则过快点击右键会造成抽搐,使射手根本射不出箭
    (timer-triggered 10)
=>
    (up-target-objects 0 action-default -1 -1)
    (chat-to-all "已找到敌我单位,攻击!")
    (enable-timer 10 2)
)

效果如图。
      P1蓝色为自由寻敌,AI红色则使用了上述代码。
      AI会控制不在抬手状态的射手,去集火1/3~1/5数量的低血量敌人。(AI的除法是四舍五入的,还有索引0,这些会导致被集火敌人数量稍多)。
      而自由寻敌的蓝方就比较随缘了,经常能遇到明明有AI残血单位却不补刀,任其继续输出的情况。
战果:
      18vs18弩手,城堡时代,升级指环科技,胜利场数 [优先补刀]10 : 4[自由寻敌],而且胜局下AI基本都能剩2~5个。




后记
物件数据有哪些?可以以距离远近、速度之类来做排序条件吗?
搜索排序有哪些?可以倒序或随机排序吗?
种属有哪些?有没有步兵和骑兵对应的种属?
指派行动有哪些?我想巡逻、驻扎怎么办?
……
你需要的UP1.5 AI参数都可以在这里查到详细的解释:UserPatch 1.5 脚本编写参考!接下来的整个UP1.5 AI体系教程,都需要不断翻阅这本参考,希望每位同学都能常备起来,多多探索其中的奥妙!
(PS:记得看“编者按”部分哦~)



下一期:搜索·筛选·指派体系及DUC应用 (中or下?)
      可能会讲的内容:up-target-point、搜索组的应用,自然资源搜索与状态搜索语句,搜索索引的用法。



本期作业:
光说不练,等于白看!来做点富有挑战性,但原理很简单的作业吧!

1、筛选练习。
查阅脚本编写参考,活用前5种up-filter-*语句(-status可选择不练),在复杂地图上准确搜索:距离地图中心5~10格、驻扎有2~5个单位、不是塔种属的单位/建筑。

(提示:城堡、城镇中心、冲车、可训练建筑、运输船都满足条件哦~)

敌方据点配置:
(注:搜索敌方需要提供有效视野,你可以在地图中心附近放一个AI的地图启示者或者哨站)


2、排序+剔除练习。
查阅脚本编写参考,找到你想要的物件数据,
①让AI的冲车去攻击地图中心附近的建筑,且应优先攻击威胁最大的;
②让AI的远程部队去优先攻击低远程护甲敌人;
③让AI的步兵优先攻击以己方冲车为目标的敌人;
④让AI的骑兵优先攻击敌人的远程部队。

(提示:这些都是可行的哦,而且只需要多轮搜索+排序+剔除,就可以实现)

AI部队配置:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册翔鹰会员(昵称)

x

评分

参与人数 2耕战 +300 鹰币 +10 收起 理由
Papermanmmj + 10 原创精华
cxt + 300 原创精华

查看全部评分

索引:
Userpatch 实用技术贴索引←点击进入
决定版精品贴大索引←点击进入

战役:
《 兔与豹》——柔弱奴隶公主  猛兽口中求生←点击进入
《敛由国的统一》←点击进入

殊途战役制作群 QQ: 616317226
翔鹰帝国Ⅱ:决定版交流群 QQ: 112822759
回复

使用道具 举报

117

主题

9

精华

9万

积分

教皇

Wolotine

耕战
17250
鹰币
546160
天龙币
0
回帖
1570

翔鹰建站十周年纪念章小评论家第十二届火箭筒杯最佳新人第十三届火箭筒杯亚军第十三届火箭筒杯亚军赌徒勋章第八届战鹰杯单人赛冠军

附庸关系11
发表于 2020-8-28 08:17:58 | 显示全部楼层
好!新桶又熬夜写AI了!
回复

使用道具 举报

11

主题

0

精华

164

积分

男爵

耕战
5
鹰币
30
天龙币
0
回帖
37
附庸关系0
发表于 2020-8-31 08:42:44 | 显示全部楼层
本帖最后由 仰望坡大刀 于 2020-8-31 08:54 编辑

集火攻击血少AI容易造成伤害溢出,如果对面全是满血,集火攻击还好,如果是半血或残血,不如巡逻过去。而且如果对面拉残血部队后撤,就容易造成集火攻击部队处于危险之中,不如原地坚守输出。
回复

使用道具 举报

183

主题

9

精华

2万

积分

教皇

耕战
3325
鹰币
15240
天龙币
0
回帖
1200

翔鹰建站十周年纪念章

附庸关系3
 楼主| 发表于 2020-9-1 01:44:49 | 显示全部楼层
仰望坡大刀 发表于 2020-8-31 08:42
集火攻击血少AI容易造成伤害溢出,如果对面全是满血,集火攻击还好,如果是半血或残血,不如巡逻过去。而且 ...

嗯,可以理解。
这几个只是教学示例,真正用于实战还需优化或另选思路。

在发布之前其实我也做了一些额外的测试。
1、弩手16vs16下的伤害溢出,会有一些,不过并不算多,大概溢出0~10点。一方面是弩手的5点伤害不算高;另一方面是我采用了动态的集火数量,一般都是3:1 或 2:1的配额;还有一方面是up-target-objects的平均分配特性,对残血敌人的伤害较平均 (最残血的敌人所受攻击通常更多,这确实是个问题,不过也很好解决,再排序一次就行)。

2、用巡逻来索敌有很多问题。首先就是开始巡逻到重新索敌会有响应时间,大概1~2游戏秒,这期间AI部队是没有任何输出的纯挨打形态;其次是可能会受到建筑或其他单位的吸引嘲讽;再有是全队统一巡逻会中断拉弓/挥剑的动作,造成不必要的伤害量损失。

3、残血部队后撤我简单尝试了一下,在弩手对射期间,后撤的残血基本都会被流矢补杀,刚转身就死掉,成功撤离前线的比例比较小(1/5)。不知道发展AI中是如何设计的。

4、如果遇上对面的残血部队后撤且成功远离,这个示例确实是会追杀过去的。若要完善,可以考虑加一道逃兵验证,比如把行动编号为移动的单位从搜索结果除名(或其他更好的判定条件),并有关部队的攻击目标变动到候选目标。
索引:
Userpatch 实用技术贴索引←点击进入
决定版精品贴大索引←点击进入

战役:
《 兔与豹》——柔弱奴隶公主  猛兽口中求生←点击进入
《敛由国的统一》←点击进入

殊途战役制作群 QQ: 616317226
翔鹰帝国Ⅱ:决定版交流群 QQ: 112822759
回复

使用道具 举报

11

主题

0

精华

164

积分

男爵

耕战
5
鹰币
30
天龙币
0
回帖
37
附庸关系0
发表于 2020-9-1 08:47:41 | 显示全部楼层
另外,貌似DUC搜索不到wk新加的单位,如百夫长、投石手、王八弩,只能搜索征服者固有的单位。
回复

使用道具 举报

11

主题

0

精华

164

积分

男爵

耕战
5
鹰币
30
天龙币
0
回帖
37
附庸关系0
发表于 2020-9-1 08:52:57 | 显示全部楼层
我自己改的是这样的,在7格射程内先打低盾低血量,在慢慢升级高盾。但是也感觉不完美,因为每个射手的射程不同,最好能设置在期射程之内,7只是保险都能够到。
  1. ; ============================================================
  2. ;-------------Destroy units with ranged-unit-class-----------
  3. ; ============================================================
  4. (defrule
  5.         (unit-type-count ranged-unit-class > 0)
  6.     (stance-toward focus-player enemy)
  7. =>        (up-full-reset-search)
  8.         (up-find-remote c: -1 c: 40)
  9.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  10.     (up-remove-objects search-remote object-data-pierce-armor > 3)
  11.         (up-remove-objects search-remote object-data-index > 0)
  12.         (up-set-target-object search-remote c: 0)
  13.         (up-get-search-state gl-local-total)
  14.         (up-get-point position-object other-point-x)
  15.         (up-set-target-point other-point-x)
  16.         (up-filter-distance c: -1 c: 7)
  17.         (set-goal split-duc-goal 64))
  18. (defrule
  19.         (goal split-duc-goal 64)
  20.         (unit-type-count ranged-unit-class > 0)
  21.         (up-find-local c: ranged-unit-class c: 1)
  22.         (up-compare-goal gl-remote-last > 0)
  23. =>        (up-set-target-point other-point-x)
  24.         (up-filter-distance c: -1 c: 7)
  25.         (up-find-local c: ranged-unit-class c: 5)
  26.         (up-target-objects 0 action-default -1 stance-stand-ground)
  27.         (chat-to-player my-player-number "Destroy 3d units with ranged-unit-class"))
  28. (defrule
  29.         (goal split-duc-goal 64)
  30.         (not (up-find-local c: ranged-unit-class c: 1))
  31.         (unit-type-count ranged-unit-class > 0)
  32.     (stance-toward focus-player enemy)
  33. =>        (up-full-reset-search)
  34.         (up-find-remote c: -1 c: 40)
  35.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  36.     (up-remove-objects search-remote object-data-pierce-armor > 4)
  37.         (up-remove-objects search-remote object-data-index > 0)
  38.         (up-set-target-object search-remote c: 0)
  39.         (up-get-search-state gl-local-total)
  40.         (up-get-point position-object other-point-x)
  41.         (up-set-target-point other-point-x)
  42.         (up-filter-distance c: -1 c: 7)
  43.         (set-goal split-duc-goal 74))
  44. (defrule
  45.         (goal split-duc-goal 64)
  46.         (up-compare-goal gl-remote-last == 0)
  47.         (unit-type-count ranged-unit-class > 0)
  48.     (stance-toward focus-player enemy)
  49. =>        (up-full-reset-search)
  50.         (up-find-remote c: -1 c: 40)
  51.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  52.     (up-remove-objects search-remote object-data-pierce-armor > 4)
  53.         (up-remove-objects search-remote object-data-index > 0)
  54.         (up-set-target-object search-remote c: 0)
  55.         (up-get-search-state gl-local-total)
  56.         (up-get-point position-object other-point-x)
  57.         (up-set-target-point other-point-x)
  58.         (up-filter-distance c: -1 c: 7)
  59.         (set-goal split-duc-goal 74))
  60. (defrule
  61.         (goal split-duc-goal 74)
  62.         (unit-type-count ranged-unit-class > 0)
  63.         (up-find-local c: ranged-unit-class c: 1)
  64.         (up-compare-goal gl-remote-last > 0)
  65. =>        (up-set-target-point other-point-x)
  66.         (up-filter-distance c: -1 c: 7)
  67.         (up-find-local c: ranged-unit-class c: 5)
  68.         (up-target-objects 0 action-default -1 stance-stand-ground)
  69.         (chat-to-player my-player-number "Destroy 4d units with ranged-unit-class"))
  70. (defrule
  71.         (goal split-duc-goal 74)
  72.         (not (up-find-local c: ranged-unit-class c: 1))
  73.         (unit-type-count ranged-unit-class > 0)
  74.     (stance-toward focus-player enemy)
  75. =>        (up-full-reset-search)
  76.         (up-find-remote c: -1 c: 40)
  77.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  78.     (up-remove-objects search-remote object-data-pierce-armor > 5)
  79.         (up-remove-objects search-remote object-data-index > 0)
  80.         (up-set-target-object search-remote c: 0)
  81.         (up-get-search-state gl-local-total)
  82.         (up-get-point position-object other-point-x)
  83.         (up-set-target-point other-point-x)
  84.         (up-filter-distance c: -1 c: 7)
  85.         (set-goal split-duc-goal 75))
  86. (defrule
  87.         (goal split-duc-goal 74)
  88.         (up-compare-goal gl-remote-last == 0)
  89.         (unit-type-count ranged-unit-class > 0)
  90.     (stance-toward focus-player enemy)
  91. =>        (up-full-reset-search)
  92.         (up-find-remote c: -1 c: 40)
  93.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  94.     (up-remove-objects search-remote object-data-pierce-armor > 5)
  95.         (up-remove-objects search-remote object-data-index > 0)
  96.         (up-set-target-object search-remote c: 0)
  97.         (up-get-search-state gl-local-total)
  98.         (up-get-point position-object other-point-x)
  99.         (up-set-target-point other-point-x)
  100.         (up-filter-distance c: -1 c: 7)
  101.         (set-goal split-duc-goal 75))
  102. (defrule
  103.         (goal split-duc-goal 75)
  104.         (unit-type-count ranged-unit-class > 0)
  105.         (up-find-local c: ranged-unit-class c: 1)
  106.         (up-compare-goal gl-remote-last > 0)
  107. =>        (up-set-target-point other-point-x)
  108.         (up-filter-distance c: -1 c: 7)
  109.         (up-find-local c: ranged-unit-class c: 5)
  110.         (up-target-objects 0 action-default -1 stance-stand-ground)
  111.         (chat-to-player my-player-number "Destroy 5d units with ranged-unit-class"))
  112. (defrule
  113.         (goal split-duc-goal 75)
  114.         (not (up-find-local c: ranged-unit-class c: 1))
  115.         (unit-type-count ranged-unit-class > 0)
  116.     (stance-toward focus-player enemy)
  117. =>        (up-full-reset-search)
  118.         (up-find-remote c: -1 c: 40)
  119.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  120.     (up-remove-objects search-remote object-data-pierce-armor > 6)
  121.         (up-remove-objects search-remote object-data-index > 0)
  122.         (up-set-target-object search-remote c: 0)
  123.         (up-get-search-state gl-local-total)
  124.         (up-get-point position-object other-point-x)
  125.         (up-set-target-point other-point-x)
  126.         (up-filter-distance c: -1 c: 7)
  127.         (set-goal split-duc-goal 68))
  128. (defrule
  129.         (goal split-duc-goal 75)
  130.         (up-compare-goal gl-remote-last == 0)
  131.         (unit-type-count ranged-unit-class > 0)
  132.     (stance-toward focus-player enemy)
  133. =>        (up-full-reset-search)
  134.         (up-find-remote c: -1 c: 40)
  135.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  136.     (up-remove-objects search-remote object-data-pierce-armor > 6)
  137.         (up-remove-objects search-remote object-data-index > 0)
  138.         (up-set-target-object search-remote c: 0)
  139.         (up-get-search-state gl-local-total)
  140.         (up-get-point position-object other-point-x)
  141.         (up-set-target-point other-point-x)
  142.         (up-filter-distance c: -1 c: 7)
  143.         (set-goal split-duc-goal 68))
  144. (defrule
  145.         (goal split-duc-goal 68)
  146.         (unit-type-count ranged-unit-class > 0)
  147.         (up-find-local c: ranged-unit-class c: 1)
  148.         (up-compare-goal gl-remote-last > 0)
  149. =>        (up-set-target-point other-point-x)
  150.         (up-filter-distance c: -1 c: 7)
  151.         (up-find-local c: ranged-unit-class c: 5)
  152.         (up-target-objects 0 action-default -1 stance-stand-ground)
  153.         (chat-to-player my-player-number "Destroy 6d units with ranged-unit-class"))
  154. (defrule
  155.         (goal split-duc-goal 68)
  156.         (not (up-find-local c: ranged-unit-class c: 1))
  157.         (unit-type-count ranged-unit-class > 0)
  158.     (stance-toward focus-player enemy)
  159. =>        (up-full-reset-search)
  160.         (up-find-remote c: -1 c: 40)
  161.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  162.     (up-remove-objects search-remote object-data-pierce-armor > 7)
  163.         (up-remove-objects search-remote object-data-index > 0)
  164.         (up-set-target-object search-remote c: 0)
  165.         (up-get-search-state gl-local-total)
  166.         (up-get-point position-object other-point-x)
  167.         (up-set-target-point other-point-x)
  168.         (up-filter-distance c: -1 c: 7)
  169.         (set-goal split-duc-goal 51))
  170. (defrule
  171.         (goal split-duc-goal 68)
  172.         (up-compare-goal gl-remote-last == 0)
  173.         (unit-type-count ranged-unit-class > 0)
  174.     (stance-toward focus-player enemy)
  175. =>        (up-full-reset-search)
  176.         (up-find-remote c: -1 c: 40)
  177.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  178.     (up-remove-objects search-remote object-data-pierce-armor > 7)
  179.         (up-remove-objects search-remote object-data-index > 0)
  180.         (up-set-target-object search-remote c: 0)
  181.         (up-get-search-state gl-local-total)
  182.         (up-get-point position-object other-point-x)
  183.         (up-set-target-point other-point-x)
  184.         (up-filter-distance c: -1 c: 7)
  185.         (set-goal split-duc-goal 51))
  186. (defrule
  187.         (goal split-duc-goal 51)
  188.         (unit-type-count ranged-unit-class > 0)
  189.         (up-find-local c: ranged-unit-class c: 1)
  190.         (up-compare-goal gl-remote-last > 0)
  191. =>        (up-set-target-point other-point-x)
  192.         (up-filter-distance c: -1 c: 7)
  193.         (up-find-local c: ranged-unit-class c: 5)
  194.         (up-target-objects 0 action-default -1 stance-stand-ground)
  195.         (chat-to-player my-player-number "Destroy 7d units with ranged-unit-class"))
  196. (defrule
  197.         (goal split-duc-goal 51)
  198.         (not (up-find-local c: ranged-unit-class c: 1))
  199.         (unit-type-count ranged-unit-class > 0)
  200.     (stance-toward focus-player enemy)
  201. =>        (up-full-reset-search)
  202.         (up-find-remote c: -1 c: 40)
  203.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  204.     (up-remove-objects search-remote object-data-pierce-armor > 8)
  205.         (up-remove-objects search-remote object-data-index > 0)
  206.         (up-set-target-object search-remote c: 0)
  207.         (up-get-search-state gl-local-total)
  208.         (up-get-point position-object other-point-x)
  209.         (up-set-target-point other-point-x)
  210.         (up-filter-distance c: -1 c: 7)
  211.         (set-goal split-duc-goal 52))
  212. (defrule
  213.         (goal split-duc-goal 51)
  214.         (up-compare-goal gl-remote-last == 0)
  215.         (unit-type-count ranged-unit-class > 0)
  216.     (stance-toward focus-player enemy)
  217. =>        (up-full-reset-search)
  218.         (up-find-remote c: -1 c: 40)
  219.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  220.     (up-remove-objects search-remote object-data-pierce-armor > 8)
  221.         (up-remove-objects search-remote object-data-index > 0)
  222.         (up-set-target-object search-remote c: 0)
  223.         (up-get-search-state gl-local-total)
  224.         (up-get-point position-object other-point-x)
  225.         (up-set-target-point other-point-x)
  226.         (up-filter-distance c: -1 c: 7)
  227.         (set-goal split-duc-goal 52))
  228. (defrule
  229.         (goal split-duc-goal 52)
  230.         (unit-type-count ranged-unit-class > 0)
  231.         (up-find-local c: ranged-unit-class c: 1)
  232.         (up-compare-goal gl-remote-last > 0)
  233. =>        (up-set-target-point other-point-x)
  234.         (up-filter-distance c: -1 c: 7)
  235.         (up-find-local c: ranged-unit-class c: 5)
  236.         (up-target-objects 0 action-default -1 stance-stand-ground)
  237.         (chat-to-player my-player-number "Destroy 8d units with ranged-unit-class"))
  238. (defrule
  239.         (goal split-duc-goal 52)
  240.         (not (up-find-local c: ranged-unit-class c: 1))
  241.         (unit-type-count ranged-unit-class > 0)
  242.     (stance-toward focus-player enemy)
  243. =>        (up-full-reset-search)
  244.         (up-find-remote c: -1 c: 40)
  245.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  246.     (up-remove-objects search-remote object-data-pierce-armor > 9)
  247.         (up-remove-objects search-remote object-data-index > 0)
  248.         (up-set-target-object search-remote c: 0)
  249.         (up-get-search-state gl-local-total)
  250.         (up-get-point position-object other-point-x)
  251.         (up-set-target-point other-point-x)
  252.         (up-filter-distance c: -1 c: 7)
  253.         (set-goal split-duc-goal 54))
  254. (defrule
  255.         (goal split-duc-goal 52)
  256.         (up-compare-goal gl-remote-last == 0)
  257.         (unit-type-count ranged-unit-class > 0)
  258.     (stance-toward focus-player enemy)
  259. =>        (up-full-reset-search)
  260.         (up-find-remote c: -1 c: 40)
  261.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  262.     (up-remove-objects search-remote object-data-pierce-armor > 9)
  263.         (up-remove-objects search-remote object-data-index > 0)
  264.         (up-set-target-object search-remote c: 0)
  265.         (up-get-search-state gl-local-total)
  266.         (up-get-point position-object other-point-x)
  267.         (up-set-target-point other-point-x)
  268.         (up-filter-distance c: -1 c: 7)
  269.         (set-goal split-duc-goal 54))
  270. (defrule
  271.         (goal split-duc-goal 54)
  272.         (unit-type-count ranged-unit-class > 0)
  273.         (up-find-local c: ranged-unit-class c: 1)
  274.         (up-compare-goal gl-remote-last > 0)
  275. =>        (up-set-target-point other-point-x)
  276.         (up-filter-distance c: -1 c: 7)
  277.         (up-find-local c: ranged-unit-class c: 5)
  278.         (up-target-objects 0 action-default -1 stance-stand-ground)
  279.         (chat-to-player my-player-number "Destroy 9d units with ranged-unit-class"))
  280. (defrule
  281.         (goal split-duc-goal 54)
  282.         (not (up-find-local c: ranged-unit-class c: 1))
  283.         (unit-type-count ranged-unit-class > 0)
  284.     (stance-toward focus-player enemy)
  285. =>        (up-full-reset-search)
  286.         (up-find-remote c: -1 c: 40)
  287.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  288.     (up-remove-objects search-remote object-data-pierce-armor > 10)
  289.         (up-remove-objects search-remote object-data-index > 0)
  290.         (up-set-target-object search-remote c: 0)
  291.         (up-get-search-state gl-local-total)
  292.         (up-get-point position-object other-point-x)
  293.         (up-set-target-point other-point-x)
  294.         (up-filter-distance c: -1 c: 7)
  295.         (set-goal split-duc-goal 72))
  296. (defrule
  297.         (goal split-duc-goal 54)
  298.         (up-compare-goal gl-remote-last == 0)
  299.         (unit-type-count ranged-unit-class > 0)
  300.     (stance-toward focus-player enemy)
  301. =>        (up-full-reset-search)
  302.         (up-find-remote c: -1 c: 40)
  303.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  304.     (up-remove-objects search-remote object-data-pierce-armor > 10)
  305.         (up-remove-objects search-remote object-data-index > 0)
  306.         (up-set-target-object search-remote c: 0)
  307.         (up-get-search-state gl-local-total)
  308.         (up-get-point position-object other-point-x)
  309.         (up-set-target-point other-point-x)
  310.         (up-filter-distance c: -1 c: 7)
  311.         (set-goal split-duc-goal 72))
  312. (defrule
  313.         (goal split-duc-goal 72)
  314.         (unit-type-count ranged-unit-class > 0)
  315.         (up-find-local c: ranged-unit-class c: 1)
  316.         (up-compare-goal gl-remote-last > 0)
  317. =>        (up-set-target-point other-point-x)
  318.         (up-filter-distance c: -1 c: 7)
  319.         (up-find-local c: ranged-unit-class c: 5)
  320.         (up-target-objects 0 action-default -1 stance-stand-ground)
  321.         (chat-to-player my-player-number "Destroy 10d units with ranged-unit-class"))
  322. (defrule
  323.         (goal split-duc-goal 72)
  324.         (not (up-find-local c: ranged-unit-class c: 1))
  325.         (unit-type-count ranged-unit-class > 0)
  326.     (stance-toward focus-player enemy)
  327. =>        (up-full-reset-search)
  328.         (up-find-remote c: -1 c: 40)
  329.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  330.         (up-remove-objects search-remote object-data-index > 0)
  331.         (up-set-target-object search-remote c: 0)
  332.         (up-get-search-state gl-local-total)
  333.         (up-get-point position-object other-point-x)
  334.         (up-set-target-point other-point-x)
  335.         (up-filter-distance c: -1 c: 7)
  336.         (set-goal split-duc-goal 73))
  337. (defrule
  338.         (goal split-duc-goal 72)
  339.         (up-compare-goal gl-remote-last == 0)
  340.         (unit-type-count ranged-unit-class > 0)
  341.     (stance-toward focus-player enemy)
  342. =>        (up-full-reset-search)
  343.         (up-find-remote c: -1 c: 40)
  344.         (up-clean-search search-remote object-data-hitpoints search-order-asc)
  345.         (up-remove-objects search-remote object-data-index > 0)
  346.         (up-set-target-object search-remote c: 0)
  347.         (up-get-search-state gl-local-total)
  348.         (up-get-point position-object other-point-x)
  349.         (up-set-target-point other-point-x)
  350.         (up-filter-distance c: -1 c: 7)
  351.         (set-goal split-duc-goal 73))
  352. (defrule
  353.         (goal split-duc-goal 73)
  354.         (unit-type-count ranged-unit-class > 0)
  355.         (up-find-local c: ranged-unit-class c: 1)
  356.         (up-compare-goal gl-remote-last > 0)
  357. =>        (up-set-target-point other-point-x)
  358.         (up-filter-distance c: -1 c: 7)
  359.         (up-find-local c: ranged-unit-class c: 5)
  360.         (up-target-objects 0 action-default -1 stance-stand-ground)
  361.         (chat-to-player my-player-number "Destroy any units with ranged-unit-class"))
  362. (defrule
  363.         (goal split-duc-goal 73)
  364. =>
  365.         (set-goal split-duc-goal -1)
  366.         (up-set-attack-stance ranged-unit-class c: stance-aggressive)
  367. )
复制代码
回复

使用道具 举报

本版积分规则

排行榜|小黑屋|翔鹰帝国

GMT+8, 2024-4-27 19:55 , Processed in 0.152725 second(s), 77 queries , File On.

Powered by Hawk Studio  QS Security Corp.® Licensed

Copyright © 2001-2023, Hawkaoe.net All Rights Reserved

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