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.04.2415:24

AI HELPER-4 重力加速度计算(加强版)

Episode 4 重力加速度计算(加强版)

找到一个比较空闲的Helper,确定这个helper是常时存在的,并且至少有3个fvar可以使用

加入下面的代码(加在helper里面),如果变量有冲突那就换,下面的也一样

;-----------------------------------------------------------------------
;重力加速度 常時読み取り
;-----------------------------------------------------------------------
[State -3, 重力加速度]
Type = Null
Trigger1 = fvar(3):= 0 || 1
Trigger1 = fvar(3):=(((EnemyNear(Root,var(58)),Anim != [5051,5059])&&(EnemyNear(Root,var(58)),Anim != [5061,5069]))&&(EnemyNear(Root,var(58)),StateNo = 5050))*25 || 1 ;这个参考Statedef 5050里面的数据(被打下落,hitfall)
Trigger1 = fvar(0):= Ceil((EnemyNear(Root,var(58)),Pos Y - fvar(2) - fvar(1))*1000.0)*(EnemyNear(Root,var(58)),Pos Y < fvar(3))/1000.0 || 1 ;fvar(0)为第一次pos y记录,fvar(1)为第二次,fvar(2)为第三次
Trigger1 = fvar(1):= EnemyNear(Root,var(58)),Pos Y - fvar(2) || 1
Trigger1 = fvar(2):= EnemyNear(Root,var(58)),Pos Y || 1
ignorehitpause = 1

原理的话是这样,因为敌方pos y为变化值,fvar(0)先记下来第一次pos y,fvar(1)记下来第二次,fvar(2)记下来第三次

第一次的值减去第三次的值在减去第二次和第三次这两次的变化的值即为最终答案

下面给出用法,这个写在Statedef -2里面

;-----------------------------------------------------------------------------
; AI用重力加速度計測
;-----------------------------------------------------------------------------
[State -2, yaccel]
Type = VarSet
TriggerAll = NumHelper(AAA) ;AAA为helper的ID
TriggerAll = EnemyNear(var(58)),Vel Y != 0
TriggerAll = EnemyNear(var(58)),Pos Y < (((EnemyNear(var(58)),Anim != [5051,5059]) && (EnemyNear(var(58)),Anim != [5061,5069])) && (EnemyNear(var(58)),StateNo = 5050))*25 ;参考Statedef 5050
TriggerAll = fvar(20) != Helper(AAA),fvar(0)
Trigger1 = EnemyNear(var(58)),StateNo != [5000,5210]
Trigger2 = EnemyNear(var(58)),MoveType != H
FV = 20
Value = Helper(AAA),fvar(0);(通常時のyaccel値) ;通常的yaccel由helper内计算值取代
IgnoreHitPause = 1

[State -2, yaccel]
Type = VarSet
TriggerAll = EnemyNear(var(58)),Vel Y != 0
TriggerAll = EnemyNear(var(58)),MoveType = H
TriggerAll = EnemyNear(var(58)),Pos Y < (((EnemyNear(var(58)),Anim != [5051,5059]) && (EnemyNear(var(58)),Anim != [5061,5069])) && (EnemyNear(var(58)),StateNo = 5050))*25 ;参考Statedef 5050
TriggerAll = fvar(20) != EnemyNear(var(58)),GetHitVar(yaccel)
Trigger1 = EnemyNear(var(58)),StateNo = [5000,5210]
FV = 20
Value = EnemyNear(var(58)),GetHitVar(yaccel);(打撃当てた時のyaccel値) ;敌方被打的yaccel
IgnoreHitPause = 1

;敵が空中じゃない時
[State -2, yaccel]
Type = VarSet
Trigger1 = fvar(20) != 0 && EnemyNear(var(58)),Vel Y = 0
FV = 20
Value = 0;(打撃当てた時のyaccel値)
IgnoreHitPause = 1

然后用DisplayToClipBoard查看fvar(20)的变化即可,大家不妨去试试看,然后理解下

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

mizore@kotori.moe, 谢谢大家!
2016.03.1712:32

AI HELPER-3 AI HELPER记忆器的制作

Episode 3 AI HELPER记忆器的制作

记忆器的话,写法是可以通用的,因为都是记招,因为HELPER能记下来的也不是万能的,所以也要配合AI里面的条件使用

举个例子,先说基本部分

;----------------------------------------------------------------------
[Statedef 36000]
anim = 9999
ctrl = 0

[State 36000, AssertSpecial]
Type = AssertSpecial
Trigger1 = 1
flag = invisible

[State 36000, BindToRoot]
type = BindToRoot
trigger1 = 1
facing = 1
pos = 0,0

[State 36000, NotHitBy]
Type = NotHitBy
Trigger1 = 1
Value = SCA

[State 36000, PlayerPush]
type = PlayerPush
trigger1 = 1
value = 0

[State 36000, SelfState]
Type = SelfState
Trigger1 = !IsHelper
Value = 0

[State 36000, AssertSpecial]
type = AssertSpecial
Trigger1 = 1
flag = NoShadow
flag2 = invisible

以上是基本部分,anim = 9999是一个空动画,前面提到过,不再讲

比如我现在记录下对手出招状态和判定触发时间,我可以这么写

;----------------------------------------------------------------------
[State 36000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0 ;对手不可控
TriggerAll = EnemyNear(Root,var(58)),MoveType = A ;对手攻击状态
TriggerAll = EnemyNear(Root,var(58)),HitDefAttr = SCA,NA,SA ;一般记下来普攻和必杀技攻击就可以,虽然说下面的状态有限制
TriggerAll = EnemyNear(Root,var(58)),StateNo = [200,499] ;200-499一般是地面拳脚,概率比较大
TriggerAll = Root,StateNo = 150 || Root,StateNo = 152 ;防御硬直中触发
TriggerAll = Root,Time = 1 ;硬直中第一帧记下来,防出错
Trigger1 = var(1) = 0 ;未记录情况
V = 1
Value = (EnemyNear(Root,var(58)),StateNo) ;记下对面状态号
IgnoreHitPause = 1

[State 36000, VarSet]
Type = VarSet
Trigger1 = var(1)!= 0 ;对面状态号有
Trigger1 = var(2) = 0 ;时间还未记下来
V = 2
Value = (EnemyNear(Root,var(58)),Time) ;记录下敌方经过时间
IgnoreHitPause = 1

一个招记下来了,接下来记第二个

[State 36000, VarSet]
Type = VarSet
TriggerAll = var(1) > 0 ;有第一招的记录
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),HitDefAttr = SCA,NA,SA
TriggerAll = EnemyNear(Root,var(58)),StateNo = [200,499]
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(1) ;不能和第一个冲突
TriggerAll = Root,StateNo = 150 || Root,StateNo = 152
TriggerAll = Root,Time = 1
Trigger1 = var(3) = 0
V = 3
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 36000, VarSet]
Type = VarSet
TriggerAll = var(2) ;第一个时间记下来了
Trigger1 = var(3)!= 0 ;有第二招的记录
Trigger1 = var(4) = 0
V = 4
Value = (EnemyNear(Root,var(58)),Time) ;记录下第二招时间
IgnoreHitPause = 1

然后一直记到10个招
............

[State 36000, VarSet]
Type = VarSet
TriggerAll = var(17) > 0
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),HitDefAttr = SCA,NA,SA
TriggerAll = EnemyNear(Root,var(58)),StateNo = [200,499]
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(1)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(3)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(5)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(7)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(9)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(11)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(13)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(15)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(17)
TriggerAll = Root,StateNo = 150 || Root,StateNo = 152
TriggerAll = Root,Time = 1
Trigger1 = var(19) = 0
V = 19
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 36000, VarSet]
Type = VarSet
TriggerAll = var(18)
Trigger1 = var(19)!= 0
Trigger1 = var(20) = 0
V = 20
Value = (EnemyNear(Root,var(58)),Time)
IgnoreHitPause = 1

这个就是记录下敌方出招和时间的方法

除此之外,还可以记录下别的东西,用敌方飞行道具为例子来举个例子

;----------------------------------------------------------------------
[State 36000, 1] ;第一个状态
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),NumProj = 1 ;一般是地波和中段波之类的,出大跳的话可以大跳躲过去抓硬直
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = var(1) = 0
var(1) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

[State 36000, 2] ;第二个
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)),StateNo != var(1)
Trigger1 = var(1) != 0
Trigger1 = var(2) = 0
var(2) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

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

[State 36000, 10] ;第十个
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)),StateNo != var(1)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(2)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(3)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(4)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(5)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(6)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(7)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(8)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(9)
Trigger1 = var(1) != 0
Trigger1 = var(2) != 0
Trigger1 = var(3) != 0
Trigger1 = var(4) != 0
Trigger1 = var(5) != 0
Trigger1 = var(6) != 0
Trigger1 = var(7) != 0
Trigger1 = var(8) != 0
Trigger1 = var(9) != 0
Trigger1 = var(10) = 0
var(10) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

这样十个招都记下来了

接下来我们来用DISPLAYTOCLIPBOARD代码来观察下面的DEBUG信息

;---------------------------------------------------------------------------
[State 36000, DisplayToClipBoard]
Type = DisplayToClipBoard
Trigger1 = IsHelper(36000) ;确认是helper并且helper的ID是36000,载入的时候记得,stateno = 36000, ID = 36000
Text = "var(1)=%d,var(2)=%d,var(3)=%d,var(4)=%d,var(5)=%d"
Params = var(1),var(2),var(3),var(4),var(5)
IgnoreHitPause = 1

[State 36000, AppendToClipboard]
Type = AppendToClipboard
Trigger1 = IsHelper(36000) ;补充段,当然,不管是记录飞行道具状态号还是记录出招状态号和时间,想观察哪个就可以改成哪个
Text = "\nvar(6)=%d,var(7)=%d,var(8)=%d,var(9=%d,var(10)=%d"
Params = var(6),var(7),var(8),var(9),var(10)
IgnoreHitPause = 1

记忆器使用其实还是挺简单的吧,实战中最好用能用到的记忆,缺哪个就补哪个

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

mizore@kotori.moe, 谢谢大家!
2016.03.1321:26

AI HELPER-2.5 防御段位被破的记忆(进阶)

Episode 2.5 防御段位被破的记忆(进阶)

在读此文章之前先把上一篇认真读完并看懂大概意思

接下来先放出改进后的HELPER

;------------------------------------------------------------------------------
;ガードチェックヘルパー
;------------------------------------------------------------------------------
[Statedef 31000]
type = A
movetype = I
physics = N
anim = 0
velset = 0,0
sprpriority = 1
ctrl = 0

[State 31000, AssertSpecial]
type = AssertSpecial
Trigger1 = 1
flag = NoShadow
flag2 = invisible

[State 31000, NotHitBy]
type = NotHitBy
trigger1 = 1
value = SCA

[State 31000, PlayerPush]
type = PlayerPush
trigger1 = 1
value = 0

[State 31000, 間違いで本体が来たら立ちへ移行]
type = SelfState
trigger1 =!ishelper
value = 0

[State -3, 目の前の敵が一番近い相手である]
type = VarSet
triggerall = roundstate = 2
trigger1 = numenemy <= 1
trigger2 = numenemy >= 2
trigger2 = enemy(0),life <= 0 || enemy(1),life <= 0
trigger2 = enemynear(0),life > 0
trigger3 = numenemy >= 2
trigger3 = enemy(0),life > 0 && enemy(1),life > 0
trigger3 = abs(root,pos x - enemynear(0),pos x) <= abs(root,pos x - enemynear(1),pos x)
var(1) = 0
IgnoreHitPause = 1

[State -3, 目の前の敵が一番近い相手ではない]
type = VarSet
triggerall = roundstate = 2
triggerall = numenemy >= 2
trigger1 = enemynear(0),life <= 0
trigger2 = numenemy >= 2
trigger2 = enemy(0),life <= 0 || enemy(1),life <= 0
trigger2 = enemynear(0),life <= 0
trigger3 = enemy(0),life > 0 && enemy(1),life > 0
trigger3 = abs(root,pos x - enemynear(0),pos x) > abs(root,pos x - enemynear(1),pos x)
var(1) = 1
IgnoreHitPause = 1

;自分の後ろに設置 ――――――――――――――――――――――――――――――――――――――――
[State 31000, Turn]
type = Turn
trigger1 = facing*ifelse((enemynear(var(1)),pos x-pos x)>=0,1,-1) < 0
IgnoreHitPause = 1
supermovetime = 9999
pausemovetime = 9999

[State 31000, VarSet]
type = VarSet
trigger1 = enemynear(var(1)),facing*ifelse((enemynear(var(1)),pos x-root,pos x)>=0,1,-1)<=0
trigger2 = !enemynear(var(1)),hitdefattr = A,NA,SA,HA
var(2) = 0
IgnoreHitPause = 1
supermovetime = 9999
pausemovetime = 9999

[State 31000, VarSet]
type = VarSet
trigger1 = enemynear(var(1)),facing*ifelse((EnemyNear(var(1)),pos x-root,pos x)>=0,1,-1)>0
trigger1 = enemynear(var(1)),hitdefattr = A,NA,SA,HA
var(2) = 1
IgnoreHitPause = 1
supermovetime = 9999
pausemovetime = 9999

[State 31000, PosSet]
type = PosSet
trigger1 = 1
x = root,pos x+ifelse((enemynear(var(1)),pos y<0&&var(2)=1),(enemynear(var(1)),const(size.attack.dist)),(enemynear(var(1)),const(size.proj.attack.dist)))*(enemynear(var(1)),facing)
IgnoreHitPause = 1
supermovetime = 9999
pausemovetime = 9999

;---------------------------------------------------------------------------
[State 31000, リセット]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,StateNo != [120,155]
Trigger1 = Root,MoveType!= H
Trigger1 = Root,Ctrl = 1 && var(50) > 0
Trigger2 = Root,MoveType = H
Trigger2 = Root,Time > 1 && var(50) > 0
var(50) = 0
IgnoreHitPause = 1

;分别记下来防御中站立,蹲下,空中(可有可无)情况

[State 31000, 立ちガード時学習用]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,StateNo = [120,155]
Trigger1 = Root,StateType = S
var(50) = 1
IgnoreHitPause = 1

[State 31000, 下段ガード時学習用]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,StateNo = [120,155]
Trigger1 = Root,StateType = C
var(50) = 2
IgnoreHitPause = 1

[State 31000, 空中ガード時学習用]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,StateNo = [120,155]
Trigger1 = Root,StateType = A
var(50) = 3
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, リセット]
Type = VarSet
Trigger1 = 1
var(51) = 0
IgnoreHitPause = 1

[State 31000, 特殊状態記憶] ;重点在这里,记录下本体被打并且不是站立也不是蹲下的情况
Type = VarSet
TriggerAll = Root,var(59) = 1
Trigger1 = Root,MoveType = H && Root,StateType != S && Root,StateType != C && (Root,StateNo != [120,155])
var(51) = 1
IgnoreHitPause = 1

;---------------------------------------------------------------------------
;ガード学習
;---------------------------------------------------------------------------
[State 31000, 中段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1 ;这里记录下特殊情况,下面也是一样
TriggerAll = EnemyNear(Root,var(58)),StateType != A && (Root,StateType = C || var(50) = 2)
Trigger1 = var(10) = 0
V = 10
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 中段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != A && (Root,StateType = C || var(50) = 2)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(10)
Trigger1 = var(10) > 0
Trigger1 = var(11) = 0
V = 11
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 中段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != A && (Root,StateType = C || var(50) = 2)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(10)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(11)
Trigger1 = var(11) > 0
Trigger1 = var(12) = 0
V = 12
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 中段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != A && (Root,StateType = C || var(50) = 2)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(10)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(11)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(12)
Trigger1 = var(12) > 0
Trigger1 = var(13) = 0
V = 13
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 中段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != A && (Root,StateType = C || var(50) = 2)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(10)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(11)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(12)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(13)
Trigger1 = var(13) > 0
Trigger1 = var(14) = 0
V = 14
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, 下段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != C && (Root,StateType = S || var(50) = 1)
Trigger1 = var(20) = 0
V = 20
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 下段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != C && (Root,StateType = S || var(50) = 1)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(20)
Trigger1 = var(20) > 0
Trigger1 = var(21) = 0
V = 21
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 下段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != C && (Root,StateType = S || var(50) = 1)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(20)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(21)
Trigger1 = var(21) > 0
Trigger1 = var(22) = 0
V = 22
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 下段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != C && (Root,StateType = S || var(50) = 1)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(20)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(21)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(22)
Trigger1 = var(22) > 0
Trigger1 = var(23) = 0
V = 23
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 下段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != C && (Root,StateType = S || var(50) = 1)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(20)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(21)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(22)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(23)
Trigger1 = var(23) > 0
Trigger1 = var(24) = 0
V = 24
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, 中段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != A && (Root,StateType = S || var(50) = 1)
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(10)
Trigger1 = var(10) > 0
V = 10
Value = 0
IgnoreHitPause = 1

[State 31000, 中段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != A && (Root,StateType = S || var(50) = 1)
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(11)
Trigger1 = var(11) > 0
V = 11
Value = 0
IgnoreHitPause = 1

[State 31000, 中段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != A && (Root,StateType = S || var(50) = 1)
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(12)
Trigger1 = var(12) > 0
V = 12
Value = 0
IgnoreHitPause = 1

[State 31000, 中段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != A && (Root,StateType = S || var(50) = 1)
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(13)
Trigger1 = var(13) > 0
V = 13
Value = 0
IgnoreHitPause = 1

[State 31000, 中段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != A && (Root,StateType = S || var(50) = 1)
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(14)
Trigger1 = var(14) > 0
V = 14
Value = 0
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, 下段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != C && (Root,StateType = C || var(50) = 2)
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(20)
Trigger1 = var(20) > 0
V = 20
Value = 0
IgnoreHitPause = 1

[State 31000, 下段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != C && (Root,StateType = C || var(50) = 2)
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(21)
Trigger1 = var(21) > 0
V = 21
Value = 0
IgnoreHitPause = 1

[State 31000, 下段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != C && (Root,StateType = C || var(50) = 2)
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(22)
Trigger1 = var(22) > 0
V = 22
Value = 0
IgnoreHitPause = 1

[State 31000, 下段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != C && (Root,StateType = C || var(50) = 2)
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(23)
Trigger1 = var(23) > 0
V = 23
Value = 0
IgnoreHitPause = 1

[State 31000, 下段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) || Root,StateNo >= 200 && var(51) = 1
TriggerAll = EnemyNear(Root,var(58)),StateType != C && (Root,StateType = C || var(50) = 2)
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(24)
Trigger1 = var(24) > 0
V = 24
Value = 0
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, DisplayToClipBoard]
Type = DisplayToClipBoard
trigger1 = IsHelper
Text = "var(10)=%d,var(11)=%d,var(12)=%d,var(13)=%d,var(14)=%d"
Params = var(10),var(11),var(12),var(13),var(14)
IgnoreHitPause = 1

[State 31000, AppendToClipboard]
type = AppendToClipboard
trigger1 = IsHelper
text = "\nvar(20)=%d,var(21)=%d,var(22)=%d,var(23)=%d,var(24)=%d"
params = var(20),var(21),var(22),var(23),var(24)
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, DestroySelf]
type = DestroySelf
triggerall = ishelper
triggerall = roundstate >= 3
trigger1 = root,stateno != [120,159]
trigger2 = roundstate >= 4

和前面一样,就是多加了两个var,记下来root,statetype情况和本体被击飞或者被强制倒地的情况

因为本来上节课那么写的是不能记下来被击飞或者强制倒地的情况的,只能记录root,statetype = S或者root,statetype = C的情况

下面来给出示例图,可以放大图片看下面的DEBUG数据

这是未记录任何被破情况
这个是未记录任何被破情况

此时下段被破了,记录下下段
此时下段被破了,记录下下段StateNo

下次就不会再吃了
那么下次就不会再吃了

中段
中段技也一样,先是被打了

下次也不会再吃了
同理,下次也不会再吃了


所以这次呢,不妨大家试用一下我改进以后的防御记忆HELPER

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

mizore@kotori.moe, 谢谢大家!
2016.03.1212:53

AI HELPER-2,防御段位被破的记忆

Episode 2 防御段位被破的记忆

这次算是给前面的防御段位切换的AI进行补充了

我们之前说过,防御分站防,蹲防,空防,空防因为不会有段位变化姑且不谈,AI的难题之一就是地面上的防御段位切换

下面给出一个防御记忆HELPER

;------------------------------------------------------------------------------
;ガードチェックヘルパー
;------------------------------------------------------------------------------
[Statedef 31000]
type = A
movetype = I
physics = N
anim = 0
velset = 0,0
sprpriority = 1
ctrl = 0

[State 31000, AssertSpecial]
type = AssertSpecial
Trigger1 = 1
flag = NoShadow
flag2 = invisible

[State 31000, NotHitBy]
type = NotHitBy
trigger1 = 1
value = SCA

[State 31000, PlayerPush]
type = PlayerPush
trigger1 = 1
value = 0

[State 31000, 間違いで本体が来たら立ちへ移行]
type = SelfState
trigger1 =!ishelper
value = 0

;------------------------从这边以上都是基础部分就不讲了

[State -3, 目の前の敵が一番近い相手である] ;记录下有近敌,作用相当于TAG
type = VarSet
triggerall = roundstate = 2 ;比赛中
trigger1 = numenemy <= 1 ;敌人只有1个或者没有
trigger2 = numenemy >= 2 ;敌人两个或者更多
trigger2 = enemy(0),life <= 0 || enemy(1),life <= 0 ;近敌或者远敌死亡
trigger2 = enemynear(0),life > 0 ;近敌存活,此时可以记住这个是近敌
trigger3 = numenemy >= 2 ;两个或者以上的敌人
trigger3 = enemy(0),life > 0 && enemy(1),life > 0 ;都存活
trigger3 = abs(root,pos x - enemynear(0),pos x) <= abs(root,pos x - enemynear(1),pos x) ;与最近敌人的距离小于较远的那个,就可以判断是近敌了
var(1) = 0
IgnoreHitPause = 1

[State -3, 目の前の敵が一番近い相手ではない] ;和上面反着来,这次就是较远的那位
type = VarSet
triggerall = roundstate = 2
triggerall = numenemy >= 2
trigger1 = enemynear(0),life <= 0
trigger2 = numenemy >= 2
trigger2 = enemy(0),life <= 0 || enemy(1),life <= 0
trigger2 = enemynear(0),life <= 0
trigger3 = enemy(0),life > 0 && enemy(1),life > 0
trigger3 = abs(root,pos x - enemynear(0),pos x) > abs(root,pos x - enemynear(1),pos x)
var(1) = 1
IgnoreHitPause = 1

;自分の後ろに設置 ――――――――――――――――――――――――――――――――――――――――
[State 31000, Turn] ;面向设置,保持(HELPER自己)面向对手(近的那位),var(1) = 0为优先,所以与近敌之间面对的时候不转方向,背对的时候转个方向
type = Turn
trigger1 = facing*ifelse((enemynear(var(1)),pos x-pos x)>=0,1,-1) < 0
IgnoreHitPause = 1
supermovetime = 9999
pausemovetime = 9999

[State 31000, VarSet]
type = VarSet
trigger1 = enemynear(var(1)),facing*ifelse((enemynear(var(1)),pos x-root,pos x)>=0,1,-1)<=0 ;近敌与本体间的距离判断为背对
trigger2 = !enemynear(var(1)),hitdefattr = A,NA,SA,HA ;对手不是空中技能(只能说明绝大多数)
var(2) = 0
IgnoreHitPause = 1
supermovetime = 9999
pausemovetime = 9999

[State 31000, VarSet]
type = VarSet
trigger1 = enemynear(var(1)),facing*ifelse((EnemyNear(var(1)),pos x-root,pos x)>=0,1,-1)>0 ;与上面相反,说明本体是面对近敌
trigger1 = enemynear(var(1)),hitdefattr = A,NA,SA,HA ;对手是空中技能(绝大多数)
var(2) = 1
IgnoreHitPause = 1
supermovetime = 9999
pausemovetime = 9999

[State 31000, PosSet] ;设置HELPER自己的位置,当对手是空中并且面对对手,满足空中拳脚之类的技能的时候,本体距离+attack.dist(默认160),除此之外就是proj.attack.dist(默认90),并确定朝向近敌
type = PosSet
trigger1 = 1
x = root,pos x+ifelse((enemynear(var(1)),pos y<0&&var(2)=1),(enemynear(var(1)),const(size.attack.dist)),(enemynear(var(1)),const(size.proj.attack.dist)))*(enemynear(var(1)),facing)
IgnoreHitPause = 1
supermovetime = 9999
pausemovetime = 9999

;---------------------------------------------------------------------------
;ガード学習 ;破防记忆,只可惜被击飞或者某些带p2stateno的特殊状态没法被记下来:(
;---------------------------------------------------------------------------
[State 31000, 中段記憶] ;当对手在地面且本体蹲下的时候,招式被破了,记下来,一般是特殊技6A,6B之类的
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1 ;被打的第一时间记下来,防止多记下不该有的
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155]) ;被破防之前是防御状态
TriggerAll = EnemyNear(Root,var(58)),StateType != A && Root,StateType = C
Trigger1 = var(10) = 0
V = 10
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 中段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != A && Root,StateType = C
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(10) ;不能与上面冲突,记下新的
Trigger1 = var(10) > 0 ;确定这个状态不是默认状态,记下新的,下面也是一样的道理
Trigger1 = var(11) = 0
V = 11
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 中段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != A && Root,StateType = C
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(10)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(11)
Trigger1 = var(11) > 0
Trigger1 = var(12) = 0
V = 12
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 中段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != A && Root,StateType = C
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(10)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(11)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(12)
Trigger1 = var(12) > 0
Trigger1 = var(13) = 0
V = 13
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 中段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != A && Root,StateType = C
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(10)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(11)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(12)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(13)
Trigger1 = var(13) > 0
Trigger1 = var(14) = 0
V = 14
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, 下段記憶] ;本体站立时候且对手不是下蹲状态,一般记下5B之类的
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != C && Root,StateType = S
Trigger1 = var(20) = 0
V = 20
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 下段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != C && Root,StateType = S
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(20)
Trigger1 = var(20) > 0
Trigger1 = var(21) = 0
V = 21
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 下段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != C && Root,StateType = S
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(20)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(21)
Trigger1 = var(21) > 0
Trigger1 = var(22) = 0
V = 22
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 下段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != C && Root,StateType = S
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(20)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(21)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(22)
Trigger1 = var(22) > 0
Trigger1 = var(23) = 0
V = 23
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

[State 31000, 下段記憶]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != C && Root,StateType = S
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(20)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(21)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(22)
TriggerAll = EnemyNear(Root,var(58)),StateNo != var(23)
Trigger1 = var(23) > 0
Trigger1 = var(24) = 0
V = 24
Value = (EnemyNear(Root,var(58)),StateNo)
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, 中段記憶削除] ;★★★为了防止某些特殊的状态(比如崩防,statetype = S,movetype = H)这种的而准备的
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != A && Root,StateType = S
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(10) ;记错了,把它消去,重新记录
Trigger1 = var(10) > 0
V = 10
Value = 0
IgnoreHitPause = 1

[State 31000, 中段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != A && Root,StateType = S
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(11)
Trigger1 = var(11) > 0
V = 11
Value = 0
IgnoreHitPause = 1

[State 31000, 中段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != A && Root,StateType = S
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(12)
Trigger1 = var(12) > 0
V = 12
Value = 0
IgnoreHitPause = 1

[State 31000, 中段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != A && Root,StateType = S
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(13)
Trigger1 = var(13) > 0
V = 13
Value = 0
IgnoreHitPause = 1

[State 31000, 中段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != A && Root,StateType = S
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(14)
Trigger1 = var(14) > 0
V = 14
Value = 0
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, 下段記憶削除] ;这边也是一样
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != C && Root,StateType = C
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(20)
Trigger1 = var(20) > 0
V = 20
Value = 0
IgnoreHitPause = 1

[State 31000, 下段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != C && Root,StateType = C
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(21)
Trigger1 = var(21) > 0
V = 21
Value = 0
IgnoreHitPause = 1

[State 31000, 下段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != C && Root,StateType = C
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(22)
Trigger1 = var(22) > 0
V = 22
Value = 0
IgnoreHitPause = 1

[State 31000, 下段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != C && Root,StateType = C
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(23)
Trigger1 = var(23) > 0
V = 23
Value = 0
IgnoreHitPause = 1

[State 31000, 下段記憶削除]
Type = VarSet
TriggerAll = Root,var(59) = 1
TriggerAll = Root,MoveType = H && Root,Time <= 1
TriggerAll =(Root,StateNo != [120,155]) && (Root,PrevStateNo = [120,155])
TriggerAll = EnemyNear(Root,var(58)),StateType != C && Root,StateType = C
TriggerAll = EnemyNear(Root,var(58)),StateNo = var(24)
Trigger1 = var(24) > 0
V = 24
Value = 0
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, DisplayToClipBoard] ;在ctrl+d下可以看到变化
Type = DisplayToClipBoard
trigger1 = IsHelper
Text = "var(10)=%d,var(11)=%d,var(12)=%d,var(13)=%d,var(14)=%d"
Params = var(10),var(11),var(12),var(13),var(14)
IgnoreHitPause = 1

[State 31000, AppendToClipboard] ;增加下段观察
type = AppendToClipboard
trigger1 = IsHelper
text = "\nvar(20)=%d,var(21)=%d,var(22)=%d,var(23)=%d,var(24)=%d"
params = var(20),var(21),var(22),var(23),var(24)
IgnoreHitPause = 1

;---------------------------------------------------------------------------
[State 31000, DestroySelf] ;一局结束之后把它消去比较好,下一局重新记录
type = DestroySelf
triggerall = ishelper
triggerall = roundstate >= 3
trigger1 = root,stateno != [120,159]
trigger2 = roundstate >= 4

;------------------------------------------------------------------------------------
然后同样的方法,召唤出HELPER

[State -3, ガードチェックヘルパー]
Type = Helper
TriggerAll = var(59)
TriggerAll = RoundState = 2
Trigger1 =!NumHelper(31000+ID)
Trigger1 =!IsHelper
HelperType = Normal
Name = "Guard"
PosType = left
StateNo = 31000
ID = 31000+ID
Pos = 0,9999
KeyCtrl = 0
Ownpal = 1
Persistent = 0
IgnoreHitPause = 1
PauseMoveTime = 2147483647
SuperMoveTime = 2147483647

[State -3, 関係無いステートに行かないように]
Type = ChangeState
Trigger1 = IsHelper
Trigger1 = IsHelper(31000+Root,ID)
Trigger1 = StateNo != 31000
Value = 31000

;很多都是前面提过的,这里就不多讲了

然后在段位里面这样用,消耗一个var,记录在-3下,如果var冲突了就换别的var

;==============================================================================
;AIガード切り替え
;==============================================================================
[State -3, 防御する必要がない状況] ;不需要防守的时候,敌人死了,或者是不在guarddist内
Type = VarSet
TriggerAll = !IsHelper
Trigger1 = NumEnemy = 0
Trigger2 = !InGuardDist
var(48) = 0
IgnoreHitPause = 1

[State -3, 立ち] ;站防,用var(48) = 2来代替
Type = VarSet
TriggerAll = var(59) = 1
TriggerAll =!IsHelper
TriggerAll = NumEnemy
TriggerAll = NumHelper(31000+ID)
TriggerAll = StateType != A
TriggerAll = EnemyNear(var(58)),StateNo != 0
Trigger1 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(10)
Trigger2 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(11)
Trigger3 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(12)
Trigger4 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(13)
Trigger5 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(14)
var(48) = 2
IgnoreHitPause = 1

[State -3, しゃがみ] ;蹲防,用var(48) = 1来代替
Type = VarSet
TriggerAll = var(59) = 1
TriggerAll =!IsHelper
TriggerAll = NumEnemy
TriggerAll = NumHelper(31000+ID)
TriggerAll = StateType != A
TriggerAll = EnemyNear(var(58)),StateNo != 0
Trigger1 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(20)
Trigger2 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(21)
Trigger3 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(22)
Trigger4 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(23)
Trigger5 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(24)
var(48) = 1
IgnoreHitPause = 1

[State -3, 立ち]
Type = VarSet
TriggerAll = var(59) = 1
TriggerAll =!IsHelper
TriggerAll = NumEnemy
TriggerAll = NumHelper(31000+ID)
TriggerAll = StateType != A
TriggerAll = EnemyNear(var(58)),StateNo != Helper(31000+ID),var(20) ;不能是被破防的招式
TriggerAll = EnemyNear(var(58)),StateNo != Helper(31000+ID),var(21)
TriggerAll = EnemyNear(var(58)),StateNo != Helper(31000+ID),var(22)
TriggerAll = EnemyNear(var(58)),StateNo != Helper(31000+ID),var(23)
TriggerAll = EnemyNear(var(58)),StateNo != Helper(31000+ID),var(24)
Trigger1 = var(57) = [1,4]
Trigger1 = EnemyNear(var(58)),StateType = A
Trigger1 = Random <= ((var(57) * 12.5) * var(56))
Trigger1 = Random <= 250
Trigger2 = var(57) > 4
Trigger2 = EnemyNear(var(58)),StateType = A
Trigger3 = var(57) > 4
Trigger3 = EnemyNear(var(58)),StateType = S
Trigger3 = EnemyNear(var(58)),Time >= 20 || EnemyNear(var(58)),StateNo >= 1000
Trigger3 =!EnemyNear(var(58)),NumProj
var(48) = 2
IgnoreHitPause = 1

[State -3, しゃがみ]
Type = VarSet
TriggerAll = var(59) = 1
TriggerAll =!IsHelper
TriggerAll = NumEnemy
TriggerAll = NumHelper(31000+ID)
TriggerAll = StateType != A
TriggerAll = EnemyNear(var(58)),StateNo != Helper(31000+ID),var(10)
TriggerAll = EnemyNear(var(58)),StateNo != Helper(31000+ID),var(11)
TriggerAll = EnemyNear(var(58)),StateNo != Helper(31000+ID),var(12)
TriggerAll = EnemyNear(var(58)),StateNo != Helper(31000+ID),var(13)
TriggerAll = EnemyNear(var(58)),StateNo != Helper(31000+ID),var(14)
Trigger1 = var(57) = [1,4]
Trigger1 = EnemyNear(var(58)),StateType != A
Trigger1 = Random <= ((var(57) * 12.5) * var(56))
Trigger1 = Random <= 250
Trigger2 = var(57) > 4
Trigger2 = EnemyNear(var(58)),StateType = C
Trigger3 = var(57) > 4
Trigger3 = EnemyNear(var(58)),StateType = S
Trigger3 = EnemyNear(var(58)),Time < 20 && EnemyNear(var(58)),StateNo < 1000
Trigger3 =!EnemyNear(var(58)),NumProj
Trigger4 = var(57) > 4
Trigger4 = EnemyNear(var(58)),StateType = S
Trigger4 = EnemyNear(var(58)),NumProj
var(48) = 1
IgnoreHitPause = 1

[State -3, 立ち]
Type = VarSet
TriggerAll = var(59) = 1
TriggerAll =!IsHelper
TriggerAll = NumEnemy
TriggerAll = NumHelper(31000+ID)
TriggerAll = StateType != A
TriggerAll = MoveType != H
Trigger1 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(10) ;破防以后换一个段位记忆招式
Trigger2 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(11)
Trigger3 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(12)
Trigger4 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(13)
Trigger5 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(14)
var(48) = 2
IgnoreHitPause = 1

[State -3, しゃがみ]
Type = VarSet
TriggerAll = var(59) = 1
TriggerAll =!IsHelper
TriggerAll = NumEnemy
TriggerAll = NumHelper(31000+ID)
TriggerAll = StateType != A
TriggerAll = MoveType != H
Trigger1 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(20)
Trigger2 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(21)
Trigger3 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(22)
Trigger4 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(23)
Trigger5 = EnemyNear(var(58)),StateNo = Helper(31000+ID),var(24)
var(48) = 1
IgnoreHitPause = 1

120-155之间也修改一下,这里只给出变化部分,照着抄就好了
;---------------------------------------------------------------------------
; GUARD (start)
[Statedef 120]
type = U ;Leave state type unchanged
physics = U ;Leave physics unchanged

[State 120, Hi to Lo]
type = StateTypeSet
triggerall = statetype = S
trigger1 = var(59) != 1
trigger1 = command = "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 1 ;var(48) = 1为蹲防,2为站防,下面有一样的就不多讲了
statetype = C
physics = C

[State 120, Lo to Hi]
type = StateTypeSet
triggerall = statetype = C
trigger1 = var(59) != 1
trigger1 = command != "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 2
statetype = S
physics = S

;---------------------------------------------------------------------------
; STAND GUARD (guarding)
[Statedef 130]
type = S
physics = S

[State 130, Hi to Lo]
type = ChangeState
trigger1 = var(59) != 1
trigger1 = command = "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 1
value = 131

[State 130, Stop Guarding]
type = ChangeState
triggerall = var(59) != 1
trigger1 = command != "holdback"
trigger2 = !inguarddist
value = 140

[State 130, Stop Guarding]
type = ChangeState
triggerall = var(59) = 1
triggerall = !inguarddist
trigger1 = enemynear(var(58)),movetype != A ;不处于攻击状态并且背对自己
trigger1 = p2bodydist x < 0
trigger2 = p2bodydist x >= 0
trigger2 = numhelper(31000+ID)
trigger2 = !helper(31000+ID),inguarddist ;确认helper不在guarddist内撤销防御
value = 140
ignorehitpause = 1

;---------------------------------------------------------------------------
; CROUCH GUARD (guarding)
[Statedef 131]
type = C
physics = C

[State 131, Lo to Hi]
type = ChangeState
trigger1 = var(59) != 1
trigger1 = command != "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 2
value = 130

[State 131, Stop Guarding]
type = ChangeState
triggerall = var(59) != 1
trigger1 = command != "holdback"
trigger2 = !inguarddist
value = 140

[State 131, Stop Guarding]
type = ChangeState
triggerall = var(59) = 1
triggerall = !inguarddist
trigger1 = enemynear(var(58)),movetype != A
trigger1 = p2bodydist x < 0
trigger2 = p2bodydist x >= 0
trigger2 = numhelper(31000+ID)
trigger2 = !helper(31000+ID),inguarddist
value = 140
ignorehitpause = 1

;---------------------------------------------------------------------------
; AIR GUARD (guarding)
[Statedef 132]
type = A
physics = N

[State 132, 6]
type = ChangeState
triggerall = sysvar(0)
triggerall = inguarddist
trigger1 = var(59) != 1
trigger1 = command = "holdback"
trigger2 = var(59) = 1
value = 130

[State 132, Stop Guarding]
type = ChangeState
triggerall = var(59) != 1
trigger1 = command != "holdback"
trigger2 = !inguarddist
value = 140

[State 132, Stop Guarding]
type = ChangeState
triggerall = var(59) = 1
triggerall = !inguarddist
trigger1 = enemynear(var(58)),movetype != A
trigger1 = p2bodydist x < 0
trigger2 = p2bodydist x >= 0
trigger2 = numhelper(31000+ID)
trigger2 = !helper(31000+ID),inguarddist
value = 140
ignorehitpause = 1

;---------------------------------------------------------------------------
; GUARD (end)
[Statedef 140]
type = U ;Leave state type unchanged
physics = U ;Leave physics unchanged
ctrl = 1

[State 140, Hi to Lo]
type = StateTypeSet
triggerall = statetype = S
trigger1 = var(59) != 1
trigger1 = command = "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 1
statetype = C
physics = C

[State 140, Lo to Hi]
type = StateTypeSet
triggerall = statetype = C
trigger1 = var(59) != 1
trigger1 = command != "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 2
statetype = S
physics = S

;---------------------------------------------------------------------------
; SGUARDHIT (shaking)
[Statedef 150]
type = S
movetype= H
physics = N
velset = 0,0

[State 150, Hi to Lo]
type = StateTypeSet
triggerall = statetype = S
trigger1 = var(59) != 1
trigger1 = command = "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 1
statetype = C
physics = C

[State 150, Lo to Hi]
type = StateTypeSet
triggerall = statetype = C
trigger1 = var(59) != 1
trigger1 = command != "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 2
statetype = S
physics = S

;---------------------------------------------------------------------------
; SGUARDHIT2 (knocked back)
[Statedef 151]
type = S
movetype= H
physics = S
anim = 150

[State 151, Hi to Lo]
type = StateTypeSet
triggerall = statetype = S
trigger1 = var(59) != 1
trigger1 = command = "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 1
statetype = C
physics = C

[State 151, Lo to Hi]
type = StateTypeSet
triggerall = statetype = C
trigger1 = var(59) != 1
trigger1 = command != "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 2
statetype = S
physics = S

;---------------------------------------------------------------------------
; CGUARDHIT (shaking)
[Statedef 152]
type = C
movetype= H
physics = N
velset = 0,0

[State 152, Hi to Lo]
type = StateTypeSet
triggerall = statetype = S
trigger1 = var(59) != 1
trigger1 = command = "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 1
statetype = C
physics = C

[State 152, Lo to Hi]
type = StateTypeSet
triggerall = statetype = C
trigger1 = var(59) != 1
trigger1 = command != "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 2
statetype = S
physics = S

;---------------------------------------------------------------------------
; CGUARDHIT2 (knocked back)
[Statedef 153]
type = C
movetype= H
physics = C
anim = 151

[State 153, Hi to Lo]
type = StateTypeSet
triggerall = statetype = S
trigger1 = var(59) != 1
trigger1 = command = "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 1
statetype = C
physics = C

[State 153, Lo to Hi]
type = StateTypeSet
triggerall = statetype = C
trigger1 = var(59) != 1
trigger1 = command != "holddown"
trigger2 = var(59) = 1
trigger2 = var(48) = 2
statetype = S
physics = S

;---------------------------------------------------------------------------
; AGUARDHIT2 (knocked away)
[Statedef 155]
type = A
movetype= H
physics = N
anim = 152

[State 155, 6]
type = ChangeState
triggerall = sysvar(0)
triggerall = inguarddist
trigger1 = var(59) != 1
trigger1 = command = "holdback"
trigger2 = var(59) = 1
value = 130

于是现在就是比较完善的防御系统了,自己也去试着理解一下吧

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

mizore@kotori.moe, 谢谢大家!

アクセス

オンライン