Solved Item that slowdowns and disables enemy attack

Question that is answered or resolved.

kimono

Well-known member
Hi, I wish to create an item that reduce speed to 1 and make all enemies unable to attack that are on screen.
I thought about stealth mode but maybye it's better if these 2 effects are desactivated if the enemy is at pain or fall state to prevent its overuse against boss type.

Do you have any idea if stealth is the correct parameter to use here?
 
Solution
@kimono

Hey buddy, here's the script for the "slow" effect. I used the "vortex" entity as a test, you can apply to any other if you want.

This is the update entity event for the "vortex" entity. You can replace all the script used for the "swirl" effect:
C:
void main()
{    /*
    * Caskey, Damon V.
    * 2022-01-26
    *
    * Example function to enumerate the entity
    * collection and take action on each
    * if they meet specfifc conditions.
    */
    void entity_cursor    = NULL();
    int entity_count    = openborvariant("count_entities");
    int entity_index    = 0;
    int exists            = 0;

    /*
    * This loop runs on every entity in play.
    * It works by iterating from 0 to <entity count>.
    * At each...
Hi Bloodbane and thanks for your concern . When the item is activated, I wish that all enemies on screen are slowdowned and have their attack disabled (most of them possess only one basic attack) until they are hit by the player :D .

@Kratus sends me a solution for this script:
You can test it on the vortex script replacing the "swirl" part of the code with the functions below. The DC's part of the code is responsible for detecting all enemies, and the part which I developed is applying the "moving" effect.


float spd = getentityproperty(target, "speed"); //GET THE CURRENT SPEED
changeentityproperty(target, "speed", spd*0.25); //APPLY SPEED REDUCTION
changeentityproperty(target, "running", spd*0.50); //APPLY RUNNING REDUCTION
changeentityproperty(target, "jumpspeed", spd*0.25); //APPLY JUMP SPEED REDUCTION
changeentityproperty(target, "edelay", 1, 2, 1, 100, 1, 100); //INCREASE DELAY VALUE
changeentityproperty(self, "attackthrottle", 9999999999); //SET A HIGH VALUE TO DISABLE ATTACKS
changeentityproperty(self, "attackthrottletime", 9999999999); //SET A HIGH VALUE TO DISABLE ATTACKS
Maybye let the effect lasts for 15 seconds like the swirl can do the job. I will update this post once I've got some news . Thanks both of you :) .
 
Last edited:
Ok, so I tried to adapt the swirl script to the alarmwave.c :
Code:
void main()
{    /*
    * Caskey, Damon V.
    * 2022-01-26
    *
    * Example function to enumerate the entity
    * collection and take action on each
    * if they meet specific conditions.
    */
    void self   = getlocalvar("self");
    float time  = openborvariant("elapsed_time")/10;

    if(getglobalvar("alarmRate"+self) == NULL()){setglobalvar("alarmRate"+self, time);}

    if(time > getglobalvar("alarmRate"+self)){
        void entity_cursor    = NULL();
        int entity_count    = openborvariant("count_entities");
        int entity_index    = 0;
        int exists            = 0;

        /*
        * This loop runs on every entity in play.
        * It works by iterating from 0 to <entity count>.
        * At each iteration it gets an entity using the
        * index cursor, verifies its existence, and then
        * runs some custom checks.
        *
        * If any check fails, the loop skips and
        * moves on to the next iteration. If all the
        * checks pass, it runs whatever action code
        * you place inside of it. The best practice
        * is to put your action code into another
        * function and let the loop execute that.
        */

        for(entity_index = 0; entity_index < entity_count; entity_index++){
            /*
            * Get target entity for this loop increment,
            * verify it is a valid pointer, and make
            * sure it exists in play. The last check
            * appears redundant, but it's possible for
            * an entity to be removed while its pointer
            * is still valid.
            */

            entity_cursor = getentity(entity_index);

            if(!entity_cursor){
                continue;
            }

            exists = getentityproperty(entity_cursor, "exists");

            if(!exists){
                continue;
            }

            /*
            * Check for specific conditions to your module here.
            * This example skips non-enemy types.
            */

            if( getentityproperty(entity_cursor, "type") != openborconstant("TYPE_ENEMY")){
               
                continue;
            }

            /* Take your actions here. Slowdown, disable attacks, etc. */
            int lifespan    = getentityproperty(self, "lifespancountdown");

            //THIS IS THE ANIMATION THAT WILL ACTIVATE THE SLOWDOWN AND DISABLE ATTACK EFFECT
            if(lifespan > 5){
                float spd = getentityproperty(target, "speed"); //GET THE CURRENT SPEED
                changeentityproperty(target, "speed", spd*0.25); //APPLY SPEED REDUCTION
                changeentityproperty(target, "running", spd*0.50); //APPLY RUNNING REDUCTION
                changeentityproperty(target, "jumpspeed", spd*0.25); //APPLY JUMP SPEED REDUCTION
                changeentityproperty(target, "edelay", 1, 2, 1, 100, 1, 100); //INCREASE DELAY VALUE
                changeentityproperty(self, "attackthrottle", 9999999999); //SET A HIGH VALUE TO DISABLE ATTACKS
                changeentityproperty(self, "attackthrottletime", 9999999999); //SET A HIGH VALUE TO DISABLE ATTACKS
            else
            {
                int dead = getentityproperty(entity_cursor, "dead");
                if(!dead){
                    setidle(entity_cursor, openborconstant("ANI_IDLE"));
                }
            }
        }
        setglobalvar("alarmRate"+self, time);
    }
}
I've got a
Failed to parse script file
error. Can someone please point me what I've done wrong here? :)
The demo for testing at cinema set, stage terminator:
 
Several of your property changes are running on "target" or "self" variables. Those don't exist in this function. Replace them with entity_cursor.

DC
 
Thanks Damon, I tried to change the script like this, following your advice but I still encountered the same error:
Code:
void main()
{    /*
    * Caskey, Damon V.
    * 2022-01-26
    *
    * Example function to enumerate the entity
    * collection and take action on each
    * if they meet specific conditions.
    */
    void self   = getlocalvar("self");
    float time  = openborvariant("elapsed_time")/10;

    if(getglobalvar("alarmRate"+self) == NULL()){setglobalvar("alarmRate"+self, time);}

    if(time > getglobalvar("alarmRate"+self)){
        void entity_cursor    = NULL();
        int entity_count    = openborvariant("count_entities");
        int entity_index    = 0;
        int exists            = 0;

        /*
        * This loop runs on every entity in play.
        * It works by iterating from 0 to <entity count>.
        * At each iteration it gets an entity using the
        * index cursor, verifies its existence, and then
        * runs some custom checks.
        *
        * If any check fails, the loop skips and
        * moves on to the next iteration. If all the
        * checks pass, it runs whatever action code
        * you place inside of it. The best practice
        * is to put your action code into another
        * function and let the loop execute that.
        */

        for(entity_index = 0; entity_index < entity_count; entity_index++){
            /*
            * Get target entity for this loop increment,
            * verify it is a valid pointer, and make
            * sure it exists in play. The last check
            * appears redundant, but it's possible for
            * an entity to be removed while its pointer
            * is still valid.
            */

            entity_cursor = getentity(entity_index);

            if(!entity_cursor){
                continue;
            }

            exists = getentityproperty(entity_cursor, "exists");

            if(!exists){
                continue;
            }

            /*
            * Check for specific conditions to your module here.
            * This example skips non-enemy types.
            */

            if( getentityproperty(entity_cursor, "type") != openborconstant("TYPE_ENEMY")){
               
                continue;
            }

            /* Take your actions here. Slowdown, disable attacks, etc. */
            int lifespan    = getentityproperty(entity_cursor, "lifespancountdown");

            //THIS IS THE ANIMATION THAT WILL ACTIVATE THE SLOWDOWN AND DISABLE ATTACK EFFECT
            if(lifespan > 5){
                float spd = getentityproperty(entity_cursor, "speed"); //GET THE CURRENT SPEED
                changeentityproperty(entity_cursor, "speed", spd*0.25); //APPLY SPEED REDUCTION
                changeentityproperty(entity_cursor, "running", spd*0.50); //APPLY RUNNING REDUCTION
                changeentityproperty(entity_cursor, "jumpspeed", spd*0.25); //APPLY JUMP SPEED REDUCTION
                changeentityproperty(entity_cursor, "edelay", 1, 2, 1, 100, 1, 100); //INCREASE DELAY VALUE
                changeentityproperty(entity_cursor, "attackthrottle", 9999999999); //SET A HIGH VALUE TO DISABLE ATTACKS
                changeentityproperty(entity_cursor, "attackthrottletime", 9999999999); //SET A HIGH VALUE TO DISABLE ATTACKS
            else
            {
                int dead = getentityproperty(entity_cursor, "dead");
                if(!dead){
                    setidle(entity_cursor, openborconstant("ANI_IDLE"));
                }
            }
        }
    setglobalvar("alarmRate"+self, time);
    }
}
The same if I change all the self mentions by entity_cursor .
 
Not sure how else I can explain. Self does not exist at all. The script will never work like you have it.

The timer @Kratus added is not necessary for what you're doing. Remove it and the self variable.
 
Ok thanks for the explanation. If I wish that all enemies on screen have their speed decreased to 1 and disable their attack for 15 seconds (the lifespan of the alarmwave entity), how can I write it?
 
@kimono

Hey buddy, here's the script for the "slow" effect. I used the "vortex" entity as a test, you can apply to any other if you want.

This is the update entity event for the "vortex" entity. You can replace all the script used for the "swirl" effect:
C:
void main()
{    /*
    * Caskey, Damon V.
    * 2022-01-26
    *
    * Example function to enumerate the entity
    * collection and take action on each
    * if they meet specfifc conditions.
    */
    void entity_cursor    = NULL();
    int entity_count    = openborvariant("count_entities");
    int entity_index    = 0;
    int exists            = 0;

    /*
    * This loop runs on every entity in play.
    * It works by iterating from 0 to <entity count>.
    * At each iteration it gets an entity using the
    * index cursor, verifies its existence, and then
    * runs some custom checks.
    *
    * If any check fails, the loop skips and
    * moves on to the next iteration. If all the
    * checks pass, it runs whatever action code
    * you place inside of it. The best practice
    * is to put your action code into another
    * function and let the loop execute that.
    */

    for(entity_index = 0; entity_index < entity_count; entity_index++){
        /*
        * Get target entity for this loop increment,
        * verify it is a valid pointer, and make
        * sure it exists in play. The last check
        * appears redundant, but it's possible for
        * an entity to be removed while its pointer
        * is still valid.
        */

        entity_cursor = getentity(entity_index);

        if(!entity_cursor){
            continue;
        }

        exists = getentityproperty(entity_cursor, "exists");

        if(!exists){
            continue;
        }

        /*
        * Check for specific conditions to your module here.
        * This example skips non-enemy types.
        */

        if( getentityproperty(entity_cursor, "type") != openborconstant("TYPE_ENEMY")){
         
            continue;
        }

        /* Take your actions here. Sucking in, doing damage, etc. */

        float speed    = getentityproperty(entity_cursor, "speed");
        float reduce   = 0.1;
        int delay      = 4;
        int noAtk      = 9999999999;

        //THIS IS THE ANIMATION THAT WILL ACTIVATE THE SWIRL EFFECT, YOU CAN PUT ANY OTHER
        if(getentityvar(entity_cursor, "slow") == NULL()){
            changeentityproperty(entity_cursor, "speed", reduce); //APPLY SPEED REDUCTION
            changeentityproperty(entity_cursor, "running", reduce*2); //APPLY RUNNING REDUCTION
            changeentityproperty(entity_cursor, "jumpspeed", reduce*2); //APPLY JUMP SPEED REDUCTION
            changeentityproperty(entity_cursor, "edelay", 1, delay, 1, 100, 1, 100); //INCREASE DELAY VALUE
            changeentityproperty(entity_cursor, "attackthrottle", noAtk); //SET A HIGH VALUE TO DISABLE ATTACKS
            changeentityproperty(entity_cursor, "attackthrottletime", noAtk); //SET A HIGH VALUE TO DISABLE ATTACKS
            setentityvar(entity_cursor, "slow", 1);
        }
    }
}

Here's the takedamage script to restore the original properties, like speed:
C:
void main()
{//Restore normal speed when slow
    void self = getlocalvar("self");
    void model = getentityproperty(self,"model");
    int slow  = getentityvar(self, "slow");

    if(slow == 1){
        changeentityproperty(self, "model", "Reset_Model", 1);
        changeentityproperty(self, "model", model, 1);
        setidle(self);
        setentityvar(self, "slow", NULL());
    }
}

And this is an example of the "reset" model entity used in the script.
##MAIN
name Reset_Model #EMPTY MODEL TO RESET ABNORMAL STATUS
type none

##MISC
modelflag 3

##ANIMATIONS#############################################################################

anim idle
loop 0
delay 1
offset 50 50
frame data/chars/misc/reset/empty.gif

Here's the file with all the changes:

 
Last edited:
Solution
@Kratus: Excellent buddy, once again you saved my day, that's exactly the effect that I wanted to realize, great job ;) . Scriptwork is so awesome sometimes :) .
When the hero fights with bare hands, there are two types of enemies that are embarrassing: the shooter and flying type because it's difficult to reach them.
A defensive weapon like a buckler can be useful here, but the choice here is to debuff them with a sonic wave item in order to approach them more easily:
I think that make a longer delay to the anim walk should be enough here and doesn't slower the action.
 
Last edited:
I am interested in the script, which prevents the attacks from being executed. 🤨
I don't know if it works for what I need, but I suppose it does. :confused:
I need the player to be unable to perform certain specific attacks at a specific level. :unsure:
 
Back
Top Bottom