Have you ever looked at a Capcom character and noticed that their animation plays through the pausetime? Think it's just there to make the animations look nice?
Yyyyyeah, turns out, no, it's more than just aesthetics. It's actually VERY important.
Kyosuke, for instance, absolutely HAS to do this in order for links to work properly:
Without:
(http://i116.photobucket.com/albums/o19/Yesujira/mugen627_zps7394fd65.png)
With:
(http://i116.photobucket.com/albums/o19/Yesujira/mugen628_zps1d212310.png)
See the frame advantage? A whopping +5 as opposed to +2. If he didn't have this, his s.LP → s.HP (close) link would be impossible to do.
So, how do you do it?
[State 205, Time Offset]
type = VarSet
trigger1 = moveContact = 1
var(x) = Time
ignorehitpause = 1
persistent = 0
[State 205, Play Anim]
type = ChangeAnim
triggerall = AnimElemTime(y) >= 0 && AnimElemTime(z) <= 0
trigger1 = hitPauseTime = [1,{pausetime} - ({total number of frames up until the end of the first frame of animation} - Var(x))]
value = anim
elem = z
ignorehitpause = 1
(simplified for the sake of education since my system has scary-looking variables)
So, let's use Kyosuke as an example:
(http://i.imgur.com/vCRnN2h.png)
You see the circled 3 ticks? Fighter Factory displays this. What it's saying is, "3 ticks will have passed after this frame ends." The current frame lasts 2 ticks, so 2 ticks AND ONLY 2 ticks of that frame need to play, regardless of any pause. That's why we have the time offset variable.
Now, that's AnimElem 2, and we want it to skip to the next AnimElem, which is 3, and then pause there. The time you use for pausetime is the EXACT pausetime you define in the HitDef.
pausetime = 9,9
So, with all that in mind, now the code will look something like this:
[State 205, Time Offset]
type = VarSet
trigger1 = moveContact = 1
var(x) = Time
ignorehitpause = 1
persistent = 0
[State 205, Play Anim]
type = ChangeAnim
triggerall = AnimElemTime(2) >= 0 && AnimElemTime(3) <= 0
trigger1 = hitPauseTime = [1,9 - (3 - Var(x))]
value = anim
elem = 3
ignorehitpause = 1
But what about custom combo? It halves the pausetime! No problem!
[State 205, Time Offset]
type = VarSet
trigger1 = moveContact = 1
var(x) = Time
ignorehitpause = 1
persistent = 0
[State 205, Play Anim]
type = ChangeAnim
triggerall = AnimElemTime(2) >= 0 && AnimElemTime(3) <= 0
trigger1 = hitPauseTime = [1,ceil(9*(2-(Var(c)>0))/2) - (3 - Var(x))]
value = anim
elem = 3
ignorehitpause = 1
Where Var(x) is your time offset variable, and Var(c) is your custom combo variable.
Now, you've probably seen a different method used in Warusaki3's and GM's stuff that accomplishes this same thing, but that requires making a "buffer" for each move during custom combo. That's a pain to have to do. This method lets you bypass all of that!
Big thanks goes to H" for finding this method.
I'm under the assumption that you'd have to duplicate the controllers for each instance, so for example, say the move has active frames on animation elements 3 and 5, then your code would be:
[State 205, Time Offset]
type = VarSet
trigger1 = animelemtime(3)>=0&&animelemtime(4)<0
trigger1 = moveContact = 1
var(x) = Time
ignorehitpause = 1
persistent = 0
[State 205, Time Offset]
type = VarSet
trigger1 = animelemtime(5)>=0&&animelemtime(6)<0
trigger1 = moveContact = 1
var(x) = Time
ignorehitpause = 1
persistent = 0
[State 205, Play Anim]
type = ChangeAnim
triggerall = hitPauseTime = [1,9 - (3 - Var(x))]
trigger1 = AnimElemTime(3) >= 0 && AnimElemTime(4) <= 0
trigger2 = AnimElemTime(5) >= 0 && AnimElemTime(6) <= 0
value = anim
elem = ifelse(AnimElemTime(3) >= 0 && AnimElemTime(4)<=0,4,6)
ignorehitpause = 1
You'd probably need to use a movehitreset controller or some other type of flag to get it to work perfectly, but this should illustrate the general idea.
But from what I can tell, this seems to solve the issue of having to wait for the hitpause to end before being able to cancel into something else? Though I only noticed a 1 frame difference in the frame advantages as opposed to the 3 frame difference in the OP, unless there's something there that I'm missing.
Edit: Scratch that. I goofed by putting the number of active frames instead of the total duration that would have elapsed after the last active frame. Another question is that the above code assumes that there are non-active frames in between each active frame for each hit, what about cases where the two active frames are back to back? Would they be handled the same way?
Byakko's simplistic idea solved the issue.
[State 255, Time Offset]
type = VarSet
trigger1 = moveContact = 1
var(2) = Time
ignorehitpause = 1
persistent = 0
[State 255, Play Anim]
type = ChangeAnim
;triggerall = AnimElemTime(22) >= 0 && AnimElemTime(27) <= 0
triggerall = AnimElemNo(0) = 3
trigger1 = hitPauseTime = [1,8 - (27 - Var(2))]
value = anim
elem = 4
ignorehitpause = 1
To test this you'll notice that I changed the 1st attack frame to be 22 ticks. This way I could have player 2 land on it after the 1st tick easier and see if it would work correctly. It did, the 1st frame continued to go through the remaining ticks to 22 then went to the next frame where it proceeded to apply the hitpause.
I don't know why JZ used AnimElemTime instead of just AnimElemNo but this seems to work correctly and is simpler!
*old coding commented out in example
Posted: June 04, 2014, 11:28:46 pm
Okay, the mistake was all mine
Spoilering where Byakko pointed out I just wasn't grasping animelemno at all apparently Long story short, JZ's coding is right and I was just dumb =p
Spoiler, click to toggle visibilty
It's probably a matter of preference and what you find easier to read, but now that I look more closely at what you have and what Jesuszilla posted in the tips section --
triggerall = AnimElemTime(2) >= 0 && AnimElemTime(7) <= 0
This trigger when the current animation element is between 2 and 7, and that includes 5, 6, 7. You mixed that up with just plain time, I assume you were trying to trigger it between the second and seventh tick because the second element lasted 5 ticks or something.
The different AnimSomething triggers can be confusing at first, they seem close but you easily miss the nuances (especially in the format they can use, like how you can write "AnimElem = 2, >= 57" but you can do that for the others). You can either try to study them all very closely before trying to copy-paste-tweak something you don't fully get, or just pick one and learn how to use it for everything. I like AnimElemNo(0) the best myself to know the current element, it's the one you can use in most situations with cancels and whatnot (since they often depend on the frame currently displayed and not how many ticks have passed). When you're learning, it's easier than trying to first figure out which one you want and then you still have to figure out how to use it.
You are absolutely correct. And I see where I got mixed up.
So, let's use Kyosuke as an example:
(http://i.imgur.com/vCRnN2h.png)
You see the circled 3 ticks? Fighter Factory displays this. What it's saying is, "3 ticks will have passed after this frame ends." The current frame lasts 2 ticks, so 2 ticks AND ONLY 2 ticks of that frame need to play, regardless of any pause. That's why we have the time offset variable.
Now, that's AnimElem 2, and we want it to skip to the next AnimElem, which is 3, and then pause there. The time you use for pausetime is the EXACT pausetime you define in the HitDef.
Since, as you said, I didn't fully grasp this trigger I mistook what was being said in the quote above as my time and not frames. I was thinking that the >= 0 was referring to the time starting from tick 2 or something. It made "wrong" sense in my head at the time at least.
Correcting that made JZ's coding work too. He was never wrong (I should have never doubted you JZ)
Looking a fool aside at least now I fully understand AnimElemNo -_-