Random to multiple follow anims.

NED

Well-known member
My enemy system will use a special grab with various cancels.
I would like it to work this way.

grab atempt : on success go to "Body slam finisher"

Since it's on "body slam", before to actually do the move, it can cancels to
-power bomb
-back breaker (new move)

About percentage, I would like to have something like that
BS 40% chance
PB 30% chance
BB 30% chance

Initially, there was only 2 slams and I used this script

Code:
      @script
    void self = getlocalvar("self");

    if( frame == 0){
      int r = rand()%40;

      if( r > 0){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW21"));
      }
    }
@end_script

How can I change it to have 3 choices : (no cancel, slam2, slam3) ?
Or do I have to use a better slam system script?

Thanks


PS: I'll certainly have to increase or reduce the cancels for other entities.
 
Code:
    void self = getlocalvar("self");
    if( frame == 0){
      int r = rand()%30;
      if( r > 11){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW1"));
      } else if( r < -10){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
      } else if( r < 0){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW3"));
      } else if( r > 0){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW4"));
      }
    }
	@end_script
Something like that, not sure how random it is thou.
 
Thanks BeasTie.

Perhaps it will look noobish, but why is there 4 follow anims on it?

I have only 3 choices (from follow20):

-Stay in follow20 (without cancel) - 40% chance
-Cancel to follow21 - 30% chance
-Cancel to follow22 - 30% chance
 
in fact, there are some errors on that logic, let me explain.

rand()%30 = from -30 to 30 = 61 values (we need to count 0 too).
A)r > 11 = excluding the values from -30 to 11 = 41 values = 61-41 = 20 values
B)r < -10 = from -30 to -11 = 20 values
C)r < 0 = from -30 to -1 = 29 values
D)r > 0 = 30 values

1- A and D share some range in common. Because "r>11" falls under the case of "r > 0", so the char won't go to follow1, but it will go to follow4.

2- 20+20+29+30 = 99 possible values. What happens if random is 0? Nothing. Plus, its a mandatory rule of most programming languages that whenever you set a "switch" (which is better than a sequence of "if"), you need to provide a default option. And you are not "closing" the loop here, since the last trigger is "else if" when it should be "else". You can use that "else" for "r==0" (double "=" not single. "==" means equal, while "=" set a value).

3- The % of each option is not the same. Using Cross-multiplication we can calculate the real % of each move:

A) 20,2020202%
B) 29,29292929%
C) 20,2020202%
D) 30,3030303%


(but there is something wrong here. All the sum is ignoring the chance of r == 0. But I can't see how)

Got it: Its 20+20+29+30+1(zero) = 100

so

A)20%
B)29%
C)20%
D)30%
Chance of staying on the same animation - 1%

Since A falls under D range, the percentage of D would be 50%.
 
Thanks for the help Ilu.

But this is a total unknown and incomprehensible world to me. ???

I'll certainly delete the 3rd slam and keep the old code.
 
Sorry I didn't write the script for you - it was just the first example i could find.

@Ilu
So what's the correct version of the above script?
 
To make it easier to understand, I do prefer to work with 100 values, to match the value number with the % number. And I use a code to check if the value is negative and make it positive, or we would have 199 values, and I think its more user friendly.

So, rand()%99 means "a random value from 0 to 99" - which means 100 values.
from 0 to 39 (40 values: 40%), does nothing;
from 40 to 69 (30 values: 30%), go to follow21;
from 70 to 99 (30 values: 30%), go to follow22;


Code:
@script	   
void self = getlocalvar("self");
if( frame == 0)
{
	int r = rand()%99;
	if (r <0)
		{			// If the r is negative,
			r = r*-1;	// Make it positive
		}
	if( r >=40 && r <=69)
		{
		changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW21"));
		} 
	else if( r >=70 && r <=99)
		{
		changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW22"));
		}
      
}
@end_script
 
Cool, yeah that is what always confused me not starting with 100%.  This is a bit easier to understand. 

Do you have good examples for 3 and 4 follows? maybe even 6.

That should cover most peoples needs.  We can add this to script index etc.
 
Do you have good examples for 3 and 4 follows? maybe even 6.
Just follow the logic and change the desired values.

The only issue would be numbers like 3, because 100/3 is a Repeating decimal.

The rule is take the maxium value (100) and divide by the number of values you want.
100/2 = 50; 100/4 = 25; 100/3 = 33 (rounding, because its 33,333333333333333...)

For 3 values:

Code:
@script	   
void self = getlocalvar("self");
if( frame == 0)
{
	int r = rand()%98; // we will work with 99 values
	if (r <0)
		{			// If the r is negative,
			r = r*-1;	// Make it positive
		}
	if( r >=0 && r <=32)
		{
		changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW21"));
		} 
	else if( r >=33 && r <=65)
		{
		changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW22"));
		}
        else if( r >=99 && r <=99)
		{
		changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW23"));
		}
      
}
@end_script

For 4 values:

Code:
@script	   
void self = getlocalvar("self");
if( frame == 0)
{
	int r = rand()%99;
	if (r <0)
		{			// If the r is negative,
			r = r*-1;	// Make it positive
		}
	if( r >=0 && r <=24)
		{
		changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW21"));
		} 
	else if( r >=25 && r <=49)
		{
		changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW22"));
		}
        else if( r >=50 && r <=74)
		{
		changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW23"));
		}
        else if( r >=75 && r <=99)
		{
		changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW24"));
		}
      
}
@end_script

Got it? you start with 0 to the value of each part - 1. For 4 cases (25%) you use

0 to 24 (means 25 values)
25 to 49 (25 values)
26 to 74 (idem)
75 to 99 (idem)

ps: for multiple of 3, you can use number which could be divided by 3, like 120, so you would use rand()%119)
 
I don't know where that script Beastie quoted came from but it's example of efficient scripting.

Code:
if( r < -10){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
      } else if( r < 0){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW3"));
      }

It might look like the 3rd if covers 2nd if but if somehow r is say -20, the 2nd if will be run ignoring the 3rd one.
So the script above is equal to this:

Code:
void self = getlocalvar("self");
    if( frame == 0){
      int r = rand()%30;
      if( r > 11){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW1"));
      } else if( r < -10){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
      } else if( r < 0 && r >= -10){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW3"));
      } else if( r > 0 && r <= 11){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW4"));
      }
    }

However, I agree with the missing if r == 0 case. It must be put into consideration when making script like this
That's why it's best to just use else for the remaining values of r without specifying the values
 
It might look like the 3rd if covers 2nd if but if somehow r is say -20, the 2nd if will be run ignoring the 3rd one.
You are right on this case because we are executing a animation change, so the 3rd will be ignored. But if it was a variable set, sound play or other thing, both triggers will be executed.
 
Sorry I think it was an just example of adding extra animations, but it didn't update the random function.

@O Ilusionista - Thanks for the new examples. :)
 
Back
Top Bottom