Previous parts:
Part 1: Basic Movements
Next parts:
Part 3: Custom Combo, Recovery, Guard
Part 4: Lose and Intro animations
Part 5: Constants, Win animations, Taunts
Part 6: Universal Helpers
Part 2: Run, Dash, Evade, Power Charge, Zero Counter, Parry
Greetings, folks! I'm listening to an H.P. Lovecraft audiobook while I'm writing this. I hope this won't affect me and make me create and Eldritch Ryu, with tentacles in his face and pitch-black Hadokens, that induces madness on whoever plays it. Now that I think about it, I think Duracelleur already made one...
In this section we'll talk about the run and dash states, plus some of the iconic features of P.o.t.S-ish characters: the SNK-style evasive moves, the Power Charge, the Alpha style Zero Counter, and finally the ever-beloved SFIII styled Parry.
RUN
This part was unexpectedly linear, no big differences between the reference characters and Ryu. That's because the real customization (I.e. the run speed) is actually on the .cns file. Let's run over it.
(Note: I'm putting some commentaries on the codes, too. Don't skip them over. Or do, I'm no cop.)
Spoiler, click to toggle visibilty
;======================<RUN>===========================
[StateDef 100]
type = S
physics = N
moveType = I
anim = 100
ctrl = 0
sprPriority = 1
[State 100, VelSet]
type = VelSet
trigger1 = 1
x = const(velocity.run.fwd.x)
[State 100, Step Sound]
type = PlaySnd
trigger1 = (AnimElem = 3 || AnimElem = 6)
value = 100, ifElse((AnimElem = 1 || AnimElem = 9), 0, 1)
; the trigger for this part depends on how the walking animation looks,
; so it HAS to be customized, of course. Source sounds on old Ryu
; are, again, different. I hope I remember to regroup them all.
[State 100, Jump]
type = ChangeState
trigger1 = !AILevel
trigger1 = command = "holdfwd" && command = "holdup"
value = 40
[State 100, Jump (AI)]
type = ChangeState
trigger1 = AILevel && Random < 25
value = 40
[State 100, End]
type = ChangeState
trigger1 = !AILevel && command != "holdfwd"
trigger2 = AILevel && P2BodyDist x <= 90
value = 101
;Stop Running
[StateDef 101]
type = S
physics = N ; <--- here, some characters had S. Don't think it matters, though.
moveType = I
anim = 101
ctrl = 0
sprPriority = 1
[State 101, Stopping Sound] ; <--- same as above sounds.
type = PlaySnd
trigger1 = !Time
value = 101,0
[State 101, VelAdd]
type = VelAdd
trigger1 = Time >= 0
x = -0.71613788604
[State 0, VelSet]
type = VelSet
trigger1 = !AnimTime
x = 0
; some of the characters I checked had these VelAdd and VelSet,
; others didn't. I guess these serve to cause a "slide" effect when
; the characters stops, instead of just freezing in place. I'll be putting
; them and see what happens.
[State 101, Skid Dust]
type = Explod
trigger1 = !Time
anim = 8104
sprPriority = 3
posType = P1
pos = 0,0
vel = 0,0
scale = 0.5,0.5
pauseMovetime = -1
superMoveTime = -1
ownpal = 1
[State 101, Jump]
type = ChangeState
trigger1 = !AILevel && command = "holdup"
value = 40
[State 101, End]
type = ChangeState
trigger1 = !AnimTime
value = ifElse(command = "holddown", 10, 0)
ctrl = 1
To summarize a bit, these codes just give your character a movement speed based on the values on the .cns and dictate how/when the state changes when you jump, prompting the statedef 40, or stop, prompting the 101. In the 101, you have the same for jumping soon after the stop or just doing nothing.
Anims 100 and 101 are, quite obviously, for the run and the stop.
Spoiler, click to toggle visibilty
;Running
[Begin Action 100]
Clsn2Default: 3
Clsn2[0] = 17, -91, 35, -73
Clsn2[1] = -18, -86, 28, -32
Clsn2[2] = -23, -32, 28, 0
110,1, 0,0, 5
Loopstart
100,4, 0,0, 5
100,5, 0,0, 6
100,0, 0,0, 5
100,1, 0,0, 6
100,2, 0,0, 5
100,3, 0,0, 6
Again, I'm taking a page from Ken and adding a dash sprite at the beginning. But I'm leaving the rest of the run unchanged: it looks less fast than Ken, and I wanna highlight the fact that Ryu is less agile and more "with grounded feet" than him.
I'm regrouping the sprites under group 101 to group 110, because they are the dash sprites.
;Running (Stopping)
[Begin Action 101]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
110,2, 0,0, 4
110,3, 0,0, 3
Sprite groups: 100 (run) and 101 (stop).
DASH
The code themselves for the back dash are, luckily, pretty samey between the reference characters, with some differences regarding the coding of the velocity, both horizontal and vertical. A vertical velocity may seem odd at first, but it can be useful if your character moves from the ground while dashing. Let's dash in.
Spoiler, click to toggle visibilty
;========================<DASH BACKWARDS>==========================
[StateDef 105]
type = A
physics = N
moveType = I
velSet = 0,0
anim = 105
ctrl = 0
sprPriority = 1
[State 105, Back Dash Sound]
type = PlaySnd
trigger1 = AnimElem = 2
value = 105,0
[State 105, Dust Helper]
type = Helper
trigger1 = AnimElem = 2
helperType = Normal
stateNo = 8103
ID = 8100
name = "Dash Dust"
posType = P1
facing = -1
pauseMoveTime = 255
superMoveTime = 255
ownPal = 1
[State 105, VelSet]
type = VelSet
trigger1 = AnimElem = 2
x = const(velocity.run.back.x)
y = const(velocity.run.back.y)
; EDIT: old Ryu had a multiplier for Evil Ryu's dash. I'm
; removing it as per KarmaChameleon's suggestion.
; EDIT 2: I messed up the first time, the multiplier
; was for the Master mode (as with others I assumed
; were for Evil Ryu and I edited out)
[State 105, VelAdd]
type = VelAdd
trigger1 = AnimElemTime(2) > 0
x = 0.09765625
; EDIT: this VelAdd was not in the old Ryu, and it is universal
; for CvS-based characters. Characters that jump during the
; dash also have an Y value, see replies for infos.
[State 105, End]
type = ChangeState
trigger1 = !AnimTime
value = 106
; Another difference between the old Ryu and new characters is the trigger
; for the end of the dash. In Ryu's file, it was just triggered by the end of the animation,
; but in some newer characters is based on a certain position and velocity.
; This time I'll be keeping the old trigger instead.
;Stop Dashing Backwards
[StateDef 106]
type = S
physics = S
ctrl = 0
anim = 106
velSet = 0,0
[State 106, PosSet]
type = PosSet
trigger1 = 1
y = 0
[State 106, Landing Sound]
type = PlaySnd
trigger1 = !Time
value = 100,1
[State 106, Landing Dust Explod]
type = Explod
trigger1 = !Time
anim = 8102
sprpriority = -3
postype = P1
scale = 0.5,0.5
pauseMoveTime = -1
superMoveTime = -1
ownPal = 1
[State 106, CtrlSet]
type = CtrlSet
trigger1 = Time >= 2
value = 1
[State 106, End]
type = ChangeState
trigger1 = !AnimTime
value = 0
ctrl = 1
; nothing much to see here, it's identical to old Ryu's.
New anims: 105 and 106. Which are, guess what? Back dash and stop.
Spoiler, click to toggle visibilty
;Dash Backwards
[Begin Action 105]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
105,0, 0,0, 3
105,1, 0,0, 6
105,2, 0,0, 7
;Dash Backwards (Stopping)
[Begin Action 106]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
105,2, 0,0, 2
11,0, 0,0, 2
Group 105. Some character have a fourth sprite on this group. Here, he'll be recycling one on the group 11.
The following is the first part that needs to get completely re-done. Not because there are big differences between old Ryu and the references, but because Ryu uses some different StateDefs for this dash, and I'll have to change them. It's a bit weird that this one is different when the back one was not, but oh well. Evolution is often funny.
The old StateDef for this dash were 102 and 103. Newer characters had 110 and 111.
Spoiler, click to toggle visibilty
;=================<DASH FORWARD>=================
[StateDef 110]
type = A
physics = N
moveType = I
anim = ifelse(var(1) = 2, 112, 110)
ctrl = 0
sprPriority = 1
; weirdly, despite the state itself being 102 on the old version,
; the animation was still 110. There's an additional anim for
; Evil Ryu, which I'll be adding, of course.
[State 110, Dash Sound]
type = PlaySnd
trigger1 = !Time
value = 110,0
[State 110, Dust Helper]
type = Helper
trigger1 = AnimElem = 2
helperType = Normal
stateNo = 8103
ID = 8100
name = "Dash Dust"
posType = P1
pauseMoveTime = 255
superMoveTime = 255
ownPal = 1
[State 110, VarSet -> Running]
type = VarSet
trigger1 = !Time
sysvar(1) = 1
[State 110, VarSet -> Not Running]
type = VarSet
triggerAll = Time <= 7
trigger1 = !AILevel && command != "holdfwd"
sysvar(1) = 0
[State 110, ChangeState to Running]
type = ChangeState
trigger1 = Time = 7 && sysvar(1)
value = 100
; the triggers on the two above blocks are the old Ryu's.
; Other characters I checked used AnimElemTime based
; triggers. I don't think it's important, though.
[State 110, VelSet]
type = VelSet
trigger1 = AnimElem = 2
x = 8.125
[State 110, VelAdd]
type = VelAdd
trigger1 = AnimElemTime(2) > 0
x = -0.09765625
; These values are, once again, constants in CvS
; styled character with a ground-type dash animation.
[State 110, End]
type = ChangeState
trigger1 = AnimElemTime(2) >= 0
trigger1 = pos y > -vel y
value = 111
;Stop Dashing Forward
[StateDef 111]
type = S
physics = S
ctrl = 1
anim = 111
velSet = 0,0
[State 111, PosSet]
type = PosSet
trigger1 = 1
y = 0
[State 111, Dash End Sound]
type = PlaySnd
trigger1 = !Time
value = 100,0
[State 111, Landing Dust Explod]
type = Explod
trigger1 = !Time
anim = 8102
sprPriority = -3
posType = P1
scale = 0.5,0.5
pauseMoveTime = -1
superMoveTime = -1
ownPal = 1
[State 111, End]
type = ChangeState
trigger1 = !AnimTime
value = 0
ctrl = 1
Time to add some more anims. I'm remaking these using Jmorphman's Ken as a template. Note that there's an additional one for Evil Ryu's forward dash.
Spoiler, click to toggle visibilty
;Dash Forward
[Begin Action 110]
Clsn2: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
110,0, 0,0, 5
Clsn2Default: 3
Clsn2[0] = 17, -81, 35, -61
Clsn2[1] = -8, -75, 34, -31
Clsn2[2] = -23, -32, 35, 0
110,1, 0,0, 6
110,2, 0,0, 7
;Dash Forward (Stopping)
[Begin Action 111]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
110,3, 0,0, 2
5,2, 0,0, 2
Ryu misses the sprite corresponding to Ken's 110,4. Luckily, he has an identical one in the group 5.
;Dash Forward (Evil Ryu)
[Begin Action 112]
Clsn2: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
110,0, 0,0, 2,
Clsn2Default: 3
Clsn2[0] = 17, -81, 35, -61
Clsn2[1] = -8, -75, 34, -31
Clsn2[2] = -23, -32, 35, 0
110,5, 0,0, 7,
110,6, 0,0, 2,
110,2, 0,0, 2,
DODGE
Another easy peasy lemon squeeze part, luckily. Basically, what we're seeing is the animation, some sounds, a playerpush state (which is the dodge itself, pretty much), an universal hitby state we can leave as it is, and the attacks that can be performed after.
The tricky thing is the fact that in newer characters this is StateDef 700, while in old Ryu is 710 (and 700 is the parry). Worry not, I'll redistribute the means of production the states. Let's dodge in.
Spoiler, click to toggle visibilty
;====================<DODGE>====================
[StateDef 700]
type = S
physics = S
moveType = I
anim = 700
ctrl = 0
velSet = 0,0
sprPriority = -2
[State 700, Voice]
type = PlaySnd
trigger1 = !Time
value = 3 + (var(1) = 2) * 10, 7 * (var(1) != 2)
channel = 0
[State 700, Dodge Sound]
type = PlaySnd
trigger1 = !Time
value = 1,3
channel = 1
[State 700, PlayerPush]
type = PlayerPush
trigger1 = 1
value = 0
ignoreHitPause = 1
[State 700, HitBy]
type = HitBy
trigger1 = 1
value = SCA,AT
time = 1
[State 700, Attack]
type = ChangeState
trigger1 = !AILevel && Time = [15,25]
trigger1 = command = "x" || command = "y" || command = "z" || command = "a" || command = "b" || command = "c"
value = ifElse((command = "x" || command = "y" || command = "z"), 210, 220)
[State 700, Attack (AI)]
type = ChangeState
trigger1 = AILevel && (Time = [15,25]) && NumEnemy
trigger1 = (EnemyNear, MoveType != A) && (P2BodyDist x = [-60,60]) && (P2Dist y >= -60)
value = ifElse(Random < 500, 210, 220)
[State 700, End]
type = ChangeState
trigger1 = !AnimTime
value = 0
ctrl = 1
These two nice blocks right before the endstate dictate which attacks will be done right after the dodge. We can customize them freely, but I'll be leaving old Ryu's values (unless I change my mind). The second trigger for the AI attacks was worded a bit differently in the old Ryu, but coded for the same effect. I put the new one.
One thing I changed to suit my tastes is the probability for CPU Ryu to attack with 210 (HP) or 220 (MK) after the dodge. It's 50/50 (random < 500). Insert obvious Thanos quote here.
Now for the animation. It was 710 on old Ryu, now it's 700.
Spoiler, click to toggle visibilty
;Evade
[Begin Action 700]
Clsn2Default: 1
Clsn2[0] = -17, -78, 17, 0
700,0, 0,0, 2
700,1, 0,0, 3
700,2, 0,0, 20
700,1, 0,0, 2
700,0, 0,0, 1
Here I go regrouping the sprites again.
ROLL
This is a part where customization is vital. While the code itself is fairly easy, each character has different looking animations. As such, positions and velocities must fit the animation.
EDIT: KarmaChameleon pointed out that this was, for the most part, bullcrap. The roll velocity is almost always the same (-5.625), and differences in the distance covered are due to the animation itself.
Again, the state was different on old Ryu, being 720. Here, I'll put it at 710 as in newer characters. Let's roll.
Spoiler, click to toggle visibilty
;================<ROLL FORWARD>================
[StateDef 710]
type = S
physics = N
moveType = I
anim = 710
ctrl = 0
velSet = 0,0
sprPriority = 1
[State 710, PlayerPush]
type = PlayerPush
trigger1 = 1
value = 0
ignoreHitPause = 1
[State 710, HitBy]
type = HitBy
trigger1 = AnimElemTime(8) < 0
value = SCA,AT
time = 1
[State 710, Voice]
type = PlaySnd
trigger1 = !Time
value = 3 + (var(1) = 2) * 10, 6 * (var(1) != 2)
channel = 0
[State 710, Voice]
type = PlaySnd
trigger1 = !Time && Random < 500
value = 3 + (var(1) = 2) * 10, 2 + (var(1) = 2)
channel = 0
[State 710, Roll Sound]
type = PlaySnd
trigger1 = Time = 1
value = 110,0
channel = 1
[State 710, Start Roll]
type = VelSet
trigger1 = AnimElem = 2
x = 5.625
[State 710, End Roll]
type = VelSet
trigger1 = AnimElem = 7
x = 0
[State 710, End]
type = ChangeState
trigger1 = !AnimTime
value = 0
ctrl = 1
About that weird PlaySnd block, that was a mean for P.o.t.S to randomize even more Ryu's grunts during the roll, so I went "why not?" and kept them.
Next is the backwards roll, which was 725 on old Ryu and now will be 715.
Spoiler, click to toggle visibilty
;===============<ROLL BACKWARDS>===============
[StateDef 715]
type = S
physics = N
moveType = I
anim = 715
ctrl = 0
velSet = 0,0
sprPriority = 1
[State 715, PlayerPush]
type = PlayerPush
trigger1 = 1
value = 0
ignoreHitPause = 1
[State 715, HitBy]
type = HitBy
trigger1 = AnimElemTime(7) < 0
value = SCA,AT
time = 1
[State 715, Voice]
type = PlaySnd
trigger1 = !Time
value = 3 + (var(1) = 2) * 10, 6 * (var(1) != 2)
channel = 0
[State 715, Voice]
type = PlaySnd
trigger1 = !Time && Random < 500
value = 3 + (var(1) = 2) * 10, 2 + (var(1) = 2)
channel = 0
[State 715, Roll Sound]
type = PlaySnd
trigger1 = Time = 1
value = 110,0
channel = 1
[State 715, Start Roll]
type = VelSet
trigger1 = AnimElem = 2
x = -5.625
[State 715, End Roll]
type = VelSet
trigger1 = AnimElem = 7
x = 0
[State 715, End]
type = ChangeState
trigger1 = !AnimTime
value = 0
ctrl = 1
Nothing to say here that I haven't said already for the previous section, the code is pretty much the same, the only difference is the negative VelSet value (obviously). I don't think it's mandatory for it to be the exact opposite, I reckon there are characters in which the two roll animation are not symmetrical. But that's not the case.
EDIT: considering what KarmaChameleon told me, this is probably false too.
Another couple of anims: 710 (was 720) and 715 (was 725).
Spoiler, click to toggle visibilty
;Roll Forward
[Begin Action 710]
Clsn2Default: 1
Clsn2[0] = -17, -78, 17, 0
710,0, 0,0, 4
710,1, 0,0, 3
710,2, 0,0, 3
710,3, 0,0, 3
710,4, 0,0, 4
710,5, 0,0, 3
710,6, 0,0, 3
Clsn2: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
11,0, 0,0, 2
;Roll Backward
[Begin Action 715]
Clsn2Default: 1
Clsn2[0] = -17, -78, 17, 0
710,0, 0,0, 4, H
710,1, 0,0, 3, H
710,2, 0,0, 3, H
710,3, 0,0, 3, H
710,4, 0,0, 4, H
710,5, 0,0, 3, H
710,6, 0,0, 3, H
Clsn2: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
6,0, 0,0, 2
Clsn2: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
11,0, 0,0, 2
Ken's animations are a bit different here, most notably Ken has an additional sprite and straightens up faster. I feel like keeping Ryu's ones this time, for the same reason as the run. Still, I'm regrouping the sprites under 710.
POWER CHARGE
There's not much room for creativity in this section. There's no reason for changes unless you want to change the mechanic itself for whatever reason.
The code itself is pretty self-explanatory. There's a PowerAdd state tied to the command and the amount of power, with a mathematic value that can be changed to speed/slow down the gain. Then there's the flash, the universal helpers, grunt sounds, and an end state.
As far as differences go, in the old Ryu the power charge was state 740. As usual, I'll change that. Other than that, there's an additional StateDef for the end in the newer characters, so I'll be adding it, even though I don't think it makes any true difference. Let's charge in.
Spoiler, click to toggle visibilty
;==========<POWER CHARGE>==========
[StateDef 730]
type = S
physics = S
moveType = I
anim = 730
velSet = 0,0
ctrl = 0
[State 730, PowerAdd]
type = PowerAdd
triggerAll = Power < const(data.power) && Power < PowerMax
trigger1 = !AILevel && (command = "holdb" && command = "holdy")
trigger2 = AILevel
value = 2 + ifElse(Time < 60, 0, (Time - 60) / 12)
[State 730, Voice]
type = PlaySnd
trigger1 = Anim = 730 && Time = 8
value = 3 + (var(1) = 2) * 10, 5 + (var(1) = 2)
channel = 0
[State 730, Character Flash]
type = PalFX
trigger1 = 1
time = 1
add = 75 + ceil(sin(Time / 6.0 * pi) * 75), 25 + ceil(sin(Time / 6.0 * pi) * 25),0
[State 730, Power Charge Helper]
type = Helper
trigger1 = !NumHelper(8330)
helperType = Normal
stateNo = 8330
ID = 8330
name = "Power Charge"
posType = P1
pos = 0,0
pauseMoveTime = 65535
superMoveTime = 65535
ownPal = 1
[State 730, Particles]
type = Helper
trigger1 = !NumHelper(8331)
helperType = Normal
stateNo = 8331
ID = 8331
name = "Particles"
postype = P1
pauseMoveTime = 65535
superMoveTime = 65535
ownPal = 1
[State 730, End]
type = ChangeState
trigger1 = Power >= const(data.power) || Power >= PowerMax || RoundState != 2
trigger2 = !AILevel && (command != "holdb" || command != "holdy")
trigger3 = AILevel && (InGuardDist || P2BodyDist x <= 120)
value = 731
ctrl = 1
;Power Charge End
[StateDef 731]
type = S
physics = S
moveType = I
anim = 731
velSet = 0,0
ctrl = 1
[State 731, StopSnd]
type = StopSnd
trigger1 = !Time
channel = 0
[State 731, Full Power Voice]
type = PlaySnd
trigger1 = !Time && Power >= const(data.power)
value = 4 + (var(1) = 2) * 10, 10 - (var(1) = 2)
channel = 0
persistent = 0
[State 730, End]
type = ChangeState
trigger1 = !AnimTime
value = 0
ctrl = 1
One thing you need to note is the position of the helper, which must fit the animation. In this case, pos = 0,0 works just fine. By the way, I didn't say that until now, but we'll tackle all these explods later, all at once.
Of course, we need the appropriate 730 and 731 anims.
Spoiler, click to toggle visibilty
;Power Charge
[Begin Action 730]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
700,0, 0,0, 3
700,1, 0,0, 3
Loopstart
730,0, 0,0, 3
730,1, 0,0, 3
We only have two sprites on this group. It's fine though, this is one of those animation we can pretty much customize around without affecting the gameplay.
;Power Charge (End)
[Begin Action 731]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
760,3, 0,0, 4
760,4, 0,0, 4
The last two sprites are from the soon-to-be-reassigned parry group, formerly 700.
ZERO COUNTER
Ah, the beloved SFA mechanic. Call me a scrub, but I never managed to pull these off during an actual fight... I'm more of an offensive player. And by that I mean that you'll probably get offended by how much of a scrub I am.
Again, not much to customize here except maybe the attacks tied to the counter. Let's, uh, zero counter in.
Spoiler, click to toggle visibilty
;====================<ZERO COUNTER>====================
[StateDef 750]
type = S
physics = S
moveType = I
anim = 750
velSet = 0,0
ctrl = 0
sprPriority = 2
powerAdd = -1000
faceP2 = 1
[State 750, Button]
type = VarSet
trigger1 = !Time && !AILevel
var(10) = (command = "412k")
ignoreHitPause = 1
[State 750, Button (AI)]
type = VarSet
trigger1 = !Time && AILevel
var(10) = ifElse((P2StateType = A), 0, ifElse((P2StateType = C), 1, ifElse(Random < 500, 0, 1)))
ignoreHitPause = 1
[State 750, NotHitBy]
type = NotHitBy
trigger1 = 1
value = SCA
time = 1
[State 750, PosFreeze]
type = PosFreeze
trigger1 = 1
value = 1
[State 750, Voice]
type = PlaySnd
trigger1 = !Time
value = 3 + (var(1) = 2) * 10, 7 - (var(1) = 2) * 4
channel = 0
[State 750, Zero Counter FX Helper]
type = Helper
trigger1 = !Time
helperType = Normal
stateNo = 8350
ID = 8350
name = "Zero Counter"
posType = P1
pos = 16, -79
superMoveTime = 255
ownPal = 1
[State 750, SuperPause]
type = SuperPause
trigger1 = !Time
time = 15
moveTime = 15
p2DefMul = 1
anim = -1
sound = s750,0
darken = 0
[State 750, End]
type = ChangeState
trigger1 = Time >= 15
value = ifElse(var(10) = 1, 255, 1100)
Once again, the position of the helper must fit the animation, so pay extra care. For the SuperPause, I need to remember to rearrange the sounds. Good thing I have this post as a reference.
One thing I was confused about is the button detect. There's new variable in play here, which we'll see a lot again, so I'll spend two words on it. Var(10) is the button detect trigger. Basically, If you input the punch (412p) command, you'll set the var to = 0 and the 1100 (a Shoryuken) attack will be triggered. If you input the kick (412k) command, you'll set it to = 1 and the 255 (HK) attack will be triggered.
These two attacks themselves can be customized by simply replacing the values with those corresponding to other attacks. I was thinking about putting the Jouen kick instead of the HK, but at the end I decided to leave things as they are.
Spoiler, click to toggle visibilty
;Zero Counter
[Begin Action 750]
Clsn2Default: 1
Clsn2[0] = -17, -78, 17, 0
700,0, 0,0, 1
700,1, 0,0, 1
Loopstart
750,0, 0,0, 3
750,1, 0,0, 3
No need to reassign anything this time. The two sprites we need are in group 750.
PARRY
Since this is a pretty universal move in P.o.t.S styled chars, I found no differences between reference characters as far as the actual code goes. Ryu had some negligible difference, the biggest one being the StateDef number (700). Let's parry carry on (this is getting weird).
Spoiler, click to toggle visibilty
;====================<PARRY>====================
;Standing Parry
[StateDef 760]
type = S
physics = S
moveType = I
anim = 760
velSet = 0,0
ctrl = 0
sprPriority = 2
powerAdd = 78
faceP2 = 1
[State 760, HitBy]
type = HitBy
trigger1 = 1
value = SCA,AT
time = 1
[State 760, Pause]
type = Pause
trigger1 = !Time
time = 15
moveTime = 15
endCmdBufTime = 15
pauseBg = 0
; there was a second Pause block on old Ryu's code,
; but I decided it wasn't necessary and I scrapped it
[State 760, Stop]
type = PosFreeze
trigger1 = 1
value = 1
[State 760, No Walking]
type = VarSet
trigger1 = 1
var(26) = 7
[State 760, Voice]
type = PlaySnd
trigger1= !Time
value = 3 + (var(1) = 2) * 10, 6 - (var(1) = 2) * 3
channel = 0
[State 760, Parry Sound]
type = PlaySnd
trigger1 = !Time
value = 760,0
channel = 1
[State 760, Player Flash]
type = PalFX
trigger1 = !Time
add = 0,64,255
sinadd = 0,-64,-255,60
time = 15
; values were slightly different on old Ryu, but I never
; really noticed any difference to be honest. Am I
; colorblind? Oh no
[State 760, FX]
type = Explod
trigger1 = !Time
anim = 8360
sprPriority = 5
posType = P1
pos = ceil(23 * const(size.xscale)), ceil(-76 * const(size.yscale))
pauseMoveTime = -1
superMoveTime = -1
scale = 0.5,0.5
ownPal = 1
[State 760, EnvShake]
type = EnvShake
trigger1 = !Time
time = 0
ampl = 0
[State 760, End]
type = ChangeState
trigger1 = !AnimTime
value = 0
ctrl = 1
As always, pay extra attention to the position of the hitspark Explod. This time I found some raw numbers in some reference characters, and ceil-based ones in others, including Ryu. I honestly don't see which is the advantage of using one instead of the other, I'd like to hear some opinions.
Spoiler, click to toggle visibilty
;Crouching Parry
[StateDef 761]
type = C
physics = C
moveType = I
anim = 761
velSet = 0,0
ctrl = 0
sprPriority = 2
powerAdd = 78
faceP2 = 1
[State 761, HitBy]
type = HitBy
trigger1 = 1
value = SCA,AT
time = 1
[State 761, Pause]
type = Pause
trigger1 = !Time
time = 15
moveTime = 15
endCmdBufTime = 15
pauseBg = 0
[State 761, PosFreeze]
type = PosFreeze
trigger1 = 1
value = 1
[State 761, No Walk]
type = VarSet
trigger1 = 1
var(26) = 7
[State 761, Voice]
type = PlaySnd
trigger1 = !Time
value = 3 + (var(1) = 2) * 10, 6 - (var(1) = 2) * 3
channel = 0
[State 761, Parry Sound]
type = PlaySnd
trigger1 = !Time
value = 760,0
channel = 1
[State 761, Player Flash]
type = PalFX
trigger1 = !Time
add = 0,64,255
sinAdd = 0,-64,-255,60
time = 15
[State 761, Parry FX]
type = Explod
trigger1 = !Time
anim = 8360
sprpriority = 5
postype = P1
pos = ceil(23 * const(size.xscale)), ceil(-48 * const(size.yscale))
pauseMovetime = -1
superMovetime = -1
scale = 0.5,0.5
ownpal = 1
[State 761, EnvShake]
type = EnvShake
trigger1 = !time
time = 0
ampl = 0
[State 761, End]
type = ChangeState
trigger1 = !AnimTime
value = 11
ctrl = 1
;Jumping Parry
[StateDef 762]
type = A
physics = N
moveType = I
anim = 762
ctrl = 0
sprPriority = 2
powerAdd = 78
faceP2 = 1
[State 762, HitBy]
type = HitBy
trigger1 = 1
value = SCA,AT
time = 1
[State 762, Pause]
type = Pause
trigger1 = !Time
time = 15
moveTime = 15
endCmdBufTime = 15
pauseBg = 0
[State 762, PosFreeze]
type = PosFreeze
trigger1 = 1
value = 1
[State 762, Voice]
type = PlaySnd
trigger1 = !Time
value = 3 + (var(1) = 2) * 10, 6 - (var(1) = 2) * 3
channel = 0
[State 762, Parry Sound]
type = PlaySnd
trigger1 = !Time
value = 760,0
channel = 1
[State 762, Player Flash]
type = PalFX
trigger1 = !Time
add = 0,64,255
sinadd = 0,-64,-255,60
time = 15
[State 762, Parry FX]
type = Explod
trigger1 = !Time
anim = 8360
sprPriority = 5
posType = P1
pos = ceil(16 * const(size.xscale)), ceil(-84 * const(size.yscale))
pauseMoveTime = -1
superMoveTime = -1
scale = 0.5,0.5
ownpal = 1
[State 762, EnvShake]
type = EnvShake
trigger1 = !Time
time = 0
ampl = 0
[State 762, End]
type = ChangeState
trigger1 = !AnimTime
value = 763
ctrl = 1
;Falling
[StateDef 763]
type = A
physics = N
movetype = I
anim = 763
ctrl = 1
[State 763, VelSet]
type = VelSet
trigger1 = !Time
x = ifElse(vel x > 2, 2, ifElse(vel x < -2, -2, vel x))
y = ifElse(vel y < -2, vel y, -2)
[State 763, Gravity]
type = Gravity
trigger1 = 1
[State 763, Landing]
type = ChangeState
trigger1 = pos y > -vel y
value = 52
Nothing much to say here, it's pretty much the same code again adapted to the crouching and aerial states. Newer characters had an extra StateDef for the falling after the aerial parry, which I gave to Ryu too, of course.
Spoiler, click to toggle visibilty
;Standing Parry
[Begin Action 760]
Clsn2Default: 1
Clsn2[0] = -17, -78, 17, 0
760,0, 0,0, 1
760,1, 0,0, 1
760,2, 0,0, 10
760,3, 0,0, 2
760,4, 0,0, 1
The standing parry animation is a LOT different on Ken, seems like Ryu has got additional sprites. The following two, not so much.
;Crouching Parry
[Begin Action 761]
Clsn2Default: 1
Clsn2[0] = -17, -78, 17, 0
761,0, 0,0, 2
761,1, 0,0, 10
761,0, 0,0, 3
;Jumping Parry
[Begin Action 762]
Clsn2Default: 1
Clsn2[0] = -21, -102, 26, -34
762,0, 0,0, 2
762,1, 0,0, 10
762,0, 0,0, 3
;Jumping Parry (Falling)
[Begin Action 763]
Clsn2Default: 1
Clsn2[0] = -21, -102, 26, -34
41,6, 0,0, 4
41,7, 0,0, 4
41,8, 0,0, -1
This is my first true new animation. No biggie, but still. Ryu's old jumping parry state had the falling part included, but newer characters separated the falling part in a new StateDef. As such, I needed to split Ryu's old jumping parry anim into two: the actual parry and the falling. For reference, this is the old animation:
;
[Begin Action 702]
Clsn2Default: 1
Clsn2[0] = -20, -112, 20, -32
702,0, 0,0, 2
702,1, 0,0, 10
702,0, 0,0, 3
41,1, 0,0, 3
41,0, 0,0, -1
The following is the Parry explod.
;Parry FX
[Begin Action 8360]
8360,0, 0,0, 1,, A
8360,1, 0,0, 1,, A
8360,2, 0,0, 1,, A
8360,3, 0,0, 1,, A
8360,4, 0,0, 1,, A
8360,5, 0,0, 1,, A
8360,6, 0,0, 1,, A
8360,7, 0,0, 1,, A
8360,8, 0,0, 1,, A
8360,9, 0,0, 1,, A
8360,10, 0,0, 1,, A
8360,11, 0,0, 1,, A
8360,12, 0,0, 1,, A
8360,13, 0,0, 1,, A
8360,14, 0,0, 1,, A
8360,15, 0,0, 1,, A
8360,16, 0,0, 1,, A
8360,17, 0,0, 1,, A
8360,18, 0,0, 1,, A
8360,19, 0,0, 1,, A
And that's it for today. Next time I'll be handling the Custom Combo, which will be fun for me, since it has always been something I wanted to learn to implement. And then the Safe Fall and Fall Recovery, and probably the Guard states too.
Before hitting the button, I want to thank everyone who commented and supported my first post. I received much more constructive criticism than I expected, and I appreciated every advice. If I sometimes sound like I don't really know what I'm doing it's because it is mostly true, so please bear with me. But one of the goals of these posts is to learn something, and hopefully give others something they can learn upon. So, I invite everyone to give criticisms and point out any mistake.
Until we meet again, humans! Now I'll restart the audiobook cause I wasn't really listening to it. I'm no multitasker I'm afraid.
Previous parts:
Part 1: Basic Movements
Next parts:
Part 3: Custom Combo, Recovery, Guard
Part 4: Lose and Intro animations
Part 5: Constants, Win animations, Taunts
Part 6: Universal Helpers