Ricepigeon

Ricepigeon's Coding Tutorial & Code Snippet Repository

14 posts in this topic

Workaround for Missing "ParentExist" Trigger

Compatibility:

WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN
yes.png
yes.png
no.png
yes.png

 

 

Have you ever had a situation where you needed to create a complex projectile or effect that utilized a single helper creating multiple helpers that were bound to it, only to encounter a glitch where, in the event that the parent helper was destroyed, the child helpers would just sorta stay on screen and Mugen's debug is spitting out complaints that all your child helper's bindtoparent controllers have no parent to bind to. You rush to alter your child helper's Destroyself controller, only to realize that there is no "ParentExist" trigger you can use to force them to destroy themselves. Sounds like all hope is lost right? Fortunately there is a clever workaround using trigger redirection.

 

For each parent helper, you'll need to reserve one variable for a unique ID, while each child helper will require two variables; one to keep track of the parent's unique ID, and one to keep track of the parent helper's playerID, which is created by the engine each time a helper is created and are periodically recycled as helpers are destroyed and new helpers created to take their place.

 

In the first state of parent helper, at the following line of code to the beginning of its state:

[State 20000, Parent ID]
type = varset
trigger1 = time = 0
var(0) = random*1000+random


This will generate a unique, 8-digit ID when the parent helper is created. You only have to set this once each time the helper is created, even if the helper goes through multiple states. Note that there is a very small chance (approx 0.0001%) that the same ID will be created twice, but the chance is so miniscule that this will rarely, if ever, happen. That's all for the parent helper.

 

The child helper is where things start to get a bit complicated, so I'll go through each part here. In the first state the child helper is created in, add the following to the beginning of the state:

[State 20010, Parent Destruct Safeguard]
type = varset
trigger1 = time = 0
var(1) = parent,id ;Set to parent's PlayerID

[State 20010, Parent Destruct Safeguard]
type = varset
trigger1 = time = 0
trigger1 = playeridexist(var(1))
var(0) = playerid(var(1)),var(0)

 

What you are basically doing is copying the values of both the parent helper's playerID (which is set by the engine) and the 8-digit ID that you generated earlier, into the child helper. The reason for copying both of these values into the child helper is to check for two possible scenarios:

 

  • Scenario 1: Parent no longer exists, Helper with Parent's Player ID doesn't exist
  • Scenario 2: Helper with Parent's Player ID exists, but unique ID don't match

 

Scenario 1 is pretty straightforward; if a helper with the parent helper's PlayerID doesn't exist, then that means that the parent helper doesn't exist and you can safely destroy the child helper.

 

Scenario 2 is a bit more complicated to understand, and requires a bit of understanding of how the MUGEN engine assigns PlayerIDs. As stated before, PlayerIDs are recycled by the engine each time a helper is destroyed; MUGEN will typically use the first available free PlayerID in these cases. In other words, you may run into situations where a helper with the parent's PlayerID exists, but the helper with that ID was actually created after the actual parent helper destroyed itself! It is for this reason that we needed that unique 8-digit ID number, as PlayerID alone is not enough to check if the parent helper no longer exists.

 

To satisfy both of these scenarios when checking to see if a child helper's parent exists, your triggers should typically look something like this:

 

trigger1 = !playeridexist(var(1))
trigger2 = playeridexist(var(1))
trigger2 = playerid(var(1)),var(0) != var(0)

 

Trigger1 will satisfy the first scenario; because there is no helper that exists with the parent helper's PlayerID, we can safely say that the parent was destroyed.
Both Trigger2s satisfy the second scenario; a helper exists with the same PlayerID as our child helper's parent, but their unique 8-digit ID number does not match what we initially recorded, indicating that the original parent helper was destroyed.

 

If you want to prevent any unusual debug errors, you should also add the following triggers to all State Controllers utilizing a parent that isn't the root (ie ParentVarSet, BindToParent, etc.):

 

triggerall = playeridexist(var(1))
triggerall = playerid(var(1)),var(0) = var(0)

 

These triggers will check for the same consistency as the ones we defined above. If everything checks out, then the state controllers will execute without any problems. Otherwise, the controllers will not execute and prevent unnecessary debug flood.

Share this post


Link to post
Share on other sites

Hitdefs with Multiple Attributes

Compatibility:

WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN
yes.png
yes.png
yes.png
no.png

 

 

Ever wondered if you could assign multiple properties to a hitdef, but didn't want multiple hitdefs conflicting with each other each tick? Thanks to a discovery by a friend of mine, you might not need to:

Quote

DoomBowser: ...
DoomBowser: Why the hell is it possibly to assign multiple attributions to a hitdef?
DoomBowser: Elecbyte wtf
Midori: WAIT WHAT
Jenngra505: Does this mean we can make Command Normals by having it be both a Normal and a Special?
DoomBowser: No
DoomBowser: It means it's both a Normal and a Special
DoomBowser: At the same time
DoomBowser: I need to look further into this
DoomBowser: Set a character's LP to be both NA and NP
DoomBowser: The attack still interacts with counters that only counter melee attacks, but also interacts with things like Yukari's gap, which only absorbs projectiles
DoomBowser: So it's both a melee attack and a projectile at the same time
DoomBowser: But why is this possible, and for what reason?
Midori: so you can type A,SA,SP?
DoomBowser: Yes, and it would probably be both
Midori: oh damn
Midori: Question
Midori: what happens if you put a hitdef that's NA,NT and there was a NotHitBy by NT
DoomBowser: I need to double check that one
DoomBowser: The opponent gets hit
Midori: !!!!
Jenngra505: Can you have an attack that's standing, crouching and aerial all at once?
DoomBowser: By the looks of it, yes
DoomBowser: SCA,NA,NP,NT,SA,SP,ST,HA,HP,HT is completely valid for a hitdef's attr parameter
DoomBowser: What's odd is that this is an extension of what I found with that crappy Futo the other day where there's AA, AP and AT functions
DoomBowser: S,AA = Standing Normal/Special/Hyper Attack
DoomBowser: Then I just happen do find the multi-function parameter in Aperson's Robotnik
DoomBowser: Robotnik's Pissed off slap worked both against Youmu's melee counter and Yukari's gap, because the hitdef attribution is S, SA,AP
RicePigeon: can we get a gif of him using it on the gap just for lulz?
DoomBowser: Sure
DoomBowser: .eJwNzNERgyAMANBdGIBgxFx0jG5AEZGrEg_iV6-

DoomBowser: It's a bit of a cheaply made gif, but you get the point
RicePigeon: oh man thats fresh
RicePigeon: lol
RicePigeon: and its not even Yukari's fault this time :p
RicePigeon: assuming Doom hasnt done it already, Im gonna go post that finding about the hitdef's attr parameter on guild
RicePigeon: out of curiousity if you have an attack classed as S,SA,SP and the opponent has two different hitoverrides active, one for melee and the other for projectiles, which one takes precedence?
DoomBowser: I haven't checked that one
DoomBowser: Is there a character I can test this on? I'm not sure if I have a character like that on me
RicePigeon: none that I know of, but I can probably whip up something real quick for testing purposes
DoomBowser: Alrighty then
RicePigeon: Okay so just tested it
RicePigeon: it seems like the hitoverride with the lower slot number takes precedence
RicePigeon: tested it first with the melee override in slot 0 and projectile in slot 1, the melee override took effect
RicePigeon: reversed the slots and the projectile override occurred
RicePigeon: Imagine what kind of broken shit you can do with this discovery

 

The tested code in question:

 

[Statedef -2]
[State 0, HitOverride]
type = HitOverride
trigger1 = 1
attr = SCA,AA
slot = 1;0
stateno = 1200 ;Melee counter state
time = 1
forceair = 0
ignorehitpause = 1
[State 0, HitOverride]
type = HitOverride
trigger1 = 1
attr = SCA,AP
slot = 0;1
stateno = 1300 ;Projectile counter state
time = 1
forceair = 0
ignorehitpause = 1

 

Other stuff to make note of due to this bug:

 

  • If an attack is attributed as multiple levels and KOs the opponent, MUGEN will flag the victory condition in the order of Special, Hyper, and Normal (ie: S,NA,SA,HA will be attributed as a Special).
  • Similarly, MUGEN will prioritize the Throw win flag if the attack is attributed as a combination of Throw and either Attack or Projectile.

 

Both of these conditions will ignore the ordering of multiple hitoverrides.

 

Some practical uses of this bug include the ability to code melee attacks that can destroy helper-based projectiles without needing to code in an additional Helper to handle projectile collisions:

.eJwFwdsNgCAMAMBdGIACbcC6DUGCJvII1C_j7t6

 

Share this post


Link to post
Share on other sites

Asymmetrical Palette Display using ReMapPal (aka The Gill Effect)

Compatibility:

WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN
no.png
yes.png
yes.png
yes.png

 

 

You've probably heard of the term "Gill Effect" or something similar before if you've ever played any of the Street Fighter III games; a character with an asymmetrical color scheme on their body. In Mugen, attempting to replicate this would require a duplicate of every sprite with the reversed palette, but even then custom states cause a problem. With the ReMapPal controller introduced in Mugen 1.0, this can now be done easily with a simple controller:

 

 

The idea is simple; using the new SFFv2 format, instead of duplicating each sprite, duplicate each palette and then remap the palettes with the new controller depending on the direction the character is facing. However, keep in mind that executing a ReMapPal controller conflicts with an earlier state controller; PalFx.

To get an idea of what I'm talking about, here we have the same attack which puts p2 into a custom state that applies a PalFX controller to simulate being frozen. One default Kung Fu Man, while the other is a character that continuously applies a ReMapPal controller in her -2 state in order to simulate the Gill effect;

 

0JcsXpn.png

 

Purely discovered by accident, I was easily able to find a workaround to this by, rather than continuously applying ReMapPal, instead only apply the controller when it needs to be. This can be done with a variable to act as a flag and compare it to the current direction the character is facing. If they do not match, only then should ReMapPal be applied, with the flag set to that facing value to avoid the controller being executed again until needed. This isn't a perfect workaround, however, as custom states that both apply a PalFX controller and repeatedly changing the opponent's facing direction may still cause the PalFX to end prematurely.

 

In the end, to address the issue outlined above, your code should look something like this:

 

Quote

 

[State -2, GILL SYNDROME]

type = RemapPal

trigger1 = facing = 1

trigger1 = var(26)!=1

source = 1,1

dest = 1+0*(var(26):=1),palno

 

[State -2, GILL SYNDROME]

type = RemapPal

trigger1 = facing != 1

trigger1 = var(26)!=2

source = 1,1

dest = 2+0*(var(26):=2),palno

 

 

The way it works is simple: You'll need a variable to keep track of which direction your character is facing: 1 for facing right, 2 for facing left. Additionally, you'll need to have two palette groups for each direction as well. The above code will check which direction you're currently facing and if you were previously facing the opposite direction; if you were, change the palette to the opposite palette group, otherwise don't change anything. This will also simultaneously set the value of the palette group to use.

Share this post


Link to post
Share on other sites

More Efficient Random Number Spreads

Compatibility:

WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN
yes.png
yes.png
yes.png
yes.png

 

Many times I've seen authors use modulo division to generate a spread of random numbers for whatever purpose (be it for AI triggers, random animations, or whatever). For those who don't know what I'm talking about, I'm referring to pieces of code like this:

 

Quote

trigger1 = random%2 = 0

 

To understand why the above code is inefficient, we have to take a deeper look into the results its producing.

For those who don't already know, in MUGEN, random generates a random integer from 0 to 999 (effectively producing 1 of 1000 different values each time random is called), each with an equal probability of being returned by random. With the % operator, such as in expression X%Y, we are dividing value X by value Y and returning only the remainder as a result. 17%10, for example, would return 7 as its value (17/10 = 1 R7). If we were to apply modulo division to random, for instance, we would be generating a random value from 0 to 999 and then dividing this number by an arbitrary value and returning its remainder as a result. By applying modulo division to random, we expect to see results that have an equal probability of being generated, as follows:

 

Random%10 generates:

Quote

0 (10% probability)
1 (10% probability)
2 (10% probability)
3 (10% probability)
4 (10% probability)
5 (10% probability)
6 (10% probability)
7 (10% probability)
8 (10% probability)
9 (10% probability)

 

As we can see above, we have a nice even spread of the 10 possible values that random%10 can generate. While this works great for numbers that are factors of 1000 (such as 2, 4, 5, 10, 20, 50, 100, etc), more arbitrary values won't be as neat and organized.

 

As an arbitrary example, instead of 10 values, we try for 666 (which should return an even spread of numbers ranging from 0 to 665). The results are listed below:

Random%666 generates:

Spoiler

Number    Probability
0    0.20%
1    0.20%
2    0.20%
3    0.20%
4    0.20%
5    0.20%
6    0.20%
7    0.20%
8    0.20%
9    0.20%
10    0.20%
11    0.20%
12    0.20%
13    0.20%
14    0.20%
15    0.20%
16    0.20%
17    0.20%
18    0.20%
19    0.20%
20    0.20%
21    0.20%
22    0.20%
23    0.20%
24    0.20%
25    0.20%
26    0.20%
27    0.20%
28    0.20%
29    0.20%
30    0.20%
31    0.20%
32    0.20%
33    0.20%
34    0.20%
35    0.20%
36    0.20%
37    0.20%
38    0.20%
39    0.20%
40    0.20%
41    0.20%
42    0.20%
43    0.20%
44    0.20%
45    0.20%
46    0.20%
47    0.20%
48    0.20%
49    0.20%
50    0.20%
51    0.20%
52    0.20%
53    0.20%
54    0.20%
55    0.20%
56    0.20%
57    0.20%
58    0.20%
59    0.20%
60    0.20%
61    0.20%
62    0.20%
63    0.20%
64    0.20%
65    0.20%
66    0.20%
67    0.20%
68    0.20%
69    0.20%
70    0.20%
71    0.20%
72    0.20%
73    0.20%
74    0.20%
75    0.20%
76    0.20%
77    0.20%
78    0.20%
79    0.20%
80    0.20%
81    0.20%
82    0.20%
83    0.20%
84    0.20%
85    0.20%
86    0.20%
87    0.20%
88    0.20%
89    0.20%
90    0.20%
91    0.20%
92    0.20%
93    0.20%
94    0.20%
95    0.20%
96    0.20%
97    0.20%
98    0.20%
99    0.20%
100    0.20%
101    0.20%
102    0.20%
103    0.20%
104    0.20%
105    0.20%
106    0.20%
107    0.20%
108    0.20%
109    0.20%
110    0.20%
111    0.20%
112    0.20%
113    0.20%
114    0.20%
115    0.20%
116    0.20%
117    0.20%
118    0.20%
119    0.20%
120    0.20%
121    0.20%
122    0.20%
123    0.20%
124    0.20%
125    0.20%
126    0.20%
127    0.20%
128    0.20%
129    0.20%
130    0.20%
131    0.20%
132    0.20%
133    0.20%
134    0.20%
135    0.20%
136    0.20%
137    0.20%
138    0.20%
139    0.20%
140    0.20%
141    0.20%
142    0.20%
143    0.20%
144    0.20%
145    0.20%
146    0.20%
147    0.20%
148    0.20%
149    0.20%
150    0.20%
151    0.20%
152    0.20%
153    0.20%
154    0.20%
155    0.20%
156    0.20%
157    0.20%
158    0.20%
159    0.20%
160    0.20%
161    0.20%
162    0.20%
163    0.20%
164    0.20%
165    0.20%
166    0.20%
167    0.20%
168    0.20%
169    0.20%
170    0.20%
171    0.20%
172    0.20%
173    0.20%
174    0.20%
175    0.20%
176    0.20%
177    0.20%
178    0.20%
179    0.20%
180    0.20%
181    0.20%
182    0.20%
183    0.20%
184    0.20%
185    0.20%
186    0.20%
187    0.20%
188    0.20%
189    0.20%
190    0.20%
191    0.20%
192    0.20%
193    0.20%
194    0.20%
195    0.20%
196    0.20%
197    0.20%
198    0.20%
199    0.20%
200    0.20%
201    0.20%
202    0.20%
203    0.20%
204    0.20%
205    0.20%
206    0.20%
207    0.20%
208    0.20%
209    0.20%
210    0.20%
211    0.20%
212    0.20%
213    0.20%
214    0.20%
215    0.20%
216    0.20%
217    0.20%
218    0.20%
219    0.20%
220    0.20%
221    0.20%
222    0.20%
223    0.20%
224    0.20%
225    0.20%
226    0.20%
227    0.20%
228    0.20%
229    0.20%
230    0.20%
231    0.20%
232    0.20%
233    0.20%
234    0.20%
235    0.20%
236    0.20%
237    0.20%
238    0.20%
239    0.20%
240    0.20%
241    0.20%
242    0.20%
243    0.20%
244    0.20%
245    0.20%
246    0.20%
247    0.20%
248    0.20%
249    0.20%
250    0.20%
251    0.20%
252    0.20%
253    0.20%
254    0.20%
255    0.20%
256    0.20%
257    0.20%
258    0.20%
259    0.20%
260    0.20%
261    0.20%
262    0.20%
263    0.20%
264    0.20%
265    0.20%
266    0.20%
267    0.20%
268    0.20%
269    0.20%
270    0.20%
271    0.20%
272    0.20%
273    0.20%
274    0.20%
275    0.20%
276    0.20%
277    0.20%
278    0.20%
279    0.20%
280    0.20%
281    0.20%
282    0.20%
283    0.20%
284    0.20%
285    0.20%
286    0.20%
287    0.20%
288    0.20%
289    0.20%
290    0.20%
291    0.20%
292    0.20%
293    0.20%
294    0.20%
295    0.20%
296    0.20%
297    0.20%
298    0.20%
299    0.20%
300    0.20%
301    0.20%
302    0.20%
303    0.20%
304    0.20%
305    0.20%
306    0.20%
307    0.20%
308    0.20%
309    0.20%
310    0.20%
311    0.20%
312    0.20%
313    0.20%
314    0.20%
315    0.20%
316    0.20%
317    0.20%
318    0.20%
319    0.20%
320    0.20%
321    0.20%
322    0.20%
323    0.20%
324    0.20%
325    0.20%
326    0.20%
327    0.20%
328    0.20%
329    0.20%
330    0.20%
331    0.20%
332    0.20%
333    0.20%
334    0.10%
335    0.10%
336    0.10%
337    0.10%
338    0.10%
339    0.10%
340    0.10%
341    0.10%
342    0.10%
343    0.10%
344    0.10%
345    0.10%
346    0.10%
347    0.10%
348    0.10%
349    0.10%
350    0.10%
351    0.10%
352    0.10%
353    0.10%
354    0.10%
355    0.10%
356    0.10%
357    0.10%
358    0.10%
359    0.10%
360    0.10%
361    0.10%
362    0.10%
363    0.10%
364    0.10%
365    0.10%
366    0.10%
367    0.10%
368    0.10%
369    0.10%
370    0.10%
371    0.10%
372    0.10%
373    0.10%
374    0.10%
375    0.10%
376    0.10%
377    0.10%
378    0.10%
379    0.10%
380    0.10%
381    0.10%
382    0.10%
383    0.10%
384    0.10%
385    0.10%
386    0.10%
387    0.10%
388    0.10%
389    0.10%
390    0.10%
391    0.10%
392    0.10%
393    0.10%
394    0.10%
395    0.10%
396    0.10%
397    0.10%
398    0.10%
399    0.10%
400    0.10%
401    0.10%
402    0.10%
403    0.10%
404    0.10%
405    0.10%
406    0.10%
407    0.10%
408    0.10%
409    0.10%
410    0.10%
411    0.10%
412    0.10%
413    0.10%
414    0.10%
415    0.10%
416    0.10%
417    0.10%
418    0.10%
419    0.10%
420    0.10%
421    0.10%
422    0.10%
423    0.10%
424    0.10%
425    0.10%
426    0.10%
427    0.10%
428    0.10%
429    0.10%
430    0.10%
431    0.10%
432    0.10%
433    0.10%
434    0.10%
435    0.10%
436    0.10%
437    0.10%
438    0.10%
439    0.10%
440    0.10%
441    0.10%
442    0.10%
443    0.10%
444    0.10%
445    0.10%
446    0.10%
447    0.10%
448    0.10%
449    0.10%
450    0.10%
451    0.10%
452    0.10%
453    0.10%
454    0.10%
455    0.10%
456    0.10%
457    0.10%
458    0.10%
459    0.10%
460    0.10%
461    0.10%
462    0.10%
463    0.10%
464    0.10%
465    0.10%
466    0.10%
467    0.10%
468    0.10%
469    0.10%
470    0.10%
471    0.10%
472    0.10%
473    0.10%
474    0.10%
475    0.10%
476    0.10%
477    0.10%
478    0.10%
479    0.10%
480    0.10%
481    0.10%
482    0.10%
483    0.10%
484    0.10%
485    0.10%
486    0.10%
487    0.10%
488    0.10%
489    0.10%
490    0.10%
491    0.10%
492    0.10%
493    0.10%
494    0.10%
495    0.10%
496    0.10%
497    0.10%
498    0.10%
499    0.10%
500    0.10%
501    0.10%
502    0.10%
503    0.10%
504    0.10%
505    0.10%
506    0.10%
507    0.10%
508    0.10%
509    0.10%
510    0.10%
511    0.10%
512    0.10%
513    0.10%
514    0.10%
515    0.10%
516    0.10%
517    0.10%
518    0.10%
519    0.10%
520    0.10%
521    0.10%
522    0.10%
523    0.10%
524    0.10%
525    0.10%
526    0.10%
527    0.10%
528    0.10%
529    0.10%
530    0.10%
531    0.10%
532    0.10%
533    0.10%
534    0.10%
535    0.10%
536    0.10%
537    0.10%
538    0.10%
539    0.10%
540    0.10%
541    0.10%
542    0.10%
543    0.10%
544    0.10%
545    0.10%
546    0.10%
547    0.10%
548    0.10%
549    0.10%
550    0.10%
551    0.10%
552    0.10%
553    0.10%
554    0.10%
555    0.10%
556    0.10%
557    0.10%
558    0.10%
559    0.10%
560    0.10%
561    0.10%
562    0.10%
563    0.10%
564    0.10%
565    0.10%
566    0.10%
567    0.10%
568    0.10%
569    0.10%
570    0.10%
571    0.10%
572    0.10%
573    0.10%
574    0.10%
575    0.10%
576    0.10%
577    0.10%
578    0.10%
579    0.10%
580    0.10%
581    0.10%
582    0.10%
583    0.10%
584    0.10%
585    0.10%
586    0.10%
587    0.10%
588    0.10%
589    0.10%
590    0.10%
591    0.10%
592    0.10%
593    0.10%
594    0.10%
595    0.10%
596    0.10%
597    0.10%
598    0.10%
599    0.10%
600    0.10%
601    0.10%
602    0.10%
603    0.10%
604    0.10%
605    0.10%
606    0.10%
607    0.10%
608    0.10%
609    0.10%
610    0.10%
611    0.10%
612    0.10%
613    0.10%
614    0.10%
615    0.10%
616    0.10%
617    0.10%
618    0.10%
619    0.10%
620    0.10%
621    0.10%
622    0.10%
623    0.10%
624    0.10%
625    0.10%
626    0.10%
627    0.10%
628    0.10%
629    0.10%
630    0.10%
631    0.10%
632    0.10%
633    0.10%
634    0.10%
635    0.10%
636    0.10%
637    0.10%
638    0.10%
639    0.10%
640    0.10%
641    0.10%
642    0.10%
643    0.10%
644    0.10%
645    0.10%
646    0.10%
647    0.10%
648    0.10%
649    0.10%
650    0.10%
651    0.10%
652    0.10%
653    0.10%
654    0.10%
655    0.10%
656    0.10%
657    0.10%
658    0.10%
659    0.10%
660    0.10%
661    0.10%
662    0.10%
663    0.10%
664    0.10%
665    0.10%

 

The problem should be immediately clear: the values ranging from 0-333 each have a 0.20% probability, while values ranging from 334-665 each have a 0.10% probability. If this were an even spread, we should expect any value from 0-332 to be generated only 50% of the time, but instead we see that numbers in this range are generated 66.6% of the time! If we were relying on a number being generated from this range, random%666 would be returning these values TWICE as often as the rest of the spread.

 

The solution? Rather than using modulo division, we use the following:

Quote

floor(X*random/1000.0)

What this does is multiply arbitrary value X by random, then divide by 1000, then floor the result to produce an integer value. This results in a spread ranging from 0-X, but in a much more even fashion. Say we revise our above code to the following:

 

floor(666*random/1000.0) generates:
 

Spoiler

Number    Probability
0    0.20%
1    0.20%
2    0.10%
3    0.20%
4    0.10%
5    0.20%
6    0.10%
7    0.20%
8    0.10%
9    0.20%
10    0.10%
11    0.20%
12    0.10%
13    0.20%
14    0.10%
15    0.20%
16    0.10%
17    0.20%
18    0.10%
19    0.20%
20    0.10%
21    0.20%
22    0.10%
23    0.20%
24    0.10%
25    0.20%
26    0.10%
27    0.20%
28    0.10%
29    0.20%
30    0.10%
31    0.20%
32    0.10%
33    0.20%
34    0.10%
35    0.20%
36    0.10%
37    0.20%
38    0.10%
39    0.20%
40    0.10%
41    0.20%
42    0.10%
43    0.20%
44    0.10%
45    0.20%
46    0.10%
47    0.20%
48    0.10%
49    0.20%
50    0.10%
51    0.20%
52    0.10%
53    0.20%
54    0.10%
55    0.20%
56    0.10%
57    0.20%
58    0.10%
59    0.20%
60    0.10%
61    0.20%
62    0.10%
63    0.20%
64    0.10%
65    0.20%
66    0.10%
67    0.20%
68    0.10%
69    0.20%
70    0.10%
71    0.20%
72    0.10%
73    0.20%
74    0.10%
75    0.20%
76    0.10%
77    0.20%
78    0.10%
79    0.20%
80    0.10%
81    0.20%
82    0.10%
83    0.20%
84    0.10%
85    0.20%
86    0.10%
87    0.20%
88    0.10%
89    0.20%
90    0.10%
91    0.20%
92    0.10%
93    0.20%
94    0.10%
95    0.20%
96    0.10%
97    0.20%
98    0.10%
99    0.20%
100    0.10%
101    0.20%
102    0.10%
103    0.20%
104    0.10%
105    0.20%
106    0.10%
107    0.20%
108    0.10%
109    0.20%
110    0.10%
111    0.20%
112    0.10%
113    0.20%
114    0.10%
115    0.20%
116    0.10%
117    0.20%
118    0.10%
119    0.20%
120    0.10%
121    0.20%
122    0.10%
123    0.20%
124    0.10%
125    0.20%
126    0.10%
127    0.20%
128    0.10%
129    0.20%
130    0.10%
131    0.20%
132    0.10%
133    0.20%
134    0.10%
135    0.20%
136    0.10%
137    0.20%
138    0.10%
139    0.20%
140    0.10%
141    0.20%
142    0.10%
143    0.20%
144    0.10%
145    0.20%
146    0.10%
147    0.20%
148    0.10%
149    0.20%
150    0.10%
151    0.20%
152    0.10%
153    0.20%
154    0.10%
155    0.20%
156    0.10%
157    0.20%
158    0.10%
159    0.20%
160    0.10%
161    0.20%
162    0.10%
163    0.20%
164    0.10%
165    0.20%
166    0.10%
167    0.20%
168    0.10%
169    0.20%
170    0.10%
171    0.20%
172    0.10%
173    0.20%
174    0.10%
175    0.20%
176    0.10%
177    0.20%
178    0.10%
179    0.20%
180    0.10%
181    0.20%
182    0.10%
183    0.20%
184    0.10%
185    0.20%
186    0.10%
187    0.20%
188    0.10%
189    0.20%
190    0.10%
191    0.20%
192    0.10%
193    0.20%
194    0.10%
195    0.20%
196    0.10%
197    0.20%
198    0.10%
199    0.20%
200    0.10%
201    0.20%
202    0.10%
203    0.20%
204    0.10%
205    0.20%
206    0.10%
207    0.20%
208    0.10%
209    0.20%
210    0.10%
211    0.20%
212    0.10%
213    0.20%
214    0.10%
215    0.20%
216    0.10%
217    0.20%
218    0.10%
219    0.20%
220    0.10%
221    0.20%
222    0.10%
223    0.20%
224    0.10%
225    0.20%
226    0.10%
227    0.20%
228    0.10%
229    0.20%
230    0.10%
231    0.20%
232    0.10%
233    0.20%
234    0.10%
235    0.20%
236    0.10%
237    0.20%
238    0.10%
239    0.20%
240    0.10%
241    0.20%
242    0.10%
243    0.20%
244    0.10%
245    0.20%
246    0.10%
247    0.20%
248    0.10%
249    0.20%
250    0.10%
251    0.20%
252    0.10%
253    0.20%
254    0.10%
255    0.20%
256    0.10%
257    0.20%
258    0.10%
259    0.20%
260    0.10%
261    0.20%
262    0.10%
263    0.20%
264    0.10%
265    0.20%
266    0.10%
267    0.20%
268    0.10%
269    0.20%
270    0.10%
271    0.20%
272    0.10%
273    0.20%
274    0.10%
275    0.20%
276    0.10%
277    0.20%
278    0.10%
279    0.20%
280    0.10%
281    0.20%
282    0.10%
283    0.20%
284    0.10%
285    0.20%
286    0.10%
287    0.20%
288    0.10%
289    0.20%
290    0.10%
291    0.20%
292    0.10%
293    0.20%
294    0.10%
295    0.20%
296    0.10%
297    0.20%
298    0.10%
299    0.20%
300    0.10%
301    0.20%
302    0.10%
303    0.20%
304    0.10%
305    0.20%
306    0.10%
307    0.20%
308    0.10%
309    0.20%
310    0.10%
311    0.20%
312    0.10%
313    0.20%
314    0.10%
315    0.20%
316    0.10%
317    0.20%
318    0.10%
319    0.20%
320    0.10%
321    0.20%
322    0.10%
323    0.20%
324    0.10%
325    0.20%
326    0.10%
327    0.20%
328    0.10%
329    0.20%
330    0.10%
331    0.20%
332    0.10%
333    0.20%
334    0.20%
335    0.10%
336    0.20%
337    0.10%
338    0.20%
339    0.10%
340    0.20%
341    0.10%
342    0.20%
343    0.10%
344    0.20%
345    0.10%
346    0.20%
347    0.10%
348    0.20%
349    0.10%
350    0.20%
351    0.10%
352    0.20%
353    0.10%
354    0.20%
355    0.10%
356    0.20%
357    0.10%
358    0.20%
359    0.10%
360    0.20%
361    0.10%
362    0.20%
363    0.10%
364    0.20%
365    0.10%
366    0.20%
367    0.10%
368    0.20%
369    0.10%
370    0.20%
371    0.10%
372    0.20%
373    0.10%
374    0.20%
375    0.10%
376    0.20%
377    0.10%
378    0.20%
379    0.10%
380    0.20%
381    0.10%
382    0.20%
383    0.10%
384    0.20%
385    0.10%
386    0.20%
387    0.10%
388    0.20%
389    0.10%
390    0.20%
391    0.10%
392    0.20%
393    0.10%
394    0.20%
395    0.10%
396    0.20%
397    0.10%
398    0.20%
399    0.10%
400    0.20%
401    0.10%
402    0.20%
403    0.10%
404    0.20%
405    0.10%
406    0.20%
407    0.10%
408    0.20%
409    0.10%
410    0.20%
411    0.10%
412    0.20%
413    0.10%
414    0.20%
415    0.10%
416    0.20%
417    0.10%
418    0.20%
419    0.10%
420    0.20%
421    0.10%
422    0.20%
423    0.10%
424    0.20%
425    0.10%
426    0.20%
427    0.10%
428    0.20%
429    0.10%
430    0.20%
431    0.10%
432    0.20%
433    0.10%
434    0.20%
435    0.10%
436    0.20%
437    0.10%
438    0.20%
439    0.10%
440    0.20%
441    0.10%
442    0.20%
443    0.10%
444    0.20%
445    0.10%
446    0.20%
447    0.10%
448    0.20%
449    0.10%
450    0.20%
451    0.10%
452    0.20%
453    0.10%
454    0.20%
455    0.10%
456    0.20%
457    0.10%
458    0.20%
459    0.10%
460    0.20%
461    0.10%
462    0.20%
463    0.10%
464    0.20%
465    0.10%
466    0.20%
467    0.10%
468    0.20%
469    0.10%
470    0.20%
471    0.10%
472    0.20%
473    0.10%
474    0.20%
475    0.10%
476    0.20%
477    0.10%
478    0.20%
479    0.10%
480    0.20%
481    0.10%
482    0.20%
483    0.10%
484    0.20%
485    0.10%
486    0.20%
487    0.10%
488    0.20%
489    0.10%
490    0.20%
491    0.10%
492    0.20%
493    0.10%
494    0.20%
495    0.10%
496    0.20%
497    0.10%
498    0.20%
499    0.10%
500    0.20%
501    0.10%
502    0.20%
503    0.10%
504    0.20%
505    0.10%
506    0.20%
507    0.10%
508    0.20%
509    0.10%
510    0.20%
511    0.10%
512    0.20%
513    0.10%
514    0.20%
515    0.10%
516    0.20%
517    0.10%
518    0.20%
519    0.10%
520    0.20%
521    0.10%
522    0.20%
523    0.10%
524    0.20%
525    0.10%
526    0.20%
527    0.10%
528    0.20%
529    0.10%
530    0.20%
531    0.10%
532    0.20%
533    0.10%
534    0.20%
535    0.10%
536    0.20%
537    0.10%
538    0.20%
539    0.10%
540    0.20%
541    0.10%
542    0.20%
543    0.10%
544    0.20%
545    0.10%
546    0.20%
547    0.10%
548    0.20%
549    0.10%
550    0.20%
551    0.10%
552    0.20%
553    0.10%
554    0.20%
555    0.10%
556    0.20%
557    0.10%
558    0.20%
559    0.10%
560    0.20%
561    0.10%
562    0.20%
563    0.10%
564    0.20%
565    0.10%
566    0.20%
567    0.10%
568    0.20%
569    0.10%
570    0.20%
571    0.10%
572    0.20%
573    0.10%
574    0.20%
575    0.10%
576    0.20%
577    0.10%
578    0.20%
579    0.10%
580    0.20%
581    0.10%
582    0.20%
583    0.10%
584    0.20%
585    0.10%
586    0.20%
587    0.10%
588    0.20%
589    0.10%
590    0.20%
591    0.10%
592    0.20%
593    0.10%
594    0.20%
595    0.10%
596    0.20%
597    0.10%
598    0.20%
599    0.10%
600    0.20%
601    0.10%
602    0.20%
603    0.10%
604    0.20%
605    0.10%
606    0.20%
607    0.10%
608    0.20%
609    0.10%
610    0.20%
611    0.10%
612    0.20%
613    0.10%
614    0.20%
615    0.10%
616    0.20%
617    0.10%
618    0.20%
619    0.10%
620    0.20%
621    0.10%
622    0.20%
623    0.10%
624    0.20%
625    0.10%
626    0.20%
627    0.10%
628    0.20%
629    0.10%
630    0.20%
631    0.10%
632    0.20%
633    0.10%
634    0.20%
635    0.10%
636    0.20%
637    0.10%
638    0.20%
639    0.10%
640    0.20%
641    0.10%
642    0.20%
643    0.10%
644    0.20%
645    0.10%
646    0.20%
647    0.10%
648    0.20%
649    0.10%
650    0.20%
651    0.10%
652    0.20%
653    0.10%
654    0.20%
655    0.10%
656    0.20%
657    0.10%
658    0.20%
659    0.10%
660    0.20%
661    0.10%
662    0.20%
663    0.10%
664    0.20%
665    0.10%

 

While this isnt foolproof, as we still have values that are twice as likely to be returned than the other values, you'll notice that the spread is much more even. Values ranging from 0-332 now have a 50% chance of being generated, as we would expect them to be, as opposed to the 66.6% probability we were generating before.

Share this post


Link to post
Share on other sites

Multiple Attack Variants Using a Single State

Compatibility:

WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN
yes.png
yes.png
yes.png
yes.png

 

This one is fairly simple, and makes use the assignment operator. Instead of defining Light, Medium, and Heavy variants of a special move in separate states, have the changestate in -1 as follows:

 

[State -1, Shoryuken]

type = ChangeState
value = 1100
triggerall = ctrl
trigger1 = command="DP_X"
trigger1 = (var(10) := 1)||1
trigger2 = command="DP_Y"
trigger2 = (var(10) := 2)||1
trigger3 = command="DP_Z"
trigger3 = (var(10) := 3)||1

 

As we can see here, each command will still bring us to our main Shoryuken state, but will keep track of which version we are using. If you have multiple different animations or anything else that varies depending on the version of the move used, you can simply refer to the variable as follows:

 

[Statedef 1100]
type = S
movetype = A
physics = S
ctrl = 0
poweradd = 20
anim = 1100+1*(var(10)=2)+2*(var(10)>=3)
sprpriority = 1
facep2 = 1

[State 1100, Hitdef]
type = HitDef
trigger1 = movecontact = 0 && movereversed = 0
trigger1 = animelemtime(1)>=0
attr = S, SA
damage = 60+10*(var(10)=2)+20*(var(10)=3),11+2*(var(10)=2)+4*(var(10)=3)

As we can see here, animations 1100, 1101, and 1102 each correspond to the Light, Medium, and Heavy versions of our DP command, and the damage values can be modified with this as well.

Share this post


Link to post
Share on other sites

Hitdef Animtype Quirk

Compatibility:

WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN
yes.png
yes.png
yes.png
yes.png

 

This is more of a bug in Mugen/IKEMEN's parser. Basically, Mugen's parser only checks the first letter of the Animtype parameter (L for Light, M for Medium, H for Heavy, B for Back, U for Up, and D for Diagup), while ignoring the rest of the parameter's value. This means that Animtype = Hard and Animtype = Heavy are functionally equivalent. This also means that some silly parameter values that normally shouldn't be accepted by the engine are valid values:

 

Animtype = Hamburger

resolves to Animtype = H (Heavy)
 

Animtype = Methamphetamine

resolves to Animtime = M (Medium)

 

Animtype = Boobies

resolves to Animtype = B (Back)

 

Basically, as long as the parameter's argument begins with an L, M, H, B, U, or D, the engine will accept it as a valid parameter.

Share this post


Link to post
Share on other sites

Improved Guarding States for Crossup Detection

Compatibility:

WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN
yes.png
yes.png
yes.png
yes.png

 

In most fighting games, you need to hold the joystick in the direction away from the opponent in order to guard, which is straightforward when the opponent is directly in front of you. But when the opponent is behind you, such as during an attack that crossed up the opponent, holding back should not allow you to guard an opponent's attack, only when holding forward. By default, Mugen's default guarding states cannot take into account these cross-up attacks. The following modifications to Mugen's guard states will replicate this proper behavior.

 

First, go through States 120, 130, 131, and 132 and search for the following block of code:

 

[State 132, Stop Guarding]
type = ChangeState
trigger1 = command!="holdback"
trigger2 = !inguarddist
value = 140

Replace this with the following:

[State 132, Stop Guarding]
type = ChangeState
trigger1 = cond(p2dist x<0,(command!="holdfwd"),(command!="holdback"))
trigger2 = !inguarddist
value = 140

What this does is tells the engine to stop guarding if we are holding back and player 2 is behind us.

 

In a similar fashion, check states 132 and 155 for the following:

[State 132, 6]
type = ChangeState
trigger1 = sysvar(0)
trigger1 = command="holdback"
trigger1 = inguarddist
value = 130

Replace with this block of code:

[State 132, 6]
type = ChangeState
trigger1 = sysvar(0)
trigger1 = cond(p2dist x<0,(command="holdfwd"),(command="holdback"))
trigger1 = inguarddist
value = 130

This will do the opposite: Tell the engine to start guarding if we are holding back ONLY when the opponent is in front of us, and when holding forward ONLY when the opponent is behind us.

Share this post


Link to post
Share on other sites

Homing/Tracking/Aimed Projectiles

Compatibility:

WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN
yes.png
yes.png
yes.png
yes.png

 

Another relatively simple concept; you have a projectile spawned at a stationary location and want it to either aim in the opponent's direction or to home in on the opponent. For this you'll need a few variables to spare and simply place the following at the beginning of the projectile's state:

 

[State 24010, Conditional Varset]
type = null
triggerall = time = 0 ;<-- See notes below
trigger1 = numenemy
trigger1 = (fvar(0):= (enemynear(0),pos x - pos x) * facing) || 1
trigger1 = (fvar(1):= enemynear(0),pos y - pos y + enemynear(0),const(size.mid.pos.y)) || 1
trigger1 = (fvar(2):=((fvar(0)**2.0)+(fvar(1)**2.0))**0.5) || 1
trigger2 = !numenemy
trigger2 = (fvar(0):= 320.0 * facing) || 1
trigger2 = (fvar(1):= 0.0) || 1
trigger2 = (fvar(2):=((fvar(0)**2.0)+(fvar(1)**2.0))**0.5) || 1

What this does is uses simple trigonometry to calculate the vectors between the opponent and the projectile. The second set of triggers (trigger 2) is necessary in the event that an opponent doesn't exist so that the code doesn't bug out, and will simply cause the projectile to fire in a straight line if there is no opponent. You might be wondering about that triggerall line at the top. Depending on what this value is will determine on whether or not the projectile is aimed or homing; an aimed projectile will simply track the opponent's position at the time of creation and fire at that direction, while a homing projectile will continuously chase the opponent for as long as the projectile exists. The above code is for an aimed projectile, but to change this to a homing projectile, simply replace "triggerall = time = 0" with "triggerall = 1".

 

But we're not done yet. We still need to apply these vectors to the projectile's velocity. Assuming that the projectile's base velocity is 10:

 

[State 24010, Velset]
type = velset
trigger1 = 1
x = 10.0*fvar(0)/fvar(2)
y = 10.0*fvar(1)/fvar(2)
ignorehitpause = 1

What we're doing here is normalizing our vectors and applying them to our projectile's base velocity. This is what will cause the aimed/homing behavior of the projectile.

 

If for some reason you also need your projectile to rotate in the direction it's traveling, make sure to add the following under your velset controller:

[State 2010, AS]
type = varset
trigger1 = vel x != 0
fvar(3) = atan(vel y/vel x)*(-180.0/pi)+((vel x<0)*180)

[State 2010, AS]
type = varset
trigger1 = vel x = 0
fvar(3) = ifelse(vel y<0,90,-90)

[State 2010, AS]
type = angledraw
trigger1 = 1
value = fvar(3)
ignorehitpause = 1

Just make sure that your projectile's graphic is facing horizontally or you'll need to make adjustments to the above code. This also checks if the projectile is traveling straight up or down; since the tangent of 90 degree angles are undefined, we need that second state controller there as a failsafe or else the code will bug out and you won't get a proper rotation.

Share this post


Link to post
Share on other sites

Damage Proration System

Compatibility:

WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN
yes.png
yes.png
yes.png
yes.png

 

Proration, also known as Damage Dampening, is a system implemented in many fighting games that prevent combos from becoming too overpowered by decreasing the amount of damage dealt by each successive hit in a combo. The exact method of how proration is achieved differs by game; most Capcom games such as the Street Fighter and Marvel vs Capcom games use a linear proration system based on the number of hits in a combo, while most games by Arc System Works tend to use a scalar method where each hit of an attack applies its own scaling value. This tutorial will deal with the latter method, which gives you greater control over how damage is scaled.

 

First, you'll need two floating point variables for this to work; we'll be using fvar(10) and fvar(11). We'll be dealing with fvar(11) as our final dampener later on, but for now, start with the following in your -2 state:

[State -2, Reset var when the opponent recovers]
type = Varset
trigger1 = numenemy
trigger1 = (enemynear,movetype!=H)
trigger2 = !numenemy
fvar(10) = 1.0

[State -2, Final Dampen]
type = null
trigger1 = (fvar(11) := ifelse(0.1>fvar(10),0.1,fvar(10)) || 1
ignorehitpause = 1

[State -2, Dampener itself]
type = Attackmulset
trigger1 = 1
value = fvar(11)
ignorehitpause = 1

The first state controller will initialize our character's proration to 100% damage (the default), as well as reset our proration value whenever the opponent is not being comboed. The second state controller is optional, but is handy to have if you want there to be a minimum proration value, as many games that use this system tend to have one. In our above example, our minimum proration is set to 0.1 or 10%, so our damage scaling will never go below 10% of an attack's base damage. You can also further modify fvar(11) for any other system mechanics you might need, including counterhit bonuses or other scaling such as the damage penalty incurred with systems such as Custom Combo. The final controller here will apply fvar(11) as our final proration value and scale our Attack stat accordingly. Note that this will only apply to damage dealt by the player and not any helper projectiles spawned by the player; in order to apply our damage proration to those, you'll need to apply the proration value directly to the attack's damage value in the hitdef:

 

damage = ceil(220.0*root,fvar(11)),44

Here, we see a helper projectile with a base damage of 220 having the root's (aka the player's) proration value applied. The ceil function is needed to ensure that the damage never falls below 1 and always returns an integer value. Note that chip damage (block damage) is never scaled.

 

Now that we have a proration system in place, all that's left is to actually apply the proration values. Go through each of your character's attacks and add a varset under their hitdef with the amount of proration you want to apply on hit:

 

[State 200, Damage Dampen]
type = varset
trigger1 = movehit
fvar(10) = fvar(10)*0.92
ignorehitpause = 1
persistent = 0

Above, we see a controller for attack that deals 92% proration on hit. As mentioned at the beginning, this will multiply the proration value by whatever proration is set by the attack, which is then applied to the damage of the next attack in the combo. If you're doing this in a helper projectile, you'll want to substitute this for an equivalent parentvarset controller:

Quote

 

[State 200, Damage Dampen]

type = parentvarset

trigger1 = movehit

fvar(10) = (root,fvar(10))*0.92

ignorehitpause = 1

persistent = 0

 

 

If an attack deals multiple hits, you'll need to apply a proration controller for each individual hit in a similar fashion; this can be accomplished through the use of the animelemno() and animelemtime() triggers, or whatever system you are using to keep track of multiple hits.

Share this post


Link to post
Share on other sites

Fix for Combo Counter Reset Bug

Compatibility:

WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN
yes.png
yes.png
yes.png
yes.png

 

For those of you who may or may not already know, but whenever you have a helper-based projectile hit an opponent and then destroy itself, this causes a peculiar bug to occur in where Mugen's combo counter will reset to 0, even if you continue the combo. The combo itself is a still valid, but the misleading aesthetics can be jarring. Fortunately, this problem is easily circumvented if one understands how targets work in Mugen.

 

To put it simply, whenever a player or helper hits something else, that something else, whether it be another player or a helper, will be registered by the attacker by its playerid. Whenever something else hits that same object, the new attacker gains that object as a target, while the previous attacks drops the object as a target. As an example, suppose you do a simple combo of S.MP into Hadouken, the Hadouken in this case being a helper-based projectile; when P1 hits P2 with S.MP, P1 gains P2 on its list of targets. The moment P1 fires the Hadouken and the Hadouken hits P2, the Hadouken helper gains P2 as a target, while P1 drops P2 from its target list. The combo counter reset bug occurs whenever a helper destroys itself, which forces it to drop all targets it has prematurely while nothing else is claiming P2 as a target. The solution; have the helper last long enough until either a combo ends or a proper transfer of "target ownership" can occur by sending it to an intermediary "destruct" state;

 

; Universal Projectile Destruction
[Statedef 999]
type = A
physics = N
movetype = I
anim = 1998 ; your blank animation
velset = 0, 0
ctrl = 0
movehitpersist = 1

[State 1112, nothitby]
type = nothitby
trigger1 = ishelper
time = 1
value = SCA
ignorehitpause = 1

[State 1112, NoShadow]
type = AssertSpecial
trigger1 = ishelper
flag = noshadow
ignorehitpause = 1

[State 1112, End]
type = destroyself
triggerall = ishelper
trigger1 = !numtarget
trigger2 = numtarget
trigger2 = target, time <= 1 && !(target, hitshakeover)
ignorehitpause = 1

Rather than calling a Destroyself controller directly, you'll be using a changestate controller to send the helper into this state instead, which satisfies both conditions outlined above. If your character has any system-specific mechanics such as Safe Fall, you'll also need to copy the associated targetstate controllers into this state as well.

 

One thing to take note of is that, if you have anything that relies on numhelper=0 triggers, you'll need to accomodate for the new intermediate state. In Mugen 1.0 and 1.1, as well as in Ikemen, you can easily accomplish this through a cond statement, usually something along the lines of;

 

triggerall = cond(numhelper(xxx)>0,cond((helper(xxx),stateno=999),1,0),1)

Basically this is a substitute for numhelper(xxx)=0 that checks for the following logic; if helper #xxx exists, check to see if its in state 999; if it is, then return true, otherwise return false. Else, if helper #xxx doesnt exist, then return true.


 

 

Share this post


Link to post
Share on other sites

On a side note, your damage dampen code doesn't really work on Simul Mode as it uses enemynear trigger, which makes fvar(10) always resets to 1, results in no damage dampen at all (which happens in all of your Touhou characters I can think of). The only way I think that can make it somehow work in Simul Mode:

[State -2, Log the first target's PlayerID]
type = varSet
triggerall = numtarget
triggerall = target,IsHelper = 0 ;Do not trigger for Helpers
trigger1 = !(PlayerIDExist(var(55)) && PlayerIDExist(var(57))) ;no logged IDs
trigger2 = PlayerIDExist(var(55)) ;one has been logged
trigger2 = target,ID != var(55) ;it's not me
trigger3 = PlayerIDExist(var(57)) ;one has been logged
trigger3 = target,ID != var(57) ;it's not me
var(55) = target,ID
ignorehitpause = 1
 
[State -2, Log the second target's PlayerID]
type = varSet
triggerall = numtarget
triggerall = target,IsHelper = 0 ;Do not trigger for Helpers
trigger1 = PlayerIDExist(var(55)) ;one has been logged
trigger1 = target,ID != var(55) ;it's not me
trigger2 = PlayerIDExist(var(57)) ;one has been logged
trigger2 = target,ID != var(57) ;it's not me
var(57) = target,ID
ignorehitpause = 1

[State -2, Reset var when the opponent recovers]
type = Varset
triggerall = numtarget && (var(55) || var(57))
trigger1 = PlayerIDExist(var(55))
trigger1 = target,ID = var(55)
trigger1 = PlayerID(var(55)),movetype!=H
trigger2 = PlayerIDExist(var(57))
trigger2 = target,ID = var(57)
trigger2 = PlayerID(var(57)),movetype!=H
fvar(10) = 1

[State -2, Reset var if no enemy]
type = Varset
trigger1 = !numtarget
fvar(10) = 1

Even so, that will not work if the first attack is from a helper.

Share this post


Link to post
Share on other sites

 Tbf, Simul Mode is a absolute broken mess and nightmare to work with. It's hardly worth catering to that mode, not to mention most people don't really use it nowadays as they did 10 years back. The damage scaling code otherwise works perfectly fine in a 1-on-1 environment, which is the intention RicePigeon had with his characters anyway.

 

 I'm personally eager for more coding snippets in the future, a lot of this stuff has been helpful to me.

Share this post


Link to post
Share on other sites

While  I agree with you, I think it's still better to note this issue than to ignore it completely.

However, this thread is still one of the most valuable MUGEN tutorials IMO.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now