You know, checking projectile hit within the same state that the projectile is spawned isn't good code practice... Character tend to leave that state before the projectile hits its target and then, bang!, no life added. Such code should be put at a special state such [State -2]
Er... I forgot to update my post since I added a main page for my site. So I now want people to enter it before downloading my stuff and for doing such I had to turn off hotlinking of zip and rar files... But the files of all my character continues free for anyone too use, copy or change the programmer name in the def file and release it as his own.
Hello, hello, hello. After having messed with angles in mugen, I couldn't help but waste my whole night thinking in normals, vectors and so on... I almost lost my sleep due to that... So, the first thing I did today as I got myself to my computer was to program a code for aimed projectiles based on the calculus of normalized vectors.
So, here is the code :
;Finds the X component of the vector Player, EnemyNear ;Formula to find the components of a given vector AB ;V(x) = B(x) - A(x) ;V(y) = B(y) - A(y) [State 1640, X] Type = VarSet Trigger1 = 1 fvar(13) = (EnemyNear(0), Pos X - Pos X) * Facing ;Adjust the direction towards player facing
;Finds the Y component of the vector Player, EnemyNear [State 1640, Y] Type = VarSet trigger1 = 1 fvar(14) = (EnemyNear(0), pos Y - Pos Y)
;Finds the vector length ;Formula of the length of a given vector AB ;|AB| = (AB(x)^2 + AB(y)^2)^1/2 [State 1640, Vector Length] Type = VarSet trigger1 = 1 fvar(15) = Exp(0.5*ln((fvar(13) * fvar(13))+(fvar(14) * fvar(14))))
;To find the normalized vector one has to use ;the following formula: ;Normal(AB) = V(AB)/|AB| ;So, you divide the X and Y components of one vector by it's length ;Obs: ;Normalized vector = The normalized vector of X is a vector in the same direction ;but with norm (length) 1. ;Now that we have the normalized vector, we multiply it by the desired absolute velocity, ;such as 5 pixels per frame.
Okay, okay, okay. After a few minutes smacking my head against the wall, I gotta this code to calculate the angle between player and EnemyNear(0): (Btw, I'm giving away a code to calculate absolute distance between player and EnemyNear(0) with it )
[State -3, Distance Between Player and the Nearest enemy] Type = VarSet trigger1 = 1 fvar(10) = Exp(0.5*ln((((EnemyNear(0), Pos X) - (Pos X)) * (( EnemyNear(0), Pos X) - (Pos X)) + ((EnemyNear(0), Pos Y - Pos Y) * (EnemyNear(0), Pos Y - Pos Y)))))
[State -3, M] Type = VarSet trigger1 = EnemyNear(0), Pos X != Pos X fvar(11) = -((EnemyNear(0), Pos Y - Pos Y)/(EnemyNear(0), Pos X - Pos X))
[State -3, M] ;There can be no triangle if both points share the same X cord Type = VarSet trigger1 = EnemyNear(0), Pos X = Pos X fvar(11) = 0
[State -3, Angle] Type = VarSet trigger1 = 1 fvar(12) = Atan(fvar(11)) * (180.0/Pi) ;Angle given in degrees.
And that was "Yet another code no one will use, nor will give a damn" brought to you by SMEE. Now, there is no need to point out that no one other than would use this code.
Edit: Removed the ABS in the M formula and fixed the inverted cartesian plan that mugen uses by multipling M by -1.
The only thing I ask other people to mention is that the AI activation code that is used was first developed by Kamek (or at least keep the mention in the cns, as I do). Otherwise, one can take those, change the creator name in DEF file, make another readme.txt and release them as their own.
You just need the winperfect trigger and maybe a time trigger... There is no need to check your life, to check p2 life or whatever. Winperfect only triggers when you win a round with a full life bar...
No, no, no!!! That's ugly and doesn't makes sense when you have a winperfect trigger. People, please, read the whole triggers.txt. There are lots of unusual triggers that no one uses there.
Instead of using Life >= 999, use this: [State whatever, I don't care] Type = Explod trigger1 = winperfect ...
Winane: The most significant one is the ** operator, which has a bad precision, doesn't like to be in expressions and doesn't accept float numbers as its base. The other thing is expression processing. Mugen hates complex expression with passion and will give you broken results whereas it can... Also, it's float number precision is really bad... So, math in mugen is like a nightmare.
Well, well, well. I know that many here might not be too found on math, but there is a thing some might find interesting. It was originally posted at MugenDev an year ago. There are two ways to get a square root of a number in mugen. The first one is by using the exp and ln functions in this way: ;Square Root [State WhatEver, I don't Care] Type = VarSet trigger1 = Something fvar(39) = exp(0.5*ln(fvar(38)))
This soluction is nice, cleaner and will give more accurate results than the second method below. Thanks to ANMC for pointing me out that the exp function in mugen ain't broken as some other math functions are and could be used this way. You can always try to generalize the function so you won't be limited to square roots: ;Root Function [State WhatEver, Root] Type = VarSet trigger1 = Something fvar(39) = exp((1.0/fvar(37)) * ln(fvar(38)))
Here fvar(37) represents the root base (2, 3, 4 and so on). Keep in mind that square roots and roots functions are very slow.
Also, you can use exp to calculate power in this way: exp(fvar(37)*ln(fvar(38))). This gives a better result than the ** operator in mugen.
Now, on the second method, that I'll be posting just for my own sake, as I spent some good nights awake and lost many precious dating hours trying to figure out the code. It has rounding error problems, is slower than the code above and so on, but it works quite nicelly. This code is based in taylor series:
;Square Root of a number using Taylor series. [State 666, SquareRoot1] Type = VarSet trigger1 = 1 fv = 0 value = Value ;We'll be storing the value we want to get the sqrt in the parent's fvar(0)
[State 666, SquareRoot10] Type = VarSet trigger1 = 1 fv = 1 value = 0.5*ln(fvar(0)) ;This is the main key for the success.
[State 666, SquareRoot11] Type = VarSet trigger1 = 1 fv = 2 value = fvar(1)*fvar(1)/2.0 ;Remember guys, the ** operator does not work very well in mugen
[State 666, SquareRoot12] Type = VarSet trigger1 = 1 fv = 3 value = fvar(2)*fvar(1)/6.0 ;fvar(1)**3/3!
[State 666, SquareRoot13] Type = VarSet trigger1 = 1 fv = 4 value = fvar(3)*fvar(1)/24.0 ;fvar(1)**4/4!
[State 666, SquareRoot14] Type = VarSet trigger1 = 1 fv = 5 value = fvar(4)*fvar(1)/120.0 ;fvar(1)**5/5!
[State 666, SquareRoot15] Type = VarSet trigger1 = 1 fv = 6 value = fvar(5)*fvar(1)/720.0 ;fvar(1)**6/6!
[State 666, SquareRoot16] Type = VarSet trigger1 = 1 fv = 7 value = fvar(6)*fvar(1)/5040.0 ;fvar(1)**7/7!
[State 666, SquareRoot17] Type = VarSet trigger1 = 1 fv = 8 value = fvar(7)*fvar(1)/40320.0 ;fvar(1)**8/8!
[State 666, SquareRoot18] Type = VarSet trigger1 = 1 fv = 9 value = fvar(8) *fvar(1)/362880.0 ;fvar(1)**9/9!
[State 666, SquareRoot19] Type = VarSet trigger1 = 1 fv = 10 value = fvar(9)*fvar(1)/3628800.0 ;fvar(1)**10/10!
[State 666, SquareRoot19] Type = VarSet trigger1 = 1 fv = 11 value = fvar(10)*fvar(1)/39916800.0 ;fvar(1)**11/11!
[State 666, SquareRoot20] Type = VarSet trigger1 = 1 fv = 12 value = fvar(11)*fvar(1)/479001600.0 ;fvar(1)**12/12!
[state 666, SquareRoot22] Type = VarSet trigger1 = 1 fvar(39) = 1+fvar(1)+fvar(2)+fvar(3)+fvar(4)+fvar(5)+fvar(6)+fvar(7)+fvar(8) +fvar(9)+fvar(10)+fvar(11)+fvar(12) ;The result is stored at fvar(39)
If you need to calculate the root of a number with mugen, stick with the first method. It has several advantages over the one I developed using Taylor series.