Absolutely excellent !!So I made the music again.
A simple and cool trick you can use is to make different spawn animations which will be randomly triggered during the normal spawn animationFor this project, I added the intro for Stage 3 and created the animation for enemies to appear at the club entrance.
void randomAnim(int iLimit, int iChance, int Ani)
{ // Randonly goes to another animation, based on the chance
// Douglas Baldan - 15/06/2018 - Thanks Bloodbane
// http://www.brazilmugenteam.com
void self = getlocalvar("self");
int r = rand()%iLimit;
if(r > iChance){
if (!getentityproperty(self, "dead")){
performattack(self, openborconstant(Ani));
}
}
}
Thanks for the mention, I appreciate itI created the credits in advance
A simple and cool trick you can use is to make different spawn animations which will be randomly triggered during the normal spawn animation
I use this function in the first frame of the spawn animation, which makes the character randomly change spawn animations using "follow" type animations. For example, I leave the default spawn animation as the enemy simply walking and entering the screen, but I create alternative animations with them running or just making a small jump on the screen.
This makes the spawns less repetitive, makes each playthrough different, and you can even have customized spawns for specific cases, such as enemies coming out of doors, jumping off rooftops, etc.
You can see the code in action here, at 0:41
If you want something more advanced, you can randomize the Z position where they appear in the level or even create an invisible entity that randomly summons certain types of enemies, making each playthrough even more different.
The function (put it on your animationscript file)
C-like:void randomAnim(int iLimit, int iChance, int Ani) { // Randonly goes to another animation, based on the chance // Douglas Baldan - 15/06/2018 - Thanks Bloodbane // http://www.brazilmugenteam.com void self = getlocalvar("self"); int r = rand()%iLimit; if(r > iChance){ if (!getentityproperty(self, "dead")){ performattack(self, openborconstant(Ani)); } } }
Usage:
@cmd randomAnim 30 0 "ANI_FOLLOW1"
Thanks for the mention, I appreciate it![]()
openborconstant() is bad... really bad, and so easily fixed.performattack(self, openborconstant(Ani));Ani is a variable, the engine cannot preprocess it. That means openborconstant() has to resolve the string at runtime every time the function runs. That is absurdly expensive because it requires searching through every available constant in the engine and comparing strings.openborconstant("ANI_FOLLOW1") = Can be seen by the engine while scripts are being loaded and compiled. OpenBOR can resolve it once at startup and replace it with the actual integer constant. At runtime, that is basically free.openborconstant(Ani) = The engine has no idea what Ani contains until the function actually runs. Since it cannot preprocess the value, it has to resolve the string every time the command executes.void randomAnim(int iLimit, int iChance, int animation_id) {
/* Guards */
if(typeof(iLimit) != openborconstant("VT_INTEGER")
|| typeof(iChance) != openborconstant("VT_INTEGER")
|| typeof(animation_id) != openborconstant("VT_INTEGER")){
shutdown(1, "\n\n ERROR: randomAnim(" + iLimit + ", " + iChance + ", " + animation_id + ") - Missing or invalid parameter.\n");
}
// Randomly goes to another animation, based on the chance
// Douglas Baldan - 15/06/2018 - Thanks Bloodbane
// http://www.brazilmugenteam.com
void self = getlocalvar("self");
int r = rand()%iLimit;
if(r > iChance){
if (!getentityproperty(self, "dead")){
performattack(self, animation_id);
}
}
}
@cmd randomAnim 30 0 openborconstant("ANI_FOLLOW1")
Yes buddy, I am aware of it@O Ilusionista, I've brought this up a couple of times in similar posts, you need to stop using strings for value in the hot path, or at least stop passing the code as is because it's teaching bad habits. Run time population ofopenborconstant()is bad... really bad, and so easily fixed.
If you think it might end up confusing people, I can avoid pasting this code on the forum again and only post it when it's updated.