2016.12.2202:59

AI 立回技巧相关(Part.2)

Episode 11 立回技巧相关(Part.2)

最近沉迷屁股所以没时间更新了_(:3」∠)_

接着上一篇来讲,上一篇我们谈到了立回中如何对应大部分地波的记忆办法,记忆解决办法就是记录下地波的状态号和帧数和距离来确定大跳抓硬直,这次我们看看如何对应投技和当身问题(因为不想分第三块来讲就干脆搁到一起来说了)

方法和之前的办法是一样的,大家要做的事情就是实验和思考如何去正确的使用,当然如果是单人战的话没有必要考虑那么多,如果是双人对打那么就要考虑一下了,有时候你跳一下就可能成为一个很大的破绽,这样会给你的队伍带来很大的不利

先说投技,我们先要做的事就是把投技给记录下来,当然一般只记录平地投,对于投技一般有个特点就是无法抓空中对象(对正常向来说,如果是魔改(对某些人来说)请自重!),那么解决办法就是起跳然后JABCD或者空中特殊技等技能来抓破绽硬直(如果投技全程无敌也请自重)

;----------------------------------------------------------------------
[State 33000, Null]
Type = Null
TriggerAll = Time = 0
Trigger1 = var(20) := -1
Trigger1 = var(21) := -1
Trigger1 = var(22) := -1
Trigger1 = var(23) := -1
Trigger1 = var(24) := -1
Trigger1 = var(25) := -1
Trigger1 = var(26) := -1
Trigger1 = var(27) := -1
Trigger1 = var(28) := -1
Trigger1 = var(29) := -1
IgnoreHitPause = 1

;----------------------------------------------------------------------
;敵に投げステート記憶
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0 ;敌方不可控记录
Trigger1 = EnemyNear(Root,var(58)),MoveType = A ;显示判定为攻击
Trigger1 = EnemyNear(Root,var(58)),HitDefAttr = SC,NT,ST,HT ;所有投技
Trigger1 = Helper(33000+Root,ID),var(20) = -1
var(20) = EnemyNear(Root,var(58)),StateNo ;记下状态号
IgnoreHitPause = 1

......(方法和以前一样我就不再重复了)

[State 33000, VarSet]
Type = VarSet
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = EnemyNear(Root,var(58)),HitDefAttr = SC,NT,ST,HT
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(20)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(21)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(22)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(23)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(24)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(25)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(26)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(27)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(28)
Trigger1 = Helper(33000+Root,ID),var(20) != -1
Trigger1 = Helper(33000+Root,ID),var(21) != -1
Trigger1 = Helper(33000+Root,ID),var(22) != -1
Trigger1 = Helper(33000+Root,ID),var(23) != -1
Trigger1 = Helper(33000+Root,ID),var(24) != -1
Trigger1 = Helper(33000+Root,ID),var(25) != -1
Trigger1 = Helper(33000+Root,ID),var(26) != -1
Trigger1 = Helper(33000+Root,ID),var(27) != -1
Trigger1 = Helper(33000+Root,ID),var(28) != -1
Trigger1 = Helper(33000+Root,ID),var(29) = -1
var(29) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

像这样,该helper内的var(20)~var(29)就负责记录10个投技状态,接下来要做的就是AI部分,考虑对策优先,对策部分先写上方,然后下面记录一般对策,所有关于投技对策的AI部分全部写在AI较为上面的部分,也就是优先的意思,在那之前,先算好你小跳的时间,比如小跳是18,中影跳是25,那么小跳的时间是小于中影跳的

;-----------------------------------------------------------------------
; 相手の特殊ステート(投げ)記憶
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = fvar(8) != 0
FV = 8
Value = 0
IgnoreHitPause = 1

[State -3, 相手の特殊ステート]
Type = Null
TriggerAll = var(59) = 1
TriggerAll = NumHelper(33000+ID)
TriggerAll = EnemyNear(var(58)),MoveType = A
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(20)
Trigger1 = fvar(8) := fvar(8) + 1 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(21)
Trigger2 = fvar(8) := fvar(8) + 1 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(22)
Trigger3 = fvar(8) := fvar(8) + 1 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(23)
Trigger4 = fvar(8) := fvar(8) + 1 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(24)
Trigger5 = fvar(8) := fvar(8) + 1 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(25)
Trigger6 = fvar(8) := fvar(8) + 1 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(26)
Trigger7 = fvar(8) := fvar(8) + 1 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(27)
Trigger8 = fvar(8) := fvar(8) + 1 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(28)
Trigger9 = fvar(8) := fvar(8) + 1 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(29)
Trigger10 = fvar(8) := fvar(8) + 1 || 1
IgnoreHitPause = 1

像这样先记录下到一个var内,然后这个var不为0的时候代表对面是被记录下来的投技

[State -3, 小、中ジャンプ隙突き(対投げ用)]
Type = ChangeState
Value = ifelse(Abs(EnemyNear(var(58)),Pos X - Pos X) > D,(前中影跳state),ifelse(Abs(EnemyNear(var(58)),Pos X - Pos X) > C,(前小跳state),(上小跳state))) ; C < D,当然这个只是举例子,如果你喜欢用中影跳的话也没关系
TriggerAll = var(59) = 1
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll =!EnemyNear(var(58)),Ctrl
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType = A
TriggerAll = EnemyNear(var(58)),StateNo >= 200
TriggerAll = EnemyNear(var(58)),AnimTime < -18
TriggerAll = EnemyNear(var(58)),HitDefAttr = SCA, NT, ST, HT || (fvar(8) != 0) ;代表记录下来的投技和检测到的投技(双保险)
TriggerAll = EnemyNear(var(58)),Time >= 50-var(59)*5 || var(59) > 9
TriggerAll = EnemyNear(var(58)),Facing != Facing || EnemyNear(var(58)),Facing = Facing && var(51) = 5 ;有关var(51)我在前面的双打部分提到过,var(51) = 5代表背后有敌人,也就是说是被夹击的状态,保持这种状态去攻击被对你的敌人可以救你的队友
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = Abs(EnemyNear(var(58)),Pos X - Pos X) = [A,B]

[State -3, バックステップ 投げ外し]
Type = ChangeState
Value = 105 ;代表44的意思,有些角色44下可以进行出招
TriggerAll = var(59) = 1
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll = BackEdgeBodyDist >= 30 ;只要不在墙角就行,如果你想跳离墙角的话就用大跳或者其他无敌闪避技能
TriggerAll =!EnemyNear(var(58)),Ctrl
TriggerAll = EnemyNear(var(58)),Vel Y >= 0 ;代表对手在平地的意思(大概不会有钻地龙吧)
TriggerAll = EnemyNear(var(58)),HitDefAttr = SCA, NT, ST, HT || (fvar(8) != 0)
TriggerAll = EnemyNear(var(58)),Time >= 50-var(59)*5 || var(59) > 9
TriggerAll = EnemyNear(var(58)),Facing != Facing || EnemyNear(var(58)),Facing = Facing && var(51) = 5
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = Abs(EnemyNear(var(58)),Pos X - Pos X) = [A,B]

44部分写在跳的下面也就是说,如果不满足跳跃成立的条件就赶紧44,甚至可以在墙角的时候进行大跳等判断迅速逃离墙角,以上投技的部分就先解释到这里,我们接下来看看当身,之前也有提到过当身的对应记录办法,这里也再提一下

;----------------------------------------------------------------------
;自分被ステート奪取記憶
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),StateNo >= 200
TriggerAll = EnemyNear(Root,var(58)),StateType != A
TriggerAll =(Root,StateNo != [120,159]) && (Root,StateNo != [5000,5500])
TriggerAll = Root,Movetype = H && Root,Time = 1
Trigger1 = Helper(33000+Root,ID),fvar(10) = 0
FV = 10
Value = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1

.......

[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),StateNo >= 200
TriggerAll = EnemyNear(Root,var(58)),StateType != A
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(10)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(11)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(12)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(13)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(14)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(15)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(16)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(17)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(18)
TriggerAll =(Root,StateNo != [120,159]) && (Root,StateNo != [5000,5500])
TriggerAll = Root,Movetype = H && Root,Time = 1
Trigger1 = Helper(33000+Root,ID),fvar(10)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(11)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(12)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(13)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(14)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(15)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(16)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(17)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(18)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(19) = 0
FV = 19
Value = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1

;-----------------------------------------------------------------------
; 自分被ステート奪取記憶
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = fvar(5) != 0
FV = 5
Value = 0
IgnoreHitPause = 1

[State -3, 自分被ステート奪取]
Type = Null
TriggerAll = var(59) = 1
TriggerAll = NumHelper(33000+ID)
TriggerAll = EnemyNear(var(58)),Ctrl = 0
TriggerAll = EnemyNear(var(58)),MoveType = A
TriggerAll = EnemyNear(var(58)),StateNo >= 200
TriggerAll = EnemyNear(var(58)),StateType != A
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(10)
Trigger1 = fvar(5) := fvar(5) + 2 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(11)
Trigger2 = fvar(5) := fvar(5) + 2 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(12)
Trigger3 = fvar(5) := fvar(5) + 2 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(13)
Trigger4 = fvar(5) := fvar(5) + 2 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(14)
Trigger5 = fvar(5) := fvar(5) + 2 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(15)
Trigger6 = fvar(5) := fvar(5) + 2 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(16)
Trigger7 = fvar(5) := fvar(5) + 2 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(17)
Trigger8 = fvar(5) := fvar(5) + 2 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(18)
Trigger9 = fvar(5) := fvar(5) + 2 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(19)
Trigger10 = fvar(5) := fvar(5) + 2 || 1
IgnoreHitPause = 1

;----------------------------------------------------------------------
[State 33000, Null]
Type = Null
TriggerAll = Time = 0
Trigger1 = var(0) := -1
Trigger1 = var(1) := -1
.......
Trigger1 = var(19) := -1
IgnoreHitPause = 1

;----------------------------------------------------------------------
;敵に当身ステート記憶 Part 1
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = Helper(33000+Root,ID),var(0) = -1
var(0) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

.......

[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(0)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(1)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(2)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(3)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(4)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(5)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(6)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(7)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(8)
Trigger1 = Helper(33000+Root,ID),var(0) != -1
Trigger1 = Helper(33000+Root,ID),var(1) != -1
Trigger1 = Helper(33000+Root,ID),var(2) != -1
Trigger1 = Helper(33000+Root,ID),var(3) != -1
Trigger1 = Helper(33000+Root,ID),var(4) != -1
Trigger1 = Helper(33000+Root,ID),var(5) != -1
Trigger1 = Helper(33000+Root,ID),var(6) != -1
Trigger1 = Helper(33000+Root,ID),var(7) != -1
Trigger1 = Helper(33000+Root,ID),var(8) != -1
Trigger1 = Helper(33000+Root,ID),var(9) = -1
var(9) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

;----------------------------------------------------------------------
;敵に当身ステート記憶 Part 2
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,fvar(5) = 2
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = Helper(33000+Root,ID),var(10) = -1
var(10) = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1

.......

[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,fvar(5) = 2
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(10)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(11)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(12)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(13)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(14)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(15)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(16)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(17)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(18)
Trigger1 = Helper(33000+Root,ID),var(10) != -1
Trigger1 = Helper(33000+Root,ID),var(11) != -1
Trigger1 = Helper(33000+Root,ID),var(12) != -1
Trigger1 = Helper(33000+Root,ID),var(13) != -1
Trigger1 = Helper(33000+Root,ID),var(14) != -1
Trigger1 = Helper(33000+Root,ID),var(15) != -1
Trigger1 = Helper(33000+Root,ID),var(16) != -1
Trigger1 = Helper(33000+Root,ID),var(17) != -1
Trigger1 = Helper(33000+Root,ID),var(18) != -1
Trigger1 = Helper(33000+Root,ID),var(19) = -1
var(19) = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1

;-----------------------------------------------------------------------
; 相手の特殊ステート(当身)記憶
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = fvar(2) != 0
FV = 2
Value = 0
IgnoreHitPause = 1

[State -3, 相手の特殊ステート]
Type = Null
TriggerAll = var(59) = 1
TriggerAll = NumHelper(33000+ID)
TriggerAll = EnemyNear(var(58)),MoveType = A
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(0)
Trigger1 = fvar(2) := fvar(2) + 1 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(1)
Trigger2 = fvar(2) := fvar(2) + 1 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(2)
Trigger3 = fvar(2) := fvar(2) + 1 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(3)
Trigger4 = fvar(2) := fvar(2) + 1 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(4)
Trigger5 = fvar(2) := fvar(2) + 1 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(5)
Trigger6 = fvar(2) := fvar(2) + 1 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(6)
Trigger7 = fvar(2) := fvar(2) + 1 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(7)
Trigger8 = fvar(2) := fvar(2) + 1 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(8)
Trigger9 = fvar(2) := fvar(2) + 1 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(9)
Trigger10 = fvar(2) := fvar(2) + 1 || 1
Trigger11 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(10)
Trigger11 = fvar(2) := fvar(2) + 2 || 1
Trigger12 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(11)
Trigger12 = fvar(2) := fvar(2) + 2 || 1
Trigger13 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(12)
Trigger13 = fvar(2) := fvar(2) + 2 || 1
Trigger14 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(13)
Trigger14 = fvar(2) := fvar(2) + 2 || 1
Trigger15 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(14)
Trigger15 = fvar(2) := fvar(2) + 2 || 1
Trigger16 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(15)
Trigger16 = fvar(2) := fvar(2) + 2 || 1
Trigger17 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(16)
Trigger17 = fvar(2) := fvar(2) + 2 || 1
Trigger18 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(17)
Trigger18 = fvar(2) := fvar(2) + 2 || 1
Trigger19 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(18)
Trigger19 = fvar(2) := fvar(2) + 2 || 1
Trigger20 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(19)
Trigger20 = fvar(2) := fvar(2) + 2 || 1
IgnoreHitPause = 1

同样这里也不多解释,看不明白的看前面的当身对应篇有说明,这里只是回顾部分,接下来就要想想如何用跳和44来逃避当身了,先举个跳跃的例子

[State -3, ハイジャンプ 逃げる]
Type = ChangeState
Value = (大跳state)
TriggerAll = var(59) = 1
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll = BackEdgeBodyDist < 30 ;前提条件是在墙角内想逃离墙角
TriggerAll =!EnemyNear(var(58)),Ctrl
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType != H
TriggerAll = EnemyNear(var(58)),StateNo >= 200
TriggerAll = EnemyNear(var(58)),Facing != Facing && P2Dist X > 0 || fvar(5) = 2
TriggerAll = EnemyNear(var(58)),Time >= 50-var(59)*5 || var(59) > 9
TriggerAll =!Enemy,NumProj && fvar(9) = 0 && (!InGuardDist || fvar(5) = 2) ;fvar(9) = 0是前篇讲的有关地波记录state的变量
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = EnemyNear(var(58)),AnimTime < -38 || Abs(EnemyNear(var(58)),Pos X - Pos X) < A && EnemyNear(var(58)),AnimTime < -18 ;大概一个小跳的时间并且距离更近的时候就按小跳时间计算,距离太远则要防止对面的对空技能
Trigger1 = (fvar(2) != 0 && fvar(5) = 2 || fvar(2) = 2) && Abs(EnemyNear(var(58)),Pos X - Pos X) < B ;B > A

[State -3, バックステップ/中後ジャンプ 逃げる]
Type = ChangeState
Value = ifelse(P2BodyDist X > 60,(后影中跳state),105)
TriggerAll = var(59) = 1
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll = BackEdgeBodyDist >= 30 ;这里条件和上面相反,不在墙角内
TriggerAll =!EnemyNear(var(58)),Ctrl
TriggerAll = EnemyNear(var(58)),StateType != A || EnemyNear(var(58)),StateType = A && EnemyNear(var(58)),Vel X >= 0 ;这里把空中当身也算进去了
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType != H
TriggerAll = EnemyNear(var(58)),StateNo >= 200
TriggerAll = EnemyNear(var(58)),Facing != Facing && P2Dist X > 0 || fvar(5) = 2
TriggerAll = EnemyNear(var(58)),Time >= 50-var(59)*5 || var(59) > 9
TriggerAll =!Enemy,NumProj && fvar(9) = 0 && (!InGuardDist || fvar(5) = 2)
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = EnemyNear(var(58)),AnimTime < -10 || EnemyNear(var(58)),StateType = A && EnemyNear(var(58)),Vel X >= 0 ;(只需要极短的时间来确认或者对面是空中当身的情况)
Trigger1 = (fvar(2) != 0 && fvar(5) = 2 || fvar(2) = 2) && Abs(EnemyNear(var(58)),Pos X - Pos X) < C

以上是举例说明内容,更多的应对还需要各位自己去实践运用

好了,今天的课就先到这,如果您有什么问题的话可以私信我,我会第一时间给您答复,或者把问题发到我的邮箱

mizore@kotori.moe, 谢谢大家!
2016.11.0512:20

AI 立回技巧相关(Part.1)

Episode 10 立回技巧相关(Part.1)

各位好久不见,我又回来了,这次我们谈谈立回的某些技巧

众所周知,立回是什么,一个人在战斗中的位置移动,走路,跑步,跳跃等等之类的,这些都是立回,怎么样才能做到所谓的精准,发挥到极致呢?其实这个也是根据这个角色的性能而决定的,比如你有当身,可以主动进攻空振当身什么的,这样比较赚,如果你拳脚和硬直属于比较变态的那种,你可以主动进攻,猛压的那种,也就是前跳,跑步和攻击的概率可以写高一点,如果你属于下位机,不妨把防御写好一点,然后等破绽抓硬直来进攻,格斗的精髓,记住,如果你有龟的资本的话,那么能龟就龟,因为你在开场时不知道对面是什么样的性能,所以如果能三十六计走为上策的话是不错的选择,当然也看作者的风格

我们今天的正题主要谈谈大前跳的作用,大家知道,大前跳是跳的很高,很远,适合打逆和突进这种的跳跃,非常实用,它的作用除了进攻以外也可以用来抓硬直,那么怎么做到呢

首先,我们先看看自己的大跳性能,比如说我举个例子,大前跳是跳跃,也是要经过state 40-50-52 这么一个变化的,打开DEBUG,比如40这个状态是4帧,然后进入50,按下pause后按scrool lock数帧数,或者截取得到最后1帧,再看DEBUG显示时间是多少,比如显示的是34,因为是从0开始数的,所以时间一共是4+35,也就是39,那么取得了这个数据,大跳的时间是39帧

接下来要怎么用呢,之前我们学过用helper记录的方法,这里也举个例子

;----------------------------------------------------------------------
[State 33000, Null]
Type = Null
TriggerAll = Time = 0
Trigger1 = var(30) := -1
Trigger1 = var(31) := -1
Trigger1 = var(32) := -1
Trigger1 = var(33) := -1
Trigger1 = var(34) := -1
Trigger1 = var(35) := -1
Trigger1 = var(36) := -1
Trigger1 = var(37) := -1
Trigger1 = var(38) := -1
Trigger1 = var(39) := -1
IgnoreHitPause = 1

;----------------------------------------------------------------------
;敵に飛び道具ステート記憶
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),NumProj = 1
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),AnimTime < EnemyNear(Root,var(58)),Time - 35 (先记录好跳跃全程时间)
Trigger1 = Helper(33000+Root,ID),var(30) = -1
var(30) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

; Abs(EnemyNear(Root,var(58)),Time - EnemyNear(Root,var(58)),AnimTime) 这个代表对面状态总时间
....

[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),NumProj = 1
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),AnimTime < EnemyNear(Root,var(58)),Time - 35
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(30)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(31)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(32)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(33)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(34)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(35)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(36)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(37)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(38)
Trigger1 = Helper(33000+Root,ID),var(30) != -1
Trigger1 = Helper(33000+Root,ID),var(31) != -1
Trigger1 = Helper(33000+Root,ID),var(32) != -1
Trigger1 = Helper(33000+Root,ID),var(33) != -1
Trigger1 = Helper(33000+Root,ID),var(34) != -1
Trigger1 = Helper(33000+Root,ID),var(35) != -1
Trigger1 = Helper(33000+Root,ID),var(36) != -1
Trigger1 = Helper(33000+Root,ID),var(37) != -1
Trigger1 = Helper(33000+Root,ID),var(38) != -1
Trigger1 = Helper(33000+Root,ID),var(39) = -1
var(39) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

这样就可以记录10个地波状态了,确保先有35帧以上,然后开始写AI,花费一个var

;-----------------------------------------------------------------------
; 相手の特殊ステート(飛び道具)記憶
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = fvar(9) != 0
FV = 9
Value = 0
IgnoreHitPause = 1

[State -3, 相手の特殊ステート]
Type = Null
TriggerAll = var(59) = 1
TriggerAll = NumHelper(33000+ID)
TriggerAll = EnemyNear(var(58)),MoveType = A
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(30)
Trigger1 = fvar(9) := fvar(9) + 1 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(31)
Trigger2 = fvar(9) := fvar(9) + 1 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(32)
Trigger3 = fvar(9) := fvar(9) + 1 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(33)
Trigger4 = fvar(9) := fvar(9) + 1 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(34)
Trigger5 = fvar(9) := fvar(9) + 1 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(35)
Trigger6 = fvar(9) := fvar(9) + 1 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(36)
Trigger7 = fvar(9) := fvar(9) + 1 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(37)
Trigger8 = fvar(9) := fvar(9) + 1 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(38)
Trigger9 = fvar(9) := fvar(9) + 1 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(39)
Trigger10 = fvar(9) := fvar(9) + 1 || 1
IgnoreHitPause = 1

现在,fvar(9)如果变为1就代表符合要求可以大跳

[State -3, 大ジャンプ 対飛び道具]
Type = ChangeState
Value = 36
TriggerAll = var(59) = 1
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll =!EnemyNear(var(58)),Ctrl
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType != H ;上面是基本属性不多解释了
TriggerAll = EnemyNear(var(58)),AnimTime <= -39 ;39帧跳跃
TriggerAll = EnemyNear(var(58)),StateNo = [1000,2000) ;2000以上可能是超杀最好别去抓
TriggerAll = EnemyNear(var(58)),Facing != Facing ;面对面
TriggerAll = EnemyNear(var(58)),Time >= 50-var(59)*10 || var(59) > 9 ;反应相关
TriggerAll = Random < EnemyNear(var(58)),Time*ifelse( var(59) > 9,25,20) ;概率相关
TriggerAll =!InGuardDist || Abs(EnemyNear(var(58)),Pos X - Pos X) > 190 ;如果默认guarddist = 160的话,190大概就是无法检测在GuardDist内的范围,但是确认攻击,也当成InGuardDist就行了
Trigger1 = Abs(EnemyNear(var(58)),Pos X - Pos X) = [A,B] ;这里需要自己算,配合空中拳脚立回自己实际测量
Trigger1 = !Enemy,NumProj && (fvar(9) != 0 || var(59) < 10) ;因为出现波可能就晚了,你不知道波是什么样的,所以要赶在没有地波出来之前出跳跃最好,同时也可以排除0帧波什么的恐怖技能,但是已经确认状态,当然也可以加一个低级AI

大概过程就是这样,希望各位能够自己亲身体会

好了,今天的课就先到这,如果您有什么问题的话可以私信我(只要是我会的,不管什么问题),我会第一时间给您答复,或者把问题发到我的邮箱

mizore@kotori.moe, 谢谢大家!
2016.09.0417:39

お知らせ

お久しぶりですね,皆さん今は元気ですか~最近はちょっと忙しいし,オンラインはないし,ごめんなさいね *>.<*

お返事は遅すぎたことはすみません,俺はきっとお返事します(゚∀゚≡゚∀゚)

だからこそ,お返事ない時間のなかで,皆さんもっと試してみてください( ^ω^ )
2016.07.3021:53

AI HELPER-5 当身记忆归类(加强版)

Episode 5 当身记忆归类(加强版)

对于大多数AI作者来言,最困难最头疼的地方就是当身这块了,也就是让人头大的movereversed

为什么呢,它可以制造格挡,也可以制造p2state技能,但是二者共同特点是都有movereversed存在

所以我们记忆的时候要给定一个归类,判断是p2技还是单纯的格挡技(不带p1和p2)

话不多说我们来举例子,准备一个helper,并且准备30个未使用var

;----------------------------------------------------------------------
;自分被ステート奪取記憶 ;10个var来记忆下自己被p2的情况,给定helper的ID比如说是33000+ID
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),StateNo >= 200
TriggerAll = EnemyNear(Root,var(58)),StateType != A
TriggerAll =(Root,StateNo != [120,159]) && (Root,StateNo != [5000,5500]) ;普通受击在5000-5500之间,一般不会超过这里,防御为120-155
TriggerAll = Root,Movetype = H && Root,Time = 1 ;被打的第一时间记下来,如果对面给你的p2不是movetype = H那只好GG
Trigger1 = Helper(33000+Root,ID),var(0) = 0
V = 0
Value = EnemyNear(Root,var(58)),PrevStateNo ;因为你是在被p2时候记录下来的。所以他前一个动作就是给你拉p2的动作
IgnoreHitPause = 1

;下面写法之前提过就不再多讲

[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),StateNo >= 200
TriggerAll = EnemyNear(Root,var(58)),StateType != A
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(0)
TriggerAll =(Root,StateNo != [120,159]) && (Root,StateNo != [5000,5500])
TriggerAll = Root,Movetype = H && Root,Time = 1
Trigger1 = Helper(33000+Root,ID),var(0)!= 0
Trigger1 = Helper(33000+Root,ID),var(1) = 0
V = 1
Value = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1

......................

[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),StateNo >= 200
TriggerAll = EnemyNear(Root,var(58)),StateType != A
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(0)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(1)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(2)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(3)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(4)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(5)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(6)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(7)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(8)
TriggerAll =(Root,StateNo != [120,159]) && (Root,StateNo != [5000,5500])
TriggerAll = Root,Movetype = H && Root,Time = 1
Trigger1 = Helper(33000+Root,ID),var(0)!= 0
Trigger1 = Helper(33000+Root,ID),var(1)!= 0
Trigger1 = Helper(33000+Root,ID),var(2)!= 0
Trigger1 = Helper(33000+Root,ID),var(3)!= 0
Trigger1 = Helper(33000+Root,ID),var(4)!= 0
Trigger1 = Helper(33000+Root,ID),var(5)!= 0
Trigger1 = Helper(33000+Root,ID),var(6)!= 0
Trigger1 = Helper(33000+Root,ID),var(7)!= 0
Trigger1 = Helper(33000+Root,ID),var(8)!= 0
Trigger1 = Helper(33000+Root,ID),var(9) = 0
V = 9
Value = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1 ;这是10个var,记录下来你被p2的情况

下面继续,这10个var在-3里面显示一下标记

;-----------------------------------------------------------------------
; 自分被ステート奪取記憶
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = fvar(5) != 0
FV = 5
Value = 0
IgnoreHitPause = 1

[State -3, 自分被ステート奪取]
Type = Null
TriggerAll = var(59) = 1
TriggerAll = NumHelper(33000+ID)
TriggerAll = EnemyNear(var(58)),Ctrl = 0
TriggerAll = EnemyNear(var(58)),MoveType = A
TriggerAll = EnemyNear(var(58)),StateNo >= 200
TriggerAll = EnemyNear(var(58)),StateType != A ;一般这时候只要记录地面的p2就好了
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(0)
Trigger1 = fvar(5) := fvar(5) + 1 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(1)
Trigger2 = fvar(5) := fvar(5) + 1 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(2)
Trigger3 = fvar(5) := fvar(5) + 1 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(3)
Trigger4 = fvar(5) := fvar(5) + 1 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(4)
Trigger5 = fvar(5) := fvar(5) + 1 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(5)
Trigger6 = fvar(5) := fvar(5) + 1 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(6)
Trigger7 = fvar(5) := fvar(5) + 1 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(7)
Trigger8 = fvar(5) := fvar(5) + 1 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(8)
Trigger9 = fvar(5) := fvar(5) + 1 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(9)
Trigger10 = fvar(5) := fvar(5) + 1 || 1
IgnoreHitPause = 1 ;当检测到p2时候,fvar(5)变为1

接下来就是带p2的当身记忆

;----------------------------------------------------------------------
;敵に当身ステート記憶 Part 1
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,fvar(5) = 1 ;首先检测到对面是带p2的技能
Trigger1 = Root,MoveReversed ;本体触摸当身,有一个前提,必须自己存在hitpausetime,不然没法记下来
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = Helper(33000+Root,ID),var(10) = -1
var(10) = EnemyNear(Root,var(58)),PrevStateNo ;前一个动作确定为当身技能
IgnoreHitPause = 1

..............................

[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,fvar(5) = 1
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(10)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(11)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(12)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(13)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(14)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(15)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(16)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(17)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(18)
Trigger1 = Helper(33000+Root,ID),var(10) != -1
Trigger1 = Helper(33000+Root,ID),var(11) != -1
Trigger1 = Helper(33000+Root,ID),var(12) != -1
Trigger1 = Helper(33000+Root,ID),var(13) != -1
Trigger1 = Helper(33000+Root,ID),var(14) != -1
Trigger1 = Helper(33000+Root,ID),var(15) != -1
Trigger1 = Helper(33000+Root,ID),var(16) != -1
Trigger1 = Helper(33000+Root,ID),var(17) != -1
Trigger1 = Helper(33000+Root,ID),var(18) != -1
Trigger1 = Helper(33000+Root,ID),var(19) = -1
var(19) = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1

这样一来,20个var就能把当身技能记录下来了,但是有个缺点,你第一次吃当身不知道对面是p2,所以得吃两次才能记下来(囧)

然后再说说格挡,比刚才简单很多,但同时也有些不足的地方

;----------------------------------------------------------------------
;敵に当身ステート記憶 Part 2
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = Helper(33000+Root,ID),var(20) = -1
var(20) = EnemyNear(Root,var(58)),StateNo ;原理同上,但是这里记下来的是当前stateno,有两种情况,1个是p2stateno,另一个就是格挡技能,不拉P1也不拉P2
IgnoreHitPause = 1

......................................

[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(20)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(21)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(22)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(23)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(24)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(25)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(26)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(27)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(28)
Trigger1 = Helper(33000+Root,ID),var(20) != -1
Trigger1 = Helper(33000+Root,ID),var(21) != -1
Trigger1 = Helper(33000+Root,ID),var(22) != -1
Trigger1 = Helper(33000+Root,ID),var(23) != -1
Trigger1 = Helper(33000+Root,ID),var(24) != -1
Trigger1 = Helper(33000+Root,ID),var(25) != -1
Trigger1 = Helper(33000+Root,ID),var(26) != -1
Trigger1 = Helper(33000+Root,ID),var(27) != -1
Trigger1 = Helper(33000+Root,ID),var(28) != -1
Trigger1 = Helper(33000+Root,ID),var(29) = -1
var(29) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

这里的缺陷,就是会把p2技和格挡技记录在一块,但是要明白一点,你被拉P2的时候是肯定不能动的,所以剩下来的就是格挡技了

然后把两个当身技能归类在var里面

;-----------------------------------------------------------------------
; 相手の特殊ステート(当身)記憶
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = fvar(2) != 0
FV = 2
Value = 0
IgnoreHitPause = 1

[State -3, 相手の特殊ステート]
Type = Null
TriggerAll = var(59) = 1
TriggerAll = NumHelper(33000+ID)
TriggerAll = EnemyNear(var(58)),MoveType = A
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(10)
Trigger1 = fvar(2) := fvar(2) + 1 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(11)
Trigger2 = fvar(2) := fvar(2) + 1 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(12)
Trigger3 = fvar(2) := fvar(2) + 1 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(13)
Trigger4 = fvar(2) := fvar(2) + 1 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(14)
Trigger5 = fvar(2) := fvar(2) + 1 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(15)
Trigger6 = fvar(2) := fvar(2) + 1 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(16)
Trigger7 = fvar(2) := fvar(2) + 1 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(17)
Trigger8 = fvar(2) := fvar(2) + 1 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(18)
Trigger9 = fvar(2) := fvar(2) + 1 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(19)
Trigger10 = fvar(2) := fvar(2) + 1 || 1
Trigger11 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(20)
Trigger11 = fvar(2) := fvar(2) + 2 || 1
Trigger12 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(21)
Trigger12 = fvar(2) := fvar(2) + 2 || 1
Trigger13 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(22)
Trigger13 = fvar(2) := fvar(2) + 2 || 1
Trigger14 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(23)
Trigger14 = fvar(2) := fvar(2) + 2 || 1
Trigger15 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(24)
Trigger15 = fvar(2) := fvar(2) + 2 || 1
Trigger16 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(25)
Trigger16 = fvar(2) := fvar(2) + 2 || 1
Trigger17 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(26)
Trigger17 = fvar(2) := fvar(2) + 2 || 1
Trigger18 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(27)
Trigger18 = fvar(2) := fvar(2) + 2 || 1
Trigger19 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(28)
Trigger19 = fvar(2) := fvar(2) + 2 || 1
Trigger20 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(29)
Trigger20 = fvar(2) := fvar(2) + 2 || 1
IgnoreHitPause = 1

这里就很明确了,fvar(2) = 1时代表带P2的当身技,fvar(2) = 2时代表格挡技和已被拉的p2state,当然被拉的p2state以外的就是格挡技了

然后接下来的AI怎么写,如果对面出当身带P2技能,你已经记下来知道了,那么不在版边你可以选择后跳和44,然后如果你被卡版边了,你可以选择闪身或者大跳(千万别手贱点嘲讽不然会死得很惨- -+),但是格挡技能因为不确定是升龙还是单纯的格挡,所以闪身和防御是最好的选择,然后剩下来的你只要抓最后几帧硬直就可以了(EnemyNear(var(58)),AnimTime = -X,X为某招触发判定帧数)

好了,今天的课就先到这,如果您有什么问题的话可以私信我(只要是我会的,不管什么问题),我会第一时间给您答复,或者把问题发到我的邮箱

mizore@kotori.moe, 谢谢大家!
2016.06.2309:55

AI 双打部分浅谈

Episode 9 双打部分浅谈

一个比较完整的AI,是要包含双打部分的,里面的概念其实很好理解,队友被打了你看情况去救队友,其中比较远程的话可以大跳或者突进过去救,如果你有飞行道具就出飞行道具技能去救队友,再比如还有队友在打对面两个对手的时候,你去补刀,队友把两个敌人拉了个P2,你可以做一个蓄气的动作来给己方攒气,或者你也可以装逼出个嘲讽啥的,反正用法很多,自己按照实际来理解

下面切入正题,今天用到两个var来记录全部双打情况,var(51)和var(52),如果被占用了就换别的

;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
; タッグ用 ;TAG(双打模式)下使用
;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[State -3, 敵が1人] ;对手只有1个人的情况,有两种情况,对手有队友但是队友死了,也可能是本来就1个人
Type = VarSet
Trigger1 = NumEnemy != 2
Trigger2 = !(EnemyNear(0),Alive && EnemyNear(1),Alive)
V = 51
Value = 0

[State -3, 敵が2人かつ前方のみ] ;两个敌人都在你面前的情况
Type = VarSet
TriggerAll = NumEnemy = 2
TriggerAll = EnemyNear(0),Alive
TriggerAll = EnemyNear(1),Alive
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Pos X > 0,EnemyNear(0),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Pos X > 0,EnemyNear(1),Pos X - Pos X < 0)
V = 51
Value = 1

[State -3, 自分、パートナー、敵、敵] ;场上4人分布情况从左到右:自己,队友,两位敌人
Type = VarSet
TriggerAll = NumEnemy = 2
TriggerAll = NumPartner
TriggerAll = EnemyNear(0),Alive
TriggerAll = EnemyNear(1),Alive
TriggerAll = Partner,Alive
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Pos X > 0,EnemyNear(0),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Pos X > 0,EnemyNear(1),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Partner,Pos X > 0,EnemyNear(0),Pos X - Partner,Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Partner,Pos X > 0,EnemyNear(1),Pos X - Partner,Pos X < 0)
V = 51
Value = 2

[State -3, 自分、敵、パートナー、敵] ;分布情况:自己,敌人,队友,敌人,此时队友可能有危险,因为队友被两个敌人夹住了
Type = VarSet
TriggerAll = NumEnemy = 2
TriggerAll = NumPartner
TriggerAll = EnemyNear(0),Alive
TriggerAll = EnemyNear(1),Alive
TriggerAll = Partner,Alive
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Pos X > 0,EnemyNear(0),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Pos X > 0,EnemyNear(1),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Partner,Pos X < 0,EnemyNear(0),Pos X - Partner,Pos X > 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Partner,Pos X > 0,EnemyNear(1),Pos X - Partner,Pos X < 0)
V = 51
Value = 3

[State -3, 自分、敵、敵、パートナー] ;分布情况:自己,两位敌人,队友,此时为优势
Type = VarSet
TriggerAll = NumEnemy = 2
TriggerAll = NumPartner
TriggerAll = EnemyNear(0),Alive
TriggerAll = EnemyNear(1),Alive
TriggerAll = Partner,Alive
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Pos X > 0,EnemyNear(0),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Pos X > 0,EnemyNear(1),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Partner,Pos X < 0,EnemyNear(0),Pos X - Partner,Pos X > 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Partner,Pos X < 0,EnemyNear(1),Pos X - Partner,Pos X > 0)
V = 51
Value = 4

[State -3, 背後に敵有り] ;这个就比较尴尬了,背后有敌人的情况,通常背后有敌人的情况就代表你前面还有一个敌人,也就是说你被两位敌人卡住了(苦笑)
Type = VarSet
TriggerAll = NumEnemy = 2
TriggerAll = EnemyNear(0),Alive
TriggerAll = EnemyNear(1),Alive
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Pos X < 0,EnemyNear(0),Pos X - Pos X > 0)
Trigger2 = ifelse(Facing = 1,EnemyNear(1),Pos X - Pos X < 0,EnemyNear(1),Pos X - Pos X > 0)
V = 51
Value = 5

;---------------------------------------------------------------------------
[State -3, パートナー不在] ;双打模式,但是队友不在或者队友已经死亡
Type = VarSet
TriggerAll = TeamMode = Simul
Trigger1 = !NumPartner
Trigger2 = !Partner,Alive
V = 52
Value = 0

[State -3, パートナー後衛] ;双打模式下队友在你后面当后卫
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
Trigger1 = ifelse(Facing = 1,Partner,Pos X - Pos X < 0,Partner,Pos X - Pos X > 0)
V = 52
Value = 1

[State -3, パートナー前衛] ;双打模式队友给你当前锋
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
Trigger1 = ifelse(Facing = 1,Partner,Pos X - Pos X > 0,Partner,Pos X - Pos X < 0)
V = 52
Value = 2

[State -3, パートナー被ダメージ] ;双打模式下队友被打,而且这里代表的是普通的被打或者被打防御的状态,可以救
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
TriggerAll = Partner,MoveType = H
TriggerAll = ifelse(Facing = 1,Partner,Pos X - Pos X > 0,Partner,Pos X - Pos X < 0)
Trigger1 = Partner,StateNo = [5000,5100)
Trigger2 = Partner,StateNo = [120,159]
V = 52
Value = 3

[State -3, パートナー攻撃中] ;队友在打敌人的情况,近敌显示被打
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
TriggerAll = Partner,MoveType = A
TriggerAll = Partner,MoveType != H
TriggerAll = EnemyNear(var(58)),MoveType = H
TriggerAll = ifelse(Facing = 1,Partner,Pos X - Pos X > 0,Partner,Pos X - Pos X < 0)
Trigger1 = EnemyNear(var(58)),StateNo = [5000,5100)
V = 52
Value = 4

[State -3, パートナー被ステート奪取] ;这个比较危险,因为是队友被抓了个P2,这个时候如果你有波的话就发波吧,最好别靠近对手,说不定你也会被卷进去
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
TriggerAll = Partner,MoveType = H
TriggerAll = ifelse(Facing = 1,Partner,Pos X - Pos X > 0,Partner,Pos X - Pos X < 0)
Trigger1 = Partner,StateNo != [5000,5500]
Trigger1 = Partner,StateNo != [120,159]
V = 52
Value = 5

[State -3, パートナーステート奪取] ;队友给别人拉了个P2,此时为近敌被拉P2的状态
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
TriggerAll =(Partner,StateNo = [2000,4999]) || Partner,StateNo > 5500
Trigger1 = EnemyNear(var(58)),MoveType = H
Trigger1 = EnemyNear(var(58)),StateNo != [5000,5500]
Trigger1 = EnemyNear(var(58)),StateNo != [120,159]
V = 52
Value = 6

好了先记下来这么多,接下来要怎么用呢

举个例子:比如说你要装逼对吧,我们就说195,挑衅这个动作,什么时候用呢?

考虑下情况,肯定是两个对手都被打,而且都被拉了P2,首先要考虑到的肯定是var(52) = 6的情况

;装逼装逼装逼
[State -3, Taunt]
Type = ChangeState
Value = 195
TriggerAll = var(59) = 1
TriggerAll = StateNo != 195 && PrevStateNo != 195 ;因为有些人195是带ctrlset的,而且不要和前一个动作重复
TriggerAll = RoundState = 2 && EnemyNear(var(58)),Life > 0
TriggerAll = Random <= 150 ;概率你可以自己定,这里是15%概率装个逼
TriggerAll = StateType != A
TriggerAll =!Enemy,NumProj ;对面没有飞行道具
TriggerAll =!InGuardDist && !Helper(31000+ID),InGuardDist ;确保是InGuarddist
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = var(52) = 6 && var(51) < 5 ;确定对手是被P2了而且不能被两位队友夹住
Trigger1 = EnemyNear(0),MoveType = H && (EnemyNear(0),StateNo != [120,159]) && (EnemyNear(0),StateNo != [5000,5100))
Trigger1 = EnemyNear(1),MoveType = H && (EnemyNear(1),StateNo != [120,159]) && (EnemyNear(1),StateNo != [5000,5100)) ;上面的2行,因为要同时确保两位敌人同时被打,近敌和远敌,分别代表0,1
Trigger1 = Abs(EnemyNear(var(58)),Pos X - Pos X) > 120; (大概距离可以自己定,Abs(EnemyNear(var(58)),Pos X - Pos X)与P2BodyDist X的换算标准是前者比后者大32)

除了装逼之外,你有可以帮助对手的东西也可以用,比如蓄气,这个换个状态号就行了,不多讲

不要成天只知道装逼,学着点去救队友和自救

先说,比如发个波去辅助队友,或者去营救

;地波
[State -3, Proj]
Type = ChangeState
Value = (地波状态号,如果你有强弱地波的话按照距离选择强弱,远了就强,稍微近一点就弱)
TriggerAll = var(59) = 1
TriggerAll = var(52) = [2,3] ; var(52) = 2代表队友给你当前锋,3代表队友在被普通的攻击
TriggerAll = var(51) < 5 ;首先要确保自己的安全,不能被夹住
TriggerAll = RoundState = 2 && EnemyNear(var(58)),life > 0
TriggerAll = Random <= 100 ;10%概率,自己可以改
TriggerAll = StateType != A
TriggerAll = NumProjID(1000) = 0
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = P2BodyDist X >= 200 ;多远出,自己算好距离

还有一点,就是你被两位对手夹住了怎么办,如果有闪避或者AB之类的技能赶紧闪出去,因为对你来说是大劣势,以AB为例
,尽量以耗气后AB或者无敌闪避技能为主,比如原版KOF的后AB是有挺大责任的,但耗1气防御下AB就是无敌的话,那么

[State -3, 後転]
Type = ChangeState
Value = (后AB状态)
TriggerAll = var(59) = 1
TriggerAll = var(51) = 5 && (var(52) > 0 || Power >= 1000) ;你队友在的时候或者有气就AB出去,没有的话你就认命吧
TriggerAll = RoundState = 2
TriggerAll = StateType != A
Trigger1 = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = Abs(EnemyNear(var(58)),Pos X - Pos X) <= 100 ;保持一定距离
Trigger1 = EnemyNear(var(58)),StateNo >= 1000 && !EnemyNear(var(58)),Ctrl ;对手攻击状态,通常1000以上为必杀,趁这个时候赶紧跑掉
Trigger1 = var(52) = 5 && BackEdgeBodyDist >= 40 (你和队友都被夹了,此时队友被P2了,你赶紧跑远了,别卖了自己)
Trigger2 = StateNo = 150 || StateNo = 152 ;消耗1气赶紧跑出去,不要管太多
Trigger2 = Power >= 1000 && var(42) >= 120 && BackEdgeBodyDist >= 20 ;自己背离墙角有一段距离
Trigger2 = ifelse(Facing = 1,(EnemyNear(0),Pos X - Pos X = [-100,0]),(EnemyNear(0),Pos X - Pos X = [0,100])) ;记得算好距离,facing = 1表示脸朝右边看,-1表示脸朝左边
Trigger2 = EnemyNear(0),BackEdgeBodyDist >= 40 ;敌人背离墙角有一段距离,不然你AB出不去的,AB完了还是被卡住
Trigger2 = EnemyNear(0),Facing = Facing ;背对敌人
Trigger3 = StateNo = 150 || StateNo = 152 ;同上面的道理
Trigger3 = Power >= 1000 && var(42) >= 120 && BackEdgeBodyDist >= 20
Trigger3 = ifelse(Facing = 1,(EnemyNear(1),Pos X - Pos X = [-100,0]),(EnemyNear(1),Pos X - Pos X = [0,100]))
Trigger3 = EnemyNear(1),BackEdgeBodyDist >= 40
Trigger3 = EnemyNear(1),Facing = Facing

这里提一下,enemynear,或者你用enemynear(var())这种的,只能指定近敌的动作,而不能代表2位敌人,所以判断2位敌人要用到enemynear(0)和enemynear(1),0代表近的那位,1代表远的那位

除了这些外,双打的想法还有很多的,比如创造人工墙角,可以配合相应的队友做出相应的反应,比如你知道你指定的队友哪个动作做出来了,比如知道是可以追打的P2StateNo,而且两位敌人同时被打,赶紧大跳或者闪避到对手后面去用2A点对面,总之好墙角自己造嘛蛤蛤蛤

好了,今天的课就先到这,如果您有什么问题的话可以私信我,我会第一时间给您答复,或者把问题发到我的邮箱

mizore@kotori.moe, 谢谢大家!

アクセス

オンライン