News:

MFG's Character of the Month: October 2026 Nominations

Main Menu

Faulty parry code

Started by Creamy_Goodness, April 15, 2009, 07:03:16 AM

Previous topic - Next topic

Creamy_Goodness


> In June of last year, I coded the parry for my character Brandy. However, I did not get the coding quite right, and noticed two serious anomalies with it. First, if a beam or some other multiple hit attack comes at Brandy, a single tap forward can cause her to parry several times for the duration of the timing window. I wanted to program the parry to defend against only one hit per forward tap, and then be immediately ready to parry the next hit. The other error is that if the player taps forward and an attack button at the same time, Brandy can parry an attack a split second after her own attack has started. This is especially problematic in the case of her counter throws that require a press of forward plus both punches or kicks. The following is Brandy's current parry code...

> In the cmd file...

;---------------------------------------------------------------------------
; Parry High
[State -1, Parry High]
type = HitOverride
triggerall = command = "fwd"
trigger1 = ctrl = 1 ;player must be in control of Brandy
trigger1 = statetype = S ;can't parry in the air
attr = SA, AA, AP ;standing and aerial, all hit attacks, all projectiles
stateno = 508 ;switches to State 508 (Parry High)
time = 15 ;parry timing window


> In the cns file...

;---------------------------------------------------------------------------
; Parry High

[Statedef 508]
type = S ;can only do while standing
physics = S ;Stand physics apply friction to Brandy
anim = 508 ;switches to Parry animation (sprites)
velset = 0, 0 ;holds Brandy in place
ctrl = 0 ;player loses control of Brandy
poweradd = 100 ;Brandy gains 100 points of energy

[State 508, Pause]
type = Pause ;type of state: freezes the game
trigger1 = AnimElem = 1 ;kicks in when animation reaches its first frame
time = 15 ;freezes the opponent for 15 ticks

[State 508, NHB]
type = NotHitBy ;type of state: Makes Brandy immune to certain attacks
trigger1 = Time = 0 ;kicks in immediately
value = SA, AA, AP ;standing and aerial, all hit attacks, all projectiles

[State 508, LifeAdd]
type = LifeAdd ;type of state: Brandy regains some health
trigger1 = Time = 0 ;kicks in immediately
value = 10 ;Brandy gains 10 points of health

[State 508, End]
type = ChangeState ;type of state: Change State
trigger1 = Time = 1 ;kicks in after 1 tick
value = 0 ;switches to State 0 (Stance)
ctrl = 1 ;player regains control of Brandy


> As always, any and all help is appreciated. :)

= = = = = = = = = =
Jason "Creamy Goodness" Tenn
http://creamyg.jdluke.com/

Shamrock

The first one can be handled in the cmd file but there has to be a better way so i'll Cy get that one.

The second problem is a command problem.

Add Triggerall= !whateverstates you don't want to the cmd for parry. There might be a cleaner way but I know that it would work.


Byakko

You can always make another HOR with time = 0 when you don't have control / are in the parry state, because you basically need to disabled the one that already was activated when you did press F under the correct circumstances. And you do that by replacing it.
If I struggled to the end of my determination, to the end of my way of life with my followers, if the result is ruin, then this ruin is inevitable. Grieve. Shed tears. But you cannot regret.

Creamy_Goodness


Byakko> So what you're basically saying is to make a second HitOverride that has all the triggers as the one for the parry, except the ctrl trigger is 0, and this is supposed to override the first HitOverride? OK thanks, I'll give it a shot.

= = = = = = = = = =
Jason "Creamy Goodness" Tenn
http://creamyg.jdluke.com/

Creamy_Goodness


> No luck. I tried using the second HitOverride to send Brandy into her stance, but she could still parry multiple hits with a single tap of Forward. Here's the code I tried...

;---------------------------------------------------------------------------
; Parry High (Not already parrying)
[State -1, Parry High]
type = HitOverride
triggerall = command = "fwd"
trigger1 = ctrl = 1 ;player must be in control of Brandy
trigger1 = statetype = S ;can't parry in the air
attr = SA, AA, AP ;standing and aerial, all hit attacks, all projectiles
stateno = 508 ;switches to State 508 (Parry High)
time = 15 ;parry timing window

;---------------------------------------------------------------------------
; Parry High (Already parrying)
[State -1, Parry High]
type = HitOverride
triggerall = command = "fwd"
trigger1 = ctrl = 0 ;player must not be in control of Brandy
trigger1 = statetype = S ;can't parry in the air
trigger1 = StateNo = 508
attr = SA, AA, AP ;standing and aerial, all hit attacks, all projectiles
;stateno = 0 ;switches to State 0 (Stance)
time = 15 ;parry timing window



= = = = = = = = = =
Jason "Creamy Goodness" Tenn
http://creamyg.jdluke.com/

Creamy_Goodness


> Since the parry effect repeats as long as the HitOverride is active, is there a way to set the time remaining on the HitOverride to zero right after a successful parry?
= = = = = = = = = =
Jason "Creamy Goodness" Tenn
http://creamyg.jdluke.com/

Byakko

Yeah it's basically what I told you to do the first time around.
If I struggled to the end of my determination, to the end of my way of life with my followers, if the result is ruin, then this ruin is inevitable. Grieve. Shed tears. But you cannot regret.

Creamy_Goodness


> Still no good :(

; Parry High
;(Not already parrying)
[State -1, Parry High]
type = HitOverride
triggerall = command = "fwd"
trigger1 = ctrl = 1 ;player must be in control of Brandy
trigger1 = statetype = S ;can't parry in the air
attr = SA, AA, AP ;standing and aerial, all hit attacks, all projectiles
stateno = 508 ;switches to State 508 (Parry High)
time = 15 ;parry timing window

;- - - - - - - - - -
; (Already parrying)
[State -1, Parry High]
type = HitOverride
triggerall = command = "fwd"
trigger1 = ctrl = 0 ;player must not be in control of Brandy
trigger1 = statetype = S ;can't parry in the air
trigger1 = StateNo = 508
attr = SA, AA, AP ;standing and aerial, all hit attacks, all projectiles
stateno = 0 ;switches to State 0 (Stance)
time = 0 ;parry timing window
= = = = = = = = = =
Jason "Creamy Goodness" Tenn
http://creamyg.jdluke.com/

Byakko

#8
Put the hitoverride with just a trigger at "!time" (time = 0) and give it a time = 0 in the parry state. You may want to give all your parries a slot number (just add the line "slot = 1" to all your parries), this way you're sure the one in the parry state goes to the same slot as the one currently active and overrides it.

Regardless, It's weird that it reactivates at all. Last I checked, hitoverride doesn't activate several times in a row, it turns off when it's activated once.
My parry code is this :
Spoiler: CMD (click to show)
;---------------------------------------------------------------------------
; [PARRY]
; Stand parry
[State -1, stp]
type = hitoverride
triggerall = statetype != A && command = "Fw"
triggerall = movetype != A
trigger1 = ctrl || stateno = 850 || stateno = 851 || stateno = 500; || stateno=[150,153]
trigger1 = var(3) := (8)
attr = SA, AA, AP
stateno = 850
time = ifelse((stateno=[150,153]), 6, 8)
slot = 1
; Stand parry a crouching, but high, attack
[State -1, stp]
type = hitoverride
triggerall = statetype != A && command = "Fw"
triggerall = movetype != A
trigger1 = ctrl || stateno = 850 || stateno = 851 || stateno = 500; || stateno=[150,153]
trigger1 = var(3) := (8)
attr = C, AA, AP
stateno = 5005
time = ifelse((stateno=[150,153]), 6, 8)
slot = 2

; Crouch parry
[State -1, crp]
type = hitoverride
triggerall = (statetype = S && command = "D") || (statetype = C && command = "Fw")
triggerall = movetype != A
trigger1 = ctrl || stateno = 850 || stateno = 851 ||stateno = 500; || stateno = [150,153]
trigger1 = var(3) := (18)
attr = C, AA, AP
stateno = 851
time = ifelse((stateno = [150,153]), 6, 8)
slot = 1
; Crouch parry a standing light attack
[State -1, crp]
type = hitoverride
triggerall = (statetype = S && command = "D") || (statetype = C && command = "Fw")
triggerall = movetype != A
trigger1 = ctrl || stateno = 850 || stateno = 851 ||stateno = 500; || stateno = [150,153]
trigger1 = var(3) := (18)
attr = S, AA, AP
stateno = 5005
time = ifelse((stateno = [150,153]), 6, 8)
slot = 2

; Air parry
[State -1, aip]
type = hitoverride
triggerall = statetype = A && command = "Fw"
triggerall = movetype != A
trigger1 = ctrl || stateno = 852; || stateno = [154,155]
trigger1 = var(3) := (28)
trigger2 = Vel Y > 0 && StateNo = [1050,1201]
trigger2 = var(3) := (28)
attr = SA, AA, AP
stateno = 852
time = ifelse((stateno = [154,155]), 6, 8)
slot = 1

; no parry if can't parry
[State -1, ps]
type = hitoverride
trigger1 = !ctrl && stateno != [850,852]
trigger1 = stateno != 3003 && stateno != [150,155]
trigger1 = var(3) := 0
trigger2 = statetype = A && var(3) != [20,29]
trigger2 = var(3) := 0
trigger3 = statetype = C && var(3) != [10,19]
trigger3 = var(3) := 0
trigger4 = statetype = S && var(3) != [1,29]
trigger4 = var(3) := 0
attr = SCA
time = 0

I also used this

[Command]
name = "Fw"
command = F
time = 4
Spoiler: CNS (click to show)
;---------------------------------------------------------------------------
; stand parry
[Statedef 850]
type = S
movetype = I
physics  = N
anim     = 850
poweradd = 100
velset   = 0,0
ctrl     = 0
SprPriority = 5

[State 3000, 1]
type = Explod
trigger1 = time = 1
anim = 7200
scale = .5,.5
pos = 34, -83
sprpriority = 6
supermove = 1
persistent = 0
pausemovetime = -1
ownpal = 1
id = 7035

[State 850, position]
type = PosSet
trigger1 = 1
y = 0

[State 850, assertsp]
type = assertspecial
trigger1 = 1
flag = nowalk
flag2 = nostandguard
flag3 = nocrouchguard

[State 850, pause]
type = pause
trigger1 = !time
time = 15
movetime = 15

[State 850, nhb]
type = nothitby
trigger1 = animelem = 4, < 0
time = 1
value = SCA

[State 850, bg effect]
type = EnvColor
trigger1 = Time = 0
value = 255, 255, 255
time = 1

[State 850, sound]
type = PlaySnd
trigger1 = time = 0
value = 6,1

[State 850, shake]
type = envshake
trigger1 = !time
time = 8
freq = 60
ampl = 3

[State 850, blueflash]
type = palfx
trigger1 = !Time
add = 0, 50, 255
sinadd = 0, -50, -255, 60
time = 15

[State 850, ctrl]
type = ctrlset
trigger1 = animelem = 2, > 8
value = 1

[State 850, end]
type = ChangeState
Trigger1 = AnimTime = 0
value = 0
ctrl = 1

(then states 851 & 852 for air & crouch, same except air doesn't have the posset)
Spoiler: StateDef -2 (click to show)
;---------------------------------------------------------------------------
; no parry if can't parry
[State -1, ps]
type = hitoverride
trigger1 = !ctrl && Stateno != [850,852]
trigger1 = Stateno != 3003 && Stateno != [150,155]
trigger2 = Statetype = A && var(3) != 3 && var(3) != 6
trigger3 = Statetype = C && var(3) != 2 && var(3) != 5
trigger4 = Statetype = S && (var(3) = 3 || var(3) = 6)
trigger5 = Stateno = [100,110]
attr = SCA
time = 0
slot = 1
[State -1, ps]
type = hitoverride
trigger1 = !ctrl && Stateno != [850,852]
trigger1 = Stateno != 3003 && Stateno != [150,155]
trigger2 = Statetype = A && var(3) != [21,29]
trigger3 = Statetype = C && var(3) != [11,19]
trigger4 = Statetype != A && var(3) = [21,29]
trigger5 = Stateno = [100,110]
attr = SCA
time = 0
slot = 2
[State -2, parrytimer]
type = VarAdd
trigger1 = Var(3) != 0 && Var(3) != 9 && Var(3) != 10 && Var(3) != 19 && Var(3) != 20
v = 3
value = -1
[State -2, noparry]
type = hitoverride
trigger1 = !(var(3)%10) && var(3) != 0
trigger1 = var(3) := 0
trigger2 = var(3)%10 = 2 && Command = "holdfwd"
trigger2 = var(3) := 0
attr = SCA
time = 0
slot = 1
[State -2, noparry]
type = hitoverride
trigger1 = !(var(3)%10) && var(3) != 0
trigger1 = var(3) := 0
trigger2 = var(3)%10 = 2 && Command = "holdfwd"
trigger2 = var(3) := 0
attr = SCA
time = 0
slot = 2
Now there are chunks in this which I used to keep track if I'm still holding forward. I use that because if you only tap, the parry is active for a given time, but if you hold, the window for parry is half shorter. I also used a variable for that, and had to split the ranges of values between stand, air and crouch. Also I split the three hitoverride in three slots, I think that was relateed to how I would hit forward and then jump, I didn't want a standing parry to activate while jumping.

keep in mind that I haven't touched this in a couple of years, so I don't remember all of it,  and it's most likely far from perfect. My usage of a "Fw" command with time = 4 is definitely weird, for example, and there must be a piece of it that's unnecessary (I don't remember why I put the "no parry if can't parry" in both the cmd and statedef -2). But I never had any noticeable problem with this.
If I struggled to the end of my determination, to the end of my way of life with my followers, if the result is ruin, then this ruin is inevitable. Grieve. Shed tears. But you cannot regret.

Creamy_Goodness


> Thanks for taking the time to help me out, Byakko. I still don't fully understand everything you said, but I might have time to experiment with it next week after I'm done with my website update, as well as coding some additional actions for Brandy.
= = = = = = = = = =
Jason "Creamy Goodness" Tenn
http://creamyg.jdluke.com/

Creamy_Goodness

#10

> I just fixed Brandy's parry code, and as it turns out, I didn't need the second HitOverride after all. I went into Brandy's AIR file and increased the number of ticks in her parry from 1 to 15, and then wrote "movetime = 15" in the Pause state controller to prevent the parry from acting weird. I also found a bug where I couldn't parry the first hit of a beam then block the rest, but I was able to fix that by changing "trigger1 = AnimTime = 0" to "trigger1 = 1" in the NotHitBy state controller. And finally in the CMD, I changed my parry code to the following...

[State -1, Parry High]
type = HitOverride
triggerall = command = "fwd"
triggerall = statetype = S ;can't parry in the air
trigger1 = ctrl = 1 ;player must be in control of Brandy
trigger2 = stateno = 508 ;State 508 (Parry High)
attr = SA, AA, AP ;standing and aerial, all hit attacks, all projectiles
stateno = 508 ;switches to State 508 (Parry High)
time = 15 ;parry timing window

> And now, not only do I get only one parry per forward tap, but I can also parry an entire beam by just jamming forward throughout the duration of the beam. So finally, after four attempts and nearly two years of trying, Brandy's broken parry code is now fixed. Here is a short video clip of what her updated parry can do...

http://creamyg.hugelaser.com/Projects/MUGEN/Characters/Brandy_Oteigh/Movies/CGX_Brandy_-_Parry.avi
= = = = = = = = = =
Jason "Creamy Goodness" Tenn
http://creamyg.jdluke.com/