• 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.

Solved Terminate an entity

Question that is answered or resolved.

O Ilusionista

Captain 80K
If you need to ternimate an entity, for whatever reason, you can use this script:

C-like:
void terminate(char target_name)
{// kill any entity on the screen by the given name
//Douglas Baldan - 11.27.2016 - Really thanks for the fix, White Dragon
// Thanks Lagarto
    int i;
    for (i = 0; i < openborvariant("count_entities"); ++i)
    {
            void ent = getentity(i);
        if ( getentityproperty(ent, "exists") )
           {
                   if ( getentityproperty(ent,"model") == target_name)
            {
                killentity(ent);
                continue;
            }
        } else continue;
    }
    return;  
}

Usage:
@cmd terminate "Max"

Just keep in mind that script is arbitrary: It will look for all models that have that name and finish ALL of them at once, not just one.

So, if you have two entities called "burnknuc" but you wanted to terminate just one of them, the script won't work - it will remove them all, as it looks for all models with that name, not just one, and ignores any alias you have given to them.

When I created this script, the idea was to eliminate entities that had somehow gotten stuck somewhere. You can use it for this, just keep in mind that it works by brute force and will affect all entities present in the game.

I have a series of scripts that manipulate entities, for different purposes and that vary in the degree of arbitrary: some check by name, animation, remaining life, etc. Others don't.

For example, this is a variation of the same script, but it will only work with entities that have the same "alias" that you provide:

C-like:
void terminateAlias(char target_name)
{// kill any entity on the screen by the given name
//Douglas Baldan - 2021.06.17 - Really thanks for the fix, White Dragon
// Thanks Lagarto
  int i;
  for (i = 0; i < openborvariant("count_entities"); ++i)
  {
        void ent = getentity(i);
    if ( getentityproperty(ent, "exists") )
      {
            if ( getentityproperty(ent,"name") == target_name)
      {
        killentity(ent);
        continue;
      }
    } else continue;
  }
  return;
}

Therefore, if you have two entities named "joe" but one of them you gave the alias "max", the script will terminate only the one named "max" if you tell it to do it:

@cmd terminateAlias "Max"

And another thing to be aware of: scripts are case sensitive.
If you ask the script to end an entity called "Max", it will not work if its alias is "max", "MAX", etc.



Thanks White Dragon for the help on the original topic.
 
Last edited:
hi!

here right code:
Code:
void terminate(char target_name)
{
	int i;
	for (i = 0; i < openborvariant("count_entities"); ++i)
	{
    		void ent = getentity(i);
		if ( getentityproperty(ent, "exists") )
	   	{
       			if ( getentityproperty(ent,"model") == target_name)
			{
				killentity(ent);
				continue;
			}
		} else continue;
	} 
	return;	
}

USAGE:
terminate("coin");

script fixes:
1) avoid to declare self if it isn't useful. It's a waste of memory
2) sure to use double apex to call the function: terminate("coin");
3) use char to explicit the var type
4) use openborvariant("count_entities") instead of openborconstant("MAX_ENTS") to be fast. openborconstant("MAX_ENTS") is a waste of computational time.
    you need of openborvariant("count_entities") because it counts all active ents.
5)  improve var names and explicits continue/return if you can for better code readability
 
Thanks.

1) I forgot to delete it.
2) So I should use @cmd terminate ("coin")? I was using @cmd terminate "coin"

    you need of openborvariant("count_entities") because it counts all active ents.
Ah so this is why I have a function using MAX_ENTITIES to spawn an effect  in every entity on the screen but sometimes it spawns even in dead entities (in fact, where those entities where standing). Thanks!

Why I shoyuld use CONTINUE after killentity?
 
O Ilusionista said:
Why I shoyuld use CONTINUE after killentity?

Continue is similar to break, except continue breaks out of the current iteration of a loop and immediately moves on to the next iteration, whereas break terminates the whole loop.

It's kind of frowned on as bad coding practice, but personally I find it very useful and logical. Especially in situations like this where the loop needs to finish no matter what, but there's no reason to continue a specific iteration once the work is done.

One thing I highly disagree with WD about though is inconsistent bracketing.

This is IMO terrible practice.
Code:
}
else continue;

Always, always, ALWAYS use brackets.

Code:
}
else
{
     continue;
}

DC
 
@cmd terminate "coin" is ok!

O Ilusionista said:
Why I shoyuld use CONTINUE after killentity?

Because if you want to kill ALL entities named "coin" you need to continue your loop.
if you use killentity(ent); and then return then you will kill JUST the first match!
the name isn't an ID...

Damon Caskey said:
Always, always, ALWAYS use brackets.

But why? It depends from code scope...
 
Thanks guys.
I have some doubts about some statements, and I would like some explanation:

use openborvariant("count_entities") instead of openborconstant("MAX_ENTS") to be fast. openborconstant("MAX_ENTS") is a waste of computational time.
Why? MAX_ENTS isn't a constant? Won't be faster to just check a constant value instead of counting entities? Because the first is just a check, while the second is a loop. Or are my logic wrong?

avoid to declare self if it isn't useful. It's a waste of memory
I can understand this as a waste because I won't use it for this function, but isn't self a localvar which was already declared by the engine and we are getting a value that is already there instead of setting a new one?

 
O Ilusionista said:
Thanks guys.
I have some doubts about some statements, and I would like some explanation:

use openborvariant("count_entities") instead of openborconstant("MAX_ENTS") to be fast. openborconstant("MAX_ENTS") is a waste of computational time.
Why? MAX_ENTS isn't a constant? Won't be faster to just check a constant value instead of counting entities? Because the first is just a check, while the second is a loop. Or are my logic wrong?

avoid to declare self if it isn't useful. It's a waste of memory
I can understand this as a waste because I won't use it for this function, but isn't self a localvar which was already declared by the engine and we are getting a value that is already there instead of setting a new one?

getlocalvar("self") already declared by engine buf if you declare
void self = getlocalvar("self") you are using a new variable called self that dies when the call is at the end.
So declare a var just when you use it or to avoid to call a few instructions.

MAX_ENTS is a constant that is the max number of entities that the engine can handle.
count_entities is a varibable that is number of entities actual existing in that time.
in generally (always really) MAX_ENTS > count_entities.
the entity list is maintained in order to have contiguous spaces.
So dont worry and just use count_entities for your scope.
 
Hi guys,

I'm trying to modify the code below to work with death animation instead of killentity. When I modified the code from killentity to damageentity for whatever reason it didn't work.  Is the code below correct for what I'm trying to accomplish?

Code:
        void terminate(char target_name)
{
	int i;
	for (i = 0; i < openborvariant("count_entities"); ++i)
	{
    		void ent = getentity(i);
		if ( getentityproperty(ent, "exists") )
	   	{
       			if ( getentityproperty(ent,"model") == target_name)
			{
				damageentity(ent);
				continue;
			}
		} else continue;
	}
	return;	
}     



 
PS VITA the synthax for "damageentity" is wrong
damageentity(entity, other, force, drop, type)

Damage the entity.
'entity' is the entity you want to damage.
'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself.
'force' is the attack force. default to 1.
'drop' is whether the attack knocks down the entity.
'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_'

 
O Ilusionista said:
PS VITA the synthax for "damageentity" is wrong
damageentity(entity, other, force, drop, type)

Damage the entity.
'entity' is the entity you want to damage.
'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself.
'force' is the attack force. default to 1.
'drop' is whether the attack knocks down the entity.
'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_'

I still don't understand. And please don't get frustrated,  because I learned that damageentity was what kills an entity with a death animation and the spelling appears to be exactly as in the manual and the game is not closing on me either when I launch it.

It's cool if you guys don't want to reply because I knew I was getting myself into deep waters when I tried to go from complete newb to using really advanced scripts. And that perhaps I should not try to be attempting this at my current level of openbor knowledge.




 
@psvita

just be patient - I am trying to figure it out myself too, because i will eventually need to use it for something -
i am still having trouble with the way scripts work  - because there is 2 ways to make them work, one is by making a "fill in the blank script" that you save in the scripts folder & you use between animation frames with @cmd scriptname

then there is this other type that is more "raw" you don't fill the information in & you have to do a bunch of lines to specify what the names & value of things are- these script are used within ondeath, onspawn, ondie script &/or in between animations are used like this:
@script
if(frame == 0){
void self = getlocalvar("self");
int map = rand()%2;
if(map < 0)
{
-map == map;
}
changeentityproperty(self, "map", map);
}
@end_script

death animation can fail & if you needed something to spawn or a music to change depending on it, another option is ONdeathscript or onkillscript
  if you need something to spawn & or music to change you can use those -
using this script within "ondeath" you can spawn anything you want & that something you spawn can do music changes, effects, level warps, drop items, etc

Code:
#import "data/scripts/spawn.c"
void main()
{
	spawnItem();
	//spawnItem2();
}

void spawnItem()
{//Spawns random item next to caller and toss it (RANDOM ITEM DROP FROM OBSTACLES)
	void self 	  = getlocalvar("self");
	void vName;
	void vSpawn;
	int dir 	  = getentityproperty(self,"direction");
	float fX 	  = getentityproperty(self, "x");
	float fY 	  = getentityproperty(self, "y");
	float fZ 	  = getentityproperty(self, "z");
	float Vx 	  = 0;
	float Vy 	  = 1;
	float Vz 	  = 0;
	float iR 	  = rand()%50+50;
	
	
	if(iR >= 0 && iR < 60){ //APPLE HAS A 60% CHANCE
		vName = "bosslow";
	}
	else
	if(iR >= 60 && iR <= 100){ //CHICKEN HAS A 40% CHANCE
		vName = "bosslow";
	}
	
	clearspawnentry();
	setspawnentry("name", vName);
	
	vSpawn = spawn();

	changeentityproperty(vSpawn, "position", fX, fZ, fY);
	changeentityproperty(vSpawn, "direction", dir);
	tossentity(vSpawn, Vy, Vx, Vz); //TOSS THE ITEM WITH DEFINED VELOCITY
	
	return vSpawn;
}

void spawnItem2()
{//Spawns random item next to caller and toss it (RANDOM ITEM DROP FROM OBSTACLES)
	void self 	  = getlocalvar("self");
	void vName;
	void vSpawn;
	int dir 	  = getentityproperty(self,"direction");
	float fX 	  = getentityproperty(self, "x");
	float fY 	  = getentityproperty(self, "y");
	float fZ 	  = getentityproperty(self, "z");
	float Vx 	  = 0;
	float Vy 	  = 1;
	float Vz 	  = 0;
	float iR 	  = rand()%50+50;
	
	
	if(iR >= 0 && iR < 60){ //APPLE HAS A 60% CHANCE
		vName = "itemr";
	}
	else
	if(iR >= 60 && iR <= 100){ //CHICKEN HAS A 40% CHANCE
		vName = "itemr2";
	}
	
	clearspawnentry();
	setspawnentry("name", vName);
	
	vSpawn = spawn();

	changeentityproperty(vSpawn, "position", fX, fZ, fY);
	changeentityproperty(vSpawn, "direction", dir);
	tossentity(vSpawn, Vy, Vx, Vz); //TOSS THE ITEM WITH DEFINED VELOCITY
	
	return vSpawn;
}
anyway , thanks to Kratus for this spawn script, & as you can see, its all those lines to just pretty much say this:
"spawn 0 0 0 0"  and spawn02 0 0 0 0
i kept the random stuff just in case & things can be deactivated using  "//" - in this case the second spawn is disabled

O Ilusionista - that is the part that gets very confusing about the manual - there is those @cmd scripts like fademusic & then there is the entries like spawn or damageentity that give you the impression that you can use them the same -

when in reality spawn needs links for the at least 3 different basic methods of how its really used (the Raw, the @cmd construct & the @script)
 
PS VITA said:
Is the code below correct for what I'm trying to accomplish?

Ilu simply meant that you need to fill in the missing parameters. The most obvious missing parameter is damage cause unlike killentity, damageentity function only damages the specified entity and engine needs to know how much damage is given.
My suggestion is to fix it into this:
Code:
damageentity(ent, ent, 1000, 0, openborconstant("ATK_NORMAL"));

I set 1000 damage assuming the to be damaged entity has health less than 1000 :).
 
Something else important to know, since damageentity() uses the engine's internal damage routine, meaning Offense and Defense settings are applied.

DC
 
Bloodbane said:
PS VITA said:
Is the code below correct for what I'm trying to accomplish?

Ilu simply meant that you need to fill in the missing parameters. The most obvious missing parameter is damage cause unlike killentity, damageentity function only damages the specified entity and engine needs to know how much damage is given.
My suggestion is to fix it into this:
Code:
damageentity(ent, ent, 1000, 0, openborconstant("ATK_NORMAL"));

I set 1000 damage assuming the to be damaged entity has health less than 1000 :).


Ooohhh, I see!

I thought that if you left out
certain parameters the engine usually defaults them to predetermined parameters, no?  But, I just realized that this doesn't work that way with scripts, correct?

Thank you all.

By the way, could the same code be modified to decrease a certain ammount of HP? Say 0%
50%, 75% or a flat number like -100 hp.
 
PS VITA said:
By the way, could the same code be modified to decrease a certain ammount of HP? Say 0%
50%, 75% or a flat number like -100 hp.

Sure, just with a bit of math work. Again, I have to point out damageentity() does factor Offense and Defense, and you need to take that into account. To help out, there's a native function that will calculate the actual damage you'll do to an entity, so you can use it to come up with a damage value that will get the target to 50% or whatever.

DC
 
Hi guys,

I modified this script so that if there are 10 entities of the same kind ( or more) the animation changes of who ever uses this script. But for some reason It wont work - could someone find out why?


For example - if  an alien nest is hatching more than 10 alien enemies it will change the animation to idle and stop the alien nest from spawning more aliens babies until there are less than 10 aliens alive.

Code:
 @cmd limit10 "alienbabies" "ANI_FOLLOW1"

Code:
void limit10(char target_name, void Ani)
{
        void self = getlocalvar("self");
	int i;
	for (i = 10; i < openborvariant("count_entities"); ++i)
	{
    		void ent = getentity(i);
		if ( getentityproperty(ent, "exists") )
	   	{
       			if ( getentityproperty(ent,"model") == target_name)
			{
				changeentityproperty(self, "animation", openborconstant(Ani)); //Change the animation
				continue;
			}
		} else continue;
	}
	return;	
}

EDIT it's basically  this piece of code created by Bloodbane

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

    if(frame>=1){
      void vEntity;                                       //Target entity placeholder.
      int  iEntity;                                       //Entity enumeration holder.
      char iName;                                         //Entity Name.
      int  iMax      = openborvariant("count_entities");         //Entity count.
      int C = 0;

      //Enumerate and loop through entity collection.
      for(iEntity=0; iEntity<iMax; iEntity++){
        vEntity = getentity(iEntity);                 //Get target entity from current loop.
        iName   = getentityproperty(vEntity, "name"); //Get target name.

        if(iName == "babyaliens"){
          C = C + 1;
        }
      }

      if(C >= 10){
        performattack(self, openborconstant("ANI_IDLE"));
      }
    }
@end_script

 
I'm trying to modify this script, so that instead of directly killing the entity, it deals damage to the entity. :unsure:
In this way, when removing it, it will show us its FALL or DEATH animation respectively. :)

This is my attempt, it doesn't give any error, but it doesn't work... :cautious:

C++:
void DamageEnt(char target_name)
{// Damage any entity on the screen by the given name

    int i;
    for (i = 0; i < openborvariant("count_entities"); ++i)
    {
            void ent = getentity(i);
        if ( getentityproperty(ent, "exists") )
           {
                   if ( getentityproperty(ent,"model") == target_name)
            {
                damageentity(ent, ent, 10000, 0, openborconstant("ATK_NORMAL")); // This line was updated
                continue;
            }
        } else continue;
    }
    return;
}

Update POST: It works perfectly, only, the problem was that the entity more health than the damage that the script causes.
I just updated this line and put 10000 damage on it.

C++:
damageentity(ent, ent, 10000, 0, openborconstant("ATK_NORMAL"));
 
Last edited:
Back
Top Bottom