newtonerdai 发表于 2020-5-28 07:21:08

[DE/UP1.5] 让AI来帮玩家1的单位编队(Shift+1~9)

本帖最后由 newtonerdai 于 2020-6-7 18:23 编辑

前言
UP1.5里有“停止单位:1~9”的扩展数字效果,用于给玩家1的单位自动编队,来做按下数字作为选项的效果。
比如《太宗传说》里的9键选择系统:
https://www.hawkaoe.net/bbs/data/attachment/album/202005/27/161117reyw0cjdaoy8xw7j.jpg

可惜,决定版貌似无法用触发给玩家编队(至少我还没发现),

但是!我偶然发现UP1.5/DE的AI也可以实现这个效果,而且更加强大、智能、亲民,甚至超越了"停止单位:1~9"。

其原理与 让AI强行控制玩家1的单位!非常类似,都是利用up-add-object-by-id这个语句来强行获取其他玩家单位的控制权(注意,不是所有权)。


学习方法:
      1. 在决定版的ai文件夹里新建“1次性测试专用.ai”和“1次性测试专用.per”,在per文件里粘贴下面的代码,并另存为UTF-8格式(为什么?);UP1.5玩家则要用GBK编码,其他同理;
      2. 保存后,到编辑器创建一个全新场景,第一个单位放置玩家1的任一单位(此时这个单位的地图ID为0)。对于第二组遍历式代码例子,则继续放置9个P1的木墙,则它们的地图ID为1~9;
      3. 给玩家2指定“1次性测试专用”这个AI个性;
      4. 进入测试,你会发现这个单位/这些木墙被自动编为了9队。

一、最短小、最关键的核心语句单元。

代码:


(defrule
    (true)                        ;可替换为你自己的条件。
=>
    (up-full-reset-search)          ;使用DUC前完全重置一次。
    (up-add-object-by-id 1 c: 0)    ;【核心】把地图ID为0的单位加入本地搜索结果用于强行控制。可通过“搜索并报告场景里某个单位的地图ID的AI”来获取你想编队的单位的地图ID。
    (up-create-group 0 1 c: 9)      ;【核心】“框选”从本地结果里的0号单位算起共1个单位,建立9号搜索组。人类玩家的单位可选1~9。
    (up-modify-group-flag 1 c: 9)   ;【核心】把9号搜索组里的单位加入到9号编队(相当于对选中的单位按Shift+9)
    (disable-self)                  ;可替换为你自己的其他效果。
)




二、锁编队但不占用——超越UP1.5的"停止单位:1~9"。

上面只提供了9号编队作为示例,1~8编队可以自己扩展。也可以善用循环来节省重复代码,甚至可以做出【锁编队但编队仍可容纳其他单位】的效果,可以解决UP1.5会强占这些编队的缺陷!——

演示:
https://www.hawkaoe.net/bbs/data/attachment/album/202005/27/195406qni9wd5ifm9jpiij.jpg

代码:


(defconst ID 100)
(defconst group 101)
(defrule
    (true)
=>
    (set-goal ID 1)                     ;为一个变量,用于依次缓存P1九个单位的地图ID。这里 1 表示接下来遍历的起始单位的ID=1。
    (set-goal group 1)                  ;为一个变量,用于依次缓存1~9这九个搜索组/编队编号,这里 1 表示接下来遍历的起始编队为1。
;   (disable-self)                      ;如果不想“锁编队”,可以启用这一行,使其只会执行一次,于是下面那条规则只会遍历一遍,因为一遍过后group就一直为10了。
)
(defrule
    (up-compare-goal group c:<= 9)      ;当group为1~9时满足条件,达到10后不再满足,会跳出循环,等待下一次遍历。
=>
    (up-full-reset-search)            ;略。
    (up-add-object-by-id 1 g: ID)       ;会把识别为目标变量,让语句读取变量里储存的值,方便遍历。
    (up-create-group 0 1 g: group)      ;会把识别为目标变量,让语句读取变量里储存的值,方便遍历。
    (up-modify-group-flag 1 g: group)   ;略。
    (up-modify-goal ID c:+ 1)         ;ID + 1,用于下次遍历
    (up-modify-goal group c:+ 1)      ;group + 1,用于下次遍历
    (up-jump-rule -1)                   ;(在group为10之前)循环本条规则
)


比较遗憾的是,虽然决定版支持1~20那么多编队,但up-create-group和up-modify-group-flag只支持编号1~9(使用0号时效果是清除该单位的编队)。


三、用Ctrl/Shift+1~9编队来发动技能或效果。

拥有了以上的让AI改变P1单位编队的方法后,我们可以做一个【用Ctrl/Shift+1~9来发动技能】的效果。
注:由于DE目前无法正常获取object-data-group-flag,因此这个效果只能在UP1.5/WK上用。

效果:(注意看步弓手的编队脚标)
https://www.hawkaoe.net/bbs/data/attachment/album/202005/28/065319h1zjj7ztzrj9jz44.gif

代码:(适合有UP1.5 AI语句基础的同学学习)


(defconst object-data-group-flag 73)
(defconst data-group 102)       ;变量。用于储存获取到的主角编队编号
(defconst skill-i 103)          ;变量。用于临时储存遍历次数。逐次储存1~4这四个技能数字

;用触发反馈的event来重置signal(我相信触发方面你们很容易就能做到)
(defrule
    (or (event-detected trigger 1)
      (or (event-detected trigger 2)
            (or (event-detected trigger 3)
                (event-detected trigger 4)
            )
      )
    )
=>
    (acknowledge-event trigger 1)
    (acknowledge-event trigger 2)
    (acknowledge-event trigger 3)
    (acknowledge-event trigger 4)
    (up-set-signal c: 1 c: 0)
    (up-set-signal c: 2 c: 0)
    (up-set-signal c: 3 c: 0)
    (up-set-signal c: 4 c: 0)
)

;初始化:获取主角的编队编号(object-data-group-flag #73)。并重置遍历用的skill-i为1(从技能1开始遍历)
(defrule
    (true)
=>
    (up-set-target-by-id c: 0)    ;0 = 主角地图ID
    (up-get-object-data object-data-group-flag data-group)
;   (up-chat-data-to-all "主角编队 = %d" g: data-group)
    (up-modify-goal skill-i c:= 1)
)

;循环开始。
;如果检测到主角编队为1~4,则把主角重新编回第5队,用于给玩家平时选择。
(defrule
    (up-compare-goal data-group g:== skill-i)
    (up-compare-goal skill-i c:<= 4)
=>
    (up-full-reset-search)
    (up-add-object-by-id 1 c: 0)    ;0 = 主角地图ID
    (up-create-group 0 1 c: 5)
    (up-modify-group-flag 1 c: 5)
    (up-set-signal g: skill-i c: 1)
;   (up-chat-data-to-all "发动了技能 %d" g: skill-i)
)

;循环判断点。若遍历完4个技能则跳出循环,否则回到循环开始
(defrule
    (up-compare-goal skill-i c:<= 4)
=>
    (up-modify-goal skill-i c:+ 1)
    (up-jump-rule -2)
)



期悦 发表于 2020-6-10 20:46:05

已学会!

newtonerdai 发表于 2020-6-11 14:21:50

HudsonLee 发表于 2020-6-10 20:46
已学会!

非常好,学会主干了。
不过disable-self会让你的设置编队只执行一次喔,如果玩家手残用Ctrl+1/2把攻城武器厂和靶场的编队覆盖掉了,那按数字发动效果的机制就失效了。我是建议你做成循环的,持续设置编队。
(吐槽一下,UP1.5下地图ID超过10万可能会变得很卡,DE不知道会不会这样,或许你应该节约一下ID了,比如把城门和TC删掉,用触发来生成)

期悦 发表于 2020-6-11 15:11:59

本帖最后由 HudsonLee 于 2020-6-11 15:37 编辑

噗,这也能加分。覆盖不考虑了,我做的是RPG,只控制一个单位,靠训练单位发动技能,不需要编队其他东西的,再提醒一下,游戏默认快捷键也能选中建筑,这还能覆盖哪肯定是故意的。我倒是想到玩家可能Del掉,循环给创建回来但是没编队了。

我用的是最小号的地图,估计才画了5分之一就7万ID....然后就会卡么?照这样更大的图就没法做了!

(看看我的地图还是很空的样子)

newtonerdai 发表于 2020-6-11 15:47:56

HudsonLee 发表于 2020-6-11 15:11
噗,这也能加分。覆盖不考虑了,我做的是RPG,只控制一个单位,靠训练单位发动技能,不需要编队其他东西的 ...

可以继续画试试看,毕竟我也不知道DE的优化如何。
ID增殖的罪魁祸首是【附加单位】,每次载入场景都会重新生成。如果你测试之后返回场景编辑,那附加单位就会消耗一波ID。

下图是城门的闭锁闸门的附加单位,81就是两侧的门柱。其他属性可以不必在意。
城镇中心也有很多个附加单位。

期悦 发表于 2020-6-11 15:55:35

newtonerdai 发表于 2020-6-11 15:47
可以继续画试试看,毕竟我也不知道DE的优化如何。
ID增殖的罪魁祸首是【附加单位】,每次载入场景都会重 ...

- -那我现在删城门和TC,附加单位的ID还保留么?我现在才知道,这得科普一波啊。
页: [1]
查看完整版本: [DE/UP1.5] 让AI来帮玩家1的单位编队(Shift+1~9)