• All, Gmail is currently rejecting messages from my host. I have a ticket in process, but it may take some time to resolve. Until further notice, do NOT use Gmail for your accounts. You will be unable to receive confirmations and two factor messages to login.
Damage All Enemies On Screen

[SCRIPT] Damage All Enemies on the screen

Damage All Enemies on the screen
Function: This code can damage all the enemies on the screen with sime custom things:

- It can damage the enemies even if they have no bbox. IOW, it can damage the enemies anytime. Maybe we can add a life check to avoid any bug.

- you can choose the damage, if it knock down the enemies, which kind of attack, a specific flash and a specific sound.

C:
void damage_all_enemies(int damage, int drop, void atk_type, void vName, char sound)
// By O Ilusionista
//thanks Lagarto, Piccolo and White Dragon
{
     int  iEntity;
        void vEntity;
        void self        = getlocalvar("self");
        int  iMax        = openborvariant("count_entities");
        playSound("data/sounds/"+sound);
     
        for(iEntity=0; iEntity<iMax; iEntity++)
        {
        vEntity = getentity(iEntity);
        float x = getentityproperty(vEntity, "x") - openborvariant("xpos");
        float a = getentityproperty(vEntity, "a");
        float z = getentityproperty(vEntity, "z");
        void Spawn;
        if(getentityproperty(vEntity, "type")==openborconstant("TYPE_enemy"))
        {
     
        clearspawnentry();
        setspawnentry("name", vName);
        setspawnentry("coords", x, z+1, a+30);
        spawn();
        clearspawnentry();
        damageentity(vEntity,self,damage,drop,openborconstant(atk_type));
     
        }
    }
}

Usage:
@cmd damage_all_enemies 2 0 "ATK_NORMAL" "flash" "beat2.wav"

It will damage all the enemies on the screen, doing 2 as damage, not knocking the enemies down (0), using "ATTACK1" as the attack, spawing a specific flash and using a custom sound.
Now I have a chance to use this script but somehow it is not working for me as it only damages 1 enemy on the screen. I know this because I set the damage to 400 just to see.
I've tried to see what I did wrong, but the script is exact the same.
I looked on the manual, there are also
"count_enemies" and "ent_max"
I am confused that why are we using "count_entities" then check to see if they are enemies?
why not using "count_enemies" ? I saw another thread which was using "ent_max"
I am at work, so I have not tried them yet.
Can someone please give me some advices on this? Thank you so much
 
@Bruce I can guarantee that the code works because I use it in my Avengers project (You can see it in action when Jean Gray attacks).

I am confused that why are we using "count_entities" then check to see if they are enemies?
Because I do want to damage only the type enemy entities and I need to be sure about the type.

On the code above, I am getting information from a pointer (the entity, on this case) and, after that, I am referencing that pointer to spawn things.
Trying to get information from a invalid point (a null pointer) isn't a problem, but referencing it (using its info) is a problem - a null pointer causes softwares to crash.
I even should add a safe check there to take care of it (althought I haven't experienced any issue yet)

Keep in mind this script works as "brute force" - I am not checking if the enemy is under a certain animation, if its on air/ground or even if it still have health left; the code will hurt them anyway. For example, if you have an enemy doing a pose or waiting (like the thugs in Final Fight), the code will break it and hurt them anyway. So use it with caution.

I saw another thread which was using "ent_max"
It's a common mistake to use "ent_max" on this case. I just need to know how much entities are on the screen, not the maximum entities allowed.

Using "ent_max" would be a waste of resources here. Why? Let's say we have 20 entitties on the screen:

  • Using "count_entities" I will get the number 20. Them the code will try execute a loop (checking all the stuff and spawing needed effects) and retry it again 19 times (as it need to do a loop for each entity, so we are talking about 20 loops.

  • If I am not mistake, "ent_max" comes from the constantc MAX_ENTS, which is set to 150 on the engine source
    #define MAX_ENTS 150
    So using ent_max here will make the engine to try the loop 150 times instead of just 20.
Using count_entities speeds up the code a bit
 
@Bruce by the way, the code above will ask for a hitflash and a hitfx. You don't need them, you can use this variation:

C-like:
void damage_all_enemies2(int damage, int drop, void atk_type)
//thanks Lagarto, Piccolo and White Dragon
//damage without effects
{
     int  iEntity;
        void vEntity;
        void self        = getlocalvar("self");
        int  iMax        = openborvariant("count_entities");   


        
        for(iEntity=0; iEntity<iMax; iEntity++)
        {
        vEntity = getentity(iEntity);
        float x = getentityproperty(vEntity, "x") - openborvariant("xpos");
        float a = getentityproperty(vEntity, "a");
        float z = getentityproperty(vEntity, "z");


        if(getentityproperty(vEntity, "type")==openborconstant("TYPE_enemy"))
        {
        damageentity(vEntity,self,damage,drop,openborconstant(atk_type));       
        }
    }
}

Usage:
@cmd damage_all_enemies 2 0 "ATK_NORMAL"

It will damage all the enemies on the screen, doing 2 as damage, not knocking the enemies down (0), using "ATTACK1" as the attack type
 
@Bruce I can guarantee that the code works because I use it in my Avengers project (You can see it in action when Jean Gray attacks).


Because I do want to damage only the type enemy entities and I need to be sure about the type.

On the code above, I am getting information from a pointer (the entity, on this case) and, after that, I am referencing that pointer to spawn things.
Trying to get information from a invalid point (a null pointer) isn't a problem, but referencing it (using its info) is a problem - a null pointer causes softwares to crash.
I even should add a safe check there to take care of it (althought I haven't experienced any issue yet)

Keep in mind this script works as "brute force" - I am not checking if the enemy is under a certain animation, if its on air/ground or even if it still have health left; the code will hurt them anyway. For example, if you have an enemy doing a pose or waiting (like the thugs in Final Fight), the code will break it and hurt them anyway. So use it with caution.


It's a common mistake to use "ent_max" on this case. I just need to know how much entities are on the screen, not the maximum entities allowed.

Using "ent_max" would be a waste of resources here. Why? Let's say we have 20 entitties on the screen:

  • Using "count_entities" I will get the number 20. Them the code will try execute a loop (checking all the stuff and spawing needed effects) and retry it again 19 times (as it need to do a loop for each entity, so we are talking about 20 loops.

  • If I am not mistake, "ent_max" comes from the constantc MAX_ENTS, which is set to 150 on the engine source
    #define MAX_ENTS 150
    So using ent_max here will make the engine to try the loop 150 times instead of just 20.
Using count_entities speeds up the code a bit
Ahh it makes more sense now. Somehow I thought "ent_max" counts the total of numbers of entities on the screen instead of the whole game.
What about the "count_enemies". Wouldn't it be better to use this since it only counts the total number of the enemies?

C-like:
void damage_all_enemies2(int damage, int drop, void atk_type)
//thanks Lagarto, Piccolo and White Dragon
//damage without effects
{
int iEntity;
void vEntity;
void self = getlocalvar("self");
int iMax = openborvariant("count_entities");



for(iEntity=0; iEntity<iMax; iEntity++)
{
vEntity = getentity(iEntity);
float x = getentityproperty(vEntity, "x") - openborvariant("xpos");
float a = getentityproperty(vEntity, "a");
float z = getentityproperty(vEntity, "z");


if(getentityproperty(vEntity, "type")==openborconstant("TYPE_enemy"))
{
damageentity(vEntity,self,damage,drop,openborconstant(atk_type));
}
}
}

Usage:
@cmd damage_all_enemies 2 0 "ATK_NORMAL"

It will damage all the enemies on the screen, doing 2 as damage, not knocking the enemies down (0), using "ATTACK1" as the attack type
I understood your first script completely and I was able to modify it to work with my case. and it looks like it should work.
For some reasons, it only damages 1 enemy instead of looping through all the entities for the enemies regardless if they are standing, falling, or on the ground.
It is very weird. I even looked on the enemies' files to make sure the type is enemy.
I will double check it again to see what's wrong with my code...
Thanks a lot
 
What about the "count_enemies". Wouldn't it be better to use this since it only counts the total number of the enemies?
Not on this case - I need to check if my target is a enemy, not only to know how many enemies are active. Without that check, the script would damage everything on the screen - including you :)
 
Not on this case - I need to check if my target is a enemy, not only to know how many enemies are active. Without that check, the script would damage everything on the screen - including you :)
lol I know that check is a must. I was saying that "count_enemies" will count the total of enemies instead of counting all entities including objects, etc.. on the screen with "count_entities". Wouldn't it be less looping to do for the for-loop? lol they are just too many functions that I don't really understand how they work yet. I am learning them one by one. Greatly appreciated for your help!
 
I was saying that "count_enemies" will count the total of enemies instead of counting all entities including objects, etc
ah you are probably right about this one - since I got this code from another code (where I have other cases, not only enemies), maybe I can change it to count only the enemies.
 
You can't use enemy count to loop over entities, because you're getting entities in the loop by their index, and that index is 0 to total entity count. Ex: There might be 20 enemies on screen, but one of the twenty enemies may have an index of 32 if there are 50 total entities. So when the loop stops at 20, it never reaches that enemy.

DC
 
You can't use enemy count to loop over entities, because you're getting entities in the loop by their index, and that index is 0 to total entity count. Ex: There might be 20 enemies on screen, but one of the twenty enemies may have an index of 32 if there are 50 total entities. So when the loop stops at 20, it never reaches that enemy.

DC
Ahh, this makes alot of sense. I even tried "count_enemies" myself and it did not work well.
Haven't said that, I re-copied O Ilusionista's first script and it is working now.
I guess I made some changes to some variables to his first script before which screwed up the script.

Thank you everyone!
 
so i wanted to make the script use MP instead of health and that part is all working good.
C:
void damageall(int damage, int drop, void atk_type, int mp_cost)
// thanks Lagarto, Piccolo, and White Dragon
// damage without effects, consumes MP when attack hits
{
    int iEntity;
    void vEntity;
    void self = getlocalvar("self");
    int iMax = openborvariant("count_entities");

    // Get current MP of the attacker
    int currentMP = getentityproperty(self, "mp");

    // Check if the attacker has enough MP
    if (currentMP < mp_cost) {
        return; // Not enough MP to perform the attack
    }

    // Spend MP
    changeentityproperty(self, "mp", currentMP - mp_cost);

    for (iEntity = 0; iEntity < iMax; iEntity++) {
        vEntity = getentity(iEntity);
        float x = getentityproperty(vEntity, "x") - openborvariant("xpos");
        float a = getentityproperty(vEntity, "a");
        float z = getentityproperty(vEntity, "z");

        if (getentityproperty(vEntity, "type") == openborconstant("TYPE_enemy")) {
            damageentity(vEntity, self, damage, drop, openborconstant(atk_type));
        }
    }
}

but the flash script from avengers does not displays the flash.. so after messing with this for hours i got it to display, but it wouldnt disapear on last hit, the last frame of the flash would stay behind and just sit there like an asshole lol
so i tried adding suicide and still the same... i dont kmpw much about scripts , theres no errors either,, the flash just wont kill itself xD

C:
// Function to kill the calling entity
void suicide()
{
    void self = getlocalvar("self");
    killentity(self);
}

// Function to spawn a flash entity and handle its lifespan
void flash_all_enemies(void vName)
{
    int iEntity;
    void vEntity;
    int iMax = openborvariant("count_entities");
    void lastSpawned = NULL();  // Variable to store last spawned entity

    // Spawn all enemies
    for (iEntity = 0; iEntity < iMax; iEntity++)
    {
        vEntity = getentity(iEntity);

        // Check if the entity is an enemy
        if (getentityproperty(vEntity, "type") == openborconstant("TYPE_enemy"))
        {
            // Get entity properties
            float x = getentityproperty(vEntity, "x") - openborvariant("xpos");
            float a = getentityproperty(vEntity, "a");
            float z = getentityproperty(vEntity, "z");

            // Clear spawn entry and set new values
            clearspawnentry();
            setspawnentry("name", vName);
            setspawnentry("coords", x, z + 1, a + 30);

            // Spawn entity and store its handle
            spawn();
            lastSpawned = getlocalvar("lastspawned");

            // Clear spawn entry for safety
            clearspawnentry();
        }
    }

    // After spawning, check and handle the last spawned entity
    if (lastSpawned != NULL())
    {
        // Example: Check if the last spawned entity's health reaches zero
        if (getentityproperty(lastSpawned, "health") <= 0)
        {
            suicide();  // Kill the last spawned entity
        }
    }
}

thanks for any help with this.



update... your avengers script does show the flash, still cant get rid of it tho... apologies am trying lol
 
Last edited:
so i tried adding suicide and still the same... i dont kmpw much about scripts , theres no errors either,, the flash just wont kill itself xD
By defaullt, a scripted entity will only do whatever you tell it to do.

Keep in mind that working with scripts gives you a lot of control over things, but here the word control is literal: you have to control what happens and the engine will only do what you tell it to do (excluding internal routines).

For example, when you invoke an entity using "knife", there are a series of variables that the engine fills in, such as "owner". However, when you do this via script, this does not happen - because you did not give this instruction.

When you use an entity as a flash and use the same entity via scripted spawn, they are very different things. If you don't say how long the entity has to remain active on the screen, it will remain active until some condition occurs (such as leaving the screen, colliding with another entity in the case of projectiles, etc.). If you just spawn her, she will stay on the screen and that's it.

In my case, to prevent what you report - which is something that can sometimes happen randomly in the engine and I never discovered the reason, I just know that it has been happening for many years now - I use two options:

1 - Provide the "lifespan" parameter in the entity header. In the Avengers project, all entities that are used as flash have this information

2 - To ensure that the entity is actually destroyed (as there are rare cases that lifespan does not kill the entity), I add an additional frame with an empty sprite - or you can simply duplicate the last frame and add the following code

@cmd killentity getlocalvar("self")
frame data/chars/empty.gif
 
By defaullt, a scripted entity will only do whatever you tell it to do.

Keep in mind that working with scripts gives you a lot of control over things, but here the word control is literal: you have to control what happens and the engine will only do what you tell it to do (excluding internal routines).

For example, when you invoke an entity using "knife", there are a series of variables that the engine fills in, such as "owner". However, when you do this via script, this does not happen - because you did not give this instruction.

When you use an entity as a flash and use the same entity via scripted spawn, they are very different things. If you don't say how long the entity has to remain active on the screen, it will remain active until some condition occurs (such as leaving the screen, colliding with another entity in the case of projectiles, etc.). If you just spawn her, she will stay on the screen and that's it.

In my case, to prevent what you report - which is something that can sometimes happen randomly in the engine and I never discovered the reason, I just know that it has been happening for many years now - I use two options:

1 - Provide the "lifespan" parameter in the entity header. In the Avengers project, all entities that are used as flash have this information

2 - To ensure that the entity is actually destroyed (as there are rare cases that lifespan does not kill the entity), I add an additional frame with an empty sprite - or you can simply duplicate the last frame and add the following code
that empty gif trick did it for me... thank you so much brother... its been a while and am old and feels like starting from scratch lol
thanks again for your great work and your assist :)
 
Funny enough, I just saw a video about my game where this bug appears. See at 12:12

I am using the "@cmd killentity getlocalvar("self")" code and, yet, after the entity had been killed....it appears again, using a different frame from the last animation frame and get stuck forever. This is an old engine bug.

To bypass this, I have to use that script + set a lifespan on its header.
 
Funny enough, I just saw a video about my game where this bug appears. See at 12:12

I am using the "@cmd killentity getlocalvar("self")" code and, yet, after the entity had been killed....it appears again, using a different frame from the last animation frame and get stuck forever. This is an old engine bug.

To bypass this, I have to use that script + set a lifespan on its header.
lol is a big one too .. man ive been gone for far to long.. i got your avengers game...never finished it, then again i hardly play since i am always doing artwork for attract mode builds
ill have to start collecting some at some point and make an openbor build xD
game looks good.
 
Back
Top Bottom