newtonerdai 发表于 2020-3-21 01:58:04

[UP1.5] [玩家编号-颜色校正模块] 在联机场景里终于可以正常使用数字AI啦!

本帖最后由 newtonerdai 于 2020-6-13 11:25 编辑

前言
由于联机场景的准备房间里,玩家可以随意选择颜色,而触发系统是按玩家颜色来分配玩家编号,AI系统则恰恰相反,是按房间里玩家位置(从上到下依次为1~8号位)来分配编号。

假如,在编辑器“玩家”选项卡中预设的玩家颜色是:

[*]青色玩家 为 玩家5。
[*]绿色玩家 为 玩家3。

而在开房准备时:

[*]3号位玩家用了青色,则触发里视为P5,AI里视为P3。
[*]5号位玩家用了绿色,则触发里视为P3,AI里视为P5。

如果我们这么设置AI和触发:

[*]AI:当收到P3的嘲弄数字1时,向触发系统发送AI信号3号;当收到P5的嘲弄数字1时,发送AI信号5号
[*]触发:当收到AI信号3号时,给P3英雄发动技能;当收到AI信号5号时,给P5英雄发动技能。

看起来没有问题?然而实际上会出现这种结果:

[*]如果游戏时青色玩家发出数字1,AI收到了P3(青色玩家)的嘲弄,并发送了AI信号3号,触发也受到了AI信号3号,但却是给P3(绿色玩家)英雄发动了技能。
[*]反之,如果绿色玩家发出数字1,AI收到了P5(绿色玩家)的嘲弄,并发送了AI信号5号,触发也受到了AI信号5号,但却是给P5(青色玩家)英雄发动了技能。

想不到吧!P3发出数字将控制P5的效果生效,而P5发出数字将控制P3效果生效。
这就势必会造成数字AI的错乱,于是以往的联机场景里基本从不考虑使用数字AI作为指令来发动效果。


但是!在UP/WK/DE的新AI语句时代下,这个窘况将彻底终结!因为【玩家编号-颜色校正模块】横空出世了!


【玩家编号-颜色校正模块】
注意:本AI模块只适用于UserPatch 1.5(UP1.5)、WololoKingdoms(WK)、Definitive Edition(DE/决定版)或其他装了UP1.5拓展的版本。

本模块有两种分型:

[*]分型一:让AI使用触发系统的玩家编号,从而与触发的玩家编号相同
[*]分型二:让AI以玩家颜色为依据识别玩家编号,从而与触发的玩家编号相同

最终效果都是以8个代数分别表示8个玩家,且与触发的玩家编号一致,可正常使用数字AI之类的效果。

选择哪一个分型则取决于你的需求:

[*]如果你喜欢用编辑器的玩家编号,那就用分型一;
[*]如果分型一对你而言太绕了,或者喜欢用玩家颜色区分编号,那就用分型二。



分型一:
;//-------------------------------------------------------------------------//
;//                        玩家编号-颜色校正模块 - 向触发玩家编号统一      //
;//-------------------------------------------------------------------------//
(defconst gl-color 100)
(defconst P1 101)
(defconst P2 102)
(defconst P3 103)
(defconst P4 104)
(defconst P5 105)
(defconst P6 106)
(defconst P7 107)
(defconst P8 108)

;假如在编辑器“玩家”标签页中预设的玩家颜色是:青色玩家 == P5。
;--在开场景房时,假如3号位用了青色(颜色id 5),则触发里是P5,AI里是P3;
;--AI校正颜色模块获取3号位玩家颜色,得到的是青色(颜色id 5),于是记goal P3为5(即P3相当于一个代数,代表 5 这个数);
;--于是之后(chat-to-player P3 ...)就是向比赛中的青色玩家发送信息;
;--而触发里对P5的条件效果,实际也是对青色玩家生效;
;--于是,经过颜色校正后,触发里的玩家1~8就等同于AI语句里的P1~P8。你想要检测触发里的玩家几发出的嘲弄,那就放心在AI里写P几吧。

(defrule
   (up-compare-goal P1 <= 0)
=>
   (up-modify-sn sn-focus-player-number c:+ 1)
   (up-get-player-color focus-player gl-color)       ;把focus-player(即sn-focus-player-number)对应的玩家的颜色id储存到gl-color里。颜色id分别为:蓝1 红2 绿3 黄4 青5 紫6 灰7 橙8。
   (up-modify-goal P1 g:= P2)      ;把P2储存的数字复制(赋值)给P1,下面以此类推。
   (up-modify-goal P2 g:= P3)
   (up-modify-goal P3 g:= P4)
   (up-modify-goal P4 g:= P5)
   (up-modify-goal P5 g:= P6)      ;如果你场景里的玩家数是5,则删掉后面6、7、8对应的3行,并把本行换成(up-modify-goal P5 g:= gl-color)。以此类推。
   (up-modify-goal P6 g:= P7)
   (up-modify-goal P7 g:= P8)
   (up-modify-goal P8 g:= gl-color)      ;第一次执行时,P1~P7都是-1(默认值),P8则是1号位玩家的颜色id。第二次执行时,P1~P6都是-1,P7储存1号位玩家的颜色id,P8储存2号位玩家的。以此类推,到第八次执行也就是最后一次时,P1将储存1号位玩家的颜色id,P2~P8同理,这时P1>0,规则的条件不再满足。
   (up-jump-rule -1)      ;up-jump-rule -1会使这条规则一直重复执行,直到条件不满足时才去执行下面的规则
)
(defrule
   (up-compare-goal P1 > 0)
=>
   (up-modify-sn sn-focus-player-number c:= 1)      ;模块校正完成后,将sn-focus-player-number还原为1
;   (up-chat-data-to-all "Player1's color: %d" g: P1)       ;下面这些是用来检查的,把行首分号去掉即可生效。可以把P1保存的玩家编号数字发送出来。以此类推
;   (up-chat-data-to-all "Player2's color id: %d" g: P2)
;   (up-chat-data-to-all "Player3's color id: %d" g: P3)
;   (up-chat-data-to-all "Player4's color id: %d" g: P4)
;   (up-chat-data-to-all "Player5's color id: %d" g: P5)
;   (up-chat-data-to-all "Player6's color id: %d" g: P6)
;   (up-chat-data-to-all "Player7's color id: %d" g: P7)
;   (up-chat-data-to-all "Player8's color id: %d" g: P8)
   (disable-self)
)

使用这个分型校正玩家编号后,你可以这么使用数字AI:
想达成的效果:
编辑器预设了玩家5是青色,但开房时3号位选了青色。AI接收到青色玩家发出的数字1后,发送AI信号#5,触发接收到AI信号#5后发动某个效果。

AI语句这么写:
既然编辑器里预设了玩家5是青色玩家,那AI里就用P5来替代“5”作为玩家代号
(defrule
    (true)
=>
    (up-modify-sn sn-focus-player-nunber c:= P5)    ;设置焦点玩家focus-player为P5储存的数字,即青色颜色id: 5
)
(defrule
    (taunt-detected focus-player 1)    ;taunt-detected无法直接识别P1~P8这种“代数”(专业一点叫“目标”),而可以识别focus-player,所以需要上一条规则来切换sn-focus-player-number。
=>
    (set-signal 3)    ;你还可以用cc资源法来与触发传递信息
    (disable-self)    ;如果需要循环利用,则需要开动脑筋自己想咯,我这里只是做简单例子了。
)


分型二:
;//-------------------------------------------------------------------------//
;//                        玩家编号-颜色校正模块 - 以玩家颜色为依据          //
;//-------------------------------------------------------------------------//
;本模块适用于联机场景,如果不经过校正,用户在准备房间里乱选与其玩家位置不匹配的颜色,会导致触发里的玩家x与AI里的玩家x不一致。
;比如,场景编辑器里预设青色玩家是玩家5,而开房间时3号位的玩家选了青色,那么触发对玩家5的条件效果会应用到青色玩家,即3号位玩家身上,而AI检测player5时,就不是检测青色玩家

(defconst get-color 149)
(defconst gl-color      140)
(defconst P-blue      141)
(defconst P-red         142)
(defconst P-green       143)
(defconst P-yellow      144)
(defconst P-cyan      145)
(defconst P-purple      146)
(defconst P-grey      147)
(defconst P-orange      148)

;假如在编辑器“玩家”标签页中预设的玩家颜色是:青色玩家 == P5。
;--在开场景房时,假如3号位用了青色(颜色id 5),则触发里是P5,AI里是P3;
;--AI校正颜色模块获取青色玩家编号,得到的是3号位玩家,于是记青色玩家P-cyan为3(即P-cyan相当于一个代数,代表 3 这个数);
;--于是之后(chat-to-player P-cyan ...)就是向3号位玩家发送信息,即比赛中的青色玩家。
;--而触发里对P5的条件效果,实际也是对青色玩家生效;
;--于是,经过颜色校正后,你可以用编辑器预设的玩家颜色来替代AI语句里的玩家1~8,与编辑器的玩家编号是一致的。比如编辑器里红色是玩家2,那么AI里如果要检测这个玩家的嘲弄,那就使用P-red来替代2吧。

(defrule
    (true)
=>
    (set-goal get-color 0)    ;初始化
    (disable-self)
)

(defrule      ;这是后面8条规则完成后会跳转(jump-rule)回来的地方
    (up-compare-sn sn-focus-player-number c:< 8)            ;8是场景的玩家数量。使用时请换成你场景里的实际玩家数。
    (up-compare-goal get-color c:< 255)            ;255 = 1 + 2 + 4 + ... + 128。每一位数字代表一种颜色,当加到255时代表所有玩家颜色都已获取。1~128分别对应颜色:蓝1 红2 绿4 黄8 青16 紫32 灰64 橙128。使用时请依据你场景里的玩家数来计算。
=>
    (up-modify-sn sn-focus-player-number c:+ 1)
    (up-get-player-color focus-player gl-color)       ;把focus-player(即sn-focus-player-number)对应的玩家的颜色id储存到gl-color里。颜色id分别为:蓝1 红2 绿3 黄4 青5 紫6 灰7 橙8。
)
(defrule
    (up-compare-goal gl-color c:== 1)
=>
    (up-modify-goal P-blue s:= sn-focus-player-number)
    (up-modify-goal get-color c:+ 1)
    (up-jump-rule -2)
    (disable-self)
)
(defrule
    (up-compare-goal gl-color c:== 2)
=>
    (up-modify-goal P-red s:= sn-focus-player-number)
    (up-modify-goal get-color c:+ 2)
    (up-jump-rule -3)
    (disable-self)
)
(defrule
    (up-compare-goal gl-color c:== 3)
=>
    (up-modify-goal P-green s:= sn-focus-player-number)
    (up-modify-goal get-color c:+ 4)
    (up-jump-rule -4)
    (disable-self)
)
(defrule
    (up-compare-goal gl-color c:== 4)
=>
    (up-modify-goal P-yellow s:= sn-focus-player-number)
    (up-modify-goal get-color c:+ 8)
    (up-jump-rule -5)
    (disable-self)
)
(defrule
    (up-compare-goal gl-color c:== 5)
=>
    (up-modify-goal P-cyan s:= sn-focus-player-number)         ;如果你场景里的玩家数是5,则删掉后面6、7、8对应的规则(从“(defrule”到单独的“)”结尾)。以此类推。
    (up-modify-goal get-color c:+ 16)
    (up-jump-rule -6)          ;up-jump-rule -6将会往前跳转6条规则(包括自身)。这些jump-rule将使得整个模块在瞬间完成校正工作。
    (disable-self)
)
(defrule
    (up-compare-goal gl-color c:== 6)
=>
    (up-modify-goal P-purple s:= sn-focus-player-number)
    (up-modify-goal get-color c:+ 32)
    (up-jump-rule -7)
    (disable-self)
)
(defrule
    (up-compare-goal gl-color c:== 7)
=>
    (up-modify-goal P-grey s:= sn-focus-player-number)
    (up-modify-goal get-color c:+ 64)
    (up-jump-rule -8)
    (disable-self)
)
(defrule
    (up-compare-goal gl-color c:== 8)
=>
    (up-modify-goal P-orange s:= sn-focus-player-number)
    (up-modify-goal get-color c:+ 128)
    (up-jump-rule -9)
    (disable-self)
)

(defrule
    (up-compare-goal get-color c:== 255)      ;同样,255要因地制宜,取决于场景里的玩家数量
=>
    (up-modify-sn sn-focus-player-number c:= 1)      ;模块校正完成后,将sn-focus-player-number还原为1
;    (up-chat-data-to-all "P-blue = %d" g: P-blue)       ;下面这些是用来检查的,把行首分号去掉即可生效。可以把P-blue保存的玩家编号数字发送出来。以此类推
;    (up-chat-data-to-all "P-red = %d" g: P-red)
;    (up-chat-data-to-all "P-green = %d" g: P-green)
;    (up-chat-data-to-all "P-yellow = %d" g: P-yellow)
;    (up-chat-data-to-all "P-cyan = %d" g: P-cyan)
;    (up-chat-data-to-all "P-purple = %d" g: P-purple)
;    (up-chat-data-to-all "P-grey = %d" g: P-grey)
;    (up-chat-data-to-all "P-orange = %d" g: P-orange)
    (disable-self)
)

使用这个分型校正玩家编号后,你可以这么使用数字AI:
想要的效果:(与上面的一样)
编辑器预设了玩家5是青色,但开房时3号位选了青色。AI接收到青色玩家发出的数字1后,发送AI信号#5,触发接收到AI信号#5后发动某个效果。

AI语句这么写:
既然编辑器里预设了玩家5是青色玩家,那AI里就用P-cyan来替代“5”作为玩家代号。
(defrule
    (true)
=>
    (up-modify-sn sn-focus-player-nunber c:= P-cyan)    ;设置焦点玩家focus-player为P-cyan储存的数字,即青色玩家的位置编号: 3号位,也就是触发里的玩家5。
)
(defrule
    (taunt-detected focus-player 1)    ;taunt-detected无法直接识别P-cyan这种“代数”(专业一点叫“目标”),而可以识别focus-player,所以需要上一条规则来切换sn-focus-player-number
=>
    (set-signal 5)    ;你还可以用cc资源法来与触发传递信息
    (disable-self)    ;如果需要循环利用,则需要开动脑筋自己想咯,我这里只是做简单例子了。
)

cxt 发表于 2020-3-21 07:49:25

新桶大半夜发帖!{:11_481:}

wzj1809620632 发表于 2020-7-30 11:19:57

请问,有局域网联机能使用的ai吗

Dick 发表于 2020-8-4 16:06:52

以前也有在多人場景用數字AI,倒是沒有出現過樓主說的問題;只要不隨便改預設顏色就不會出事。
倒是更多會出現Host player掉線,而新Host player沒有AI檔,導致AI無法運行。
页: [1]
查看完整版本: [UP1.5] [玩家编号-颜色校正模块] 在联机场景里终于可以正常使用数字AI啦!