AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   Finding certain entity in sphere (https://forums.alliedmods.net/showthread.php?t=282475)

SkazzY 05-07-2016 19:26

Finding certain entity in sphere
 
First of all code :
PHP Code:

public DetonateLasermine(id)
{
    new 
EntityName[32];
    new 
Float:origin[3]
    
pev(id,pev_origin,origin);
    new 
ent = -1
    ColorChat
(idRED"^4[SkazzY LaserMine] ^1Plugin is ^3WORKING")
    while((
ent find_ent_in_sphere(id,origin,512.0)) != 0) {
        
pev(entpev_classnameEntityName31)
        if(
equali(EntityNameENT_CLASS_NAME))
        {
            if(
pev(entLASERMINE_OWNER) != id)
            {
                
ColorChat(idRED"^4[SkazzY LaserMine] ^1You don't have any lasermines in ^3RADIUS ^1of ^3512 ^1units")
                return 
PLUGIN_HANDLED
            
}
            else
            {
                
PlaySound(entSTOP_SOUND)
                
CreateExplosion(ent)
                
CreateDamage(entget_pcvar_float(g_LRDMG), get_pcvar_float(g_LRADIUS))
                
RemoveEntity(ent)
                
ColorChat(idRED"^4[SkazzY LaserMine] ^1You have succesfully ^3DETONATED ^1your lasermine")
                return 
PLUGIN_HANDLED
            
}
        }
        
ColorChat(idRED"^4[SkazzY LaserMine] ^1There are no lasermines in ^3RADIUS ^1of ^3512 ^1units")
        return 
PLUGIN_HANDLED
    
}  
    return 
PLUGIN_HANDLED


Explain :
So first of all, this is just a part of modified LaserMine plugin (lasermine_023) which i didn't make, most of things are changed but nothing that is important in this exact function. For those who don't know this plugin, it sets a entity lasermine box that emits "light" and deals damage. What i am trying to do is detonate entity in radius of 512 units with conditions of its classname being "lasermine" == ENT_CLASS_NAME (ENT_CLASS_NAME is defined at the top of the code and that classname is set while creating lasermine), and it needs to be yours (LASERMINE_OWNER is defined and set same as ENT_CLASS_NAME).

Problem :
No matter where i go, how many lasers/entities surround it pops this message :
Code:

[SkazzY LaserMine] Plugin is WORKING
[SkazzY LaserMine] There are no lasermines in RADIUS of 512 units

Which means plugin did find entity but that entity isn't lasermine.
Same message appears if i go out of the map where there are no entities.

Black Rose 05-08-2016 12:57

Re: Finding certain entity in sphere
 
LASERMINE_OWNER should probably be set to pev_iuser1 or something similar, depending on what the plugin uses to define the owner of it.

SkazzY 05-08-2016 16:19

Re: Finding certain entity in sphere
 
Yes, it is define as pev_iuser2
PHP Code:

#define LASERMINE_OWNER        pev_iuser2 


Black Rose 05-08-2016 17:05

Re: Finding certain entity in sphere
 
Code:
            if(pev(ent, LASERMINE_OWNER) != id)             {                 ColorChat(id, RED, "^4[SkazzY LaserMine] ^1You don't have any lasermines in ^3RADIUS ^1of ^3512 ^1units")                 return PLUGIN_HANDLED             }             else             {                 PlaySound(ent, STOP_SOUND)                 CreateExplosion(ent)                 CreateDamage(ent, get_pcvar_float(g_LRDMG), get_pcvar_float(g_LRADIUS))                 RemoveEntity(ent)                 ColorChat(id, RED, "^4[SkazzY LaserMine] ^1You have succesfully ^3DETONATED ^1your lasermine")                 return PLUGIN_HANDLED             }
This means that if you find one entity matching the classname that isn't yours it will return instantly, not even bothering checking any others.
You probably want to remove the "return" inside the if/else statement. Make a counter to see if you got any matches, display messages after the loop is complete, not during. You have got to let the loop finish completely. otherwise it will turn into a lottery.

Xalus 05-08-2016 23:36

Re: Finding certain entity in sphere
 
Code:

public DetonateLasermine(id)
{
        new EntityName[32];
        new Float:origin[3]
        pev(id,pev_origin,origin);
        new ent = -1
        ColorChat(id, RED, "^4[SkazzY LaserMine] ^1Plugin is ^3WORKING")
       
        while((ent = find_ent_in_sphere(id,origin,512.0)) != 0)
        {
                pev(ent, pev_classname, EntityName, 31)
                if(equali(EntityName, ENT_CLASS_NAME))
                {
                        if(pev(ent, LASERMINE_OWNER) == id)
                        {
                                PlaySound(ent, STOP_SOUND)
                                CreateExplosion(ent)
                                CreateDamage(ent, get_pcvar_float(g_LRDMG), get_pcvar_float(g_LRADIUS))
                                RemoveEntity(ent)
                                ColorChat(id, RED, "^4[SkazzY LaserMine] ^1You have succesfully ^3DETONATED ^1your lasermine")
                               
                                ent = -99;
                                break
                        }
                }
        }
        if(ent != -99)
        {
                ColorChat(id, RED, "^4[SkazzY LaserMine] ^1You don't have any lasermines in ^3RADIUS ^1of ^3512 ^1units")
        }
        return PLUGIN_HANDLED
}


SkazzY 05-09-2016 15:30

Re: Finding certain entity in sphere
 
I totally forgot i need to loop all entities, so dumb. As you said it will turn into lottery.
@Black Rose
Appreciate explaining

@XaluX
Appreciate the code

EDIT : XaluX your code crashes my server after entering loop (It displays message that plugin is running, i made it with log_amx because that is instant without delay).

Black Rose 05-10-2016 11:15

Re: Finding certain entity in sphere
 
I don't see an obvious reason for the crash. Xalus code will still only find one lasermine and destroy it.
If you want to edit it to find more you need to remove "ent = -99;" and "break". But you also have to find another condition to display the message. I strongly suggest a counter. And if counter is not equal to 0, display the message.
To find what part of the code crashes the server, add log_amx between each line to see exactly where it stops. Like this for example:
Code:
    log_amx("Starting the loop");     while((ent = find_ent_in_sphere(id,origin,512.0)) != 0)     {         log_amx("Looping entity %d", ent);         pev(ent, pev_classname, EntityName, 31)         if(equali(EntityName, ENT_CLASS_NAME))         {             log_amx("Classname match on entity %d", ent);             if(pev(ent, LASERMINE_OWNER) == id)             {                 log_amx("Owner match on entity %d: %d", ent, id);                 PlaySound(ent, STOP_SOUND)                 log_amx("PlaySound completed");                 CreateExplosion(ent)                 log_amx("CreateExplosion completed");                 CreateDamage(ent, get_pcvar_float(g_LRDMG), get_pcvar_float(g_LRADIUS))                 log_amx("CreateDamage completed");                 RemoveEntity(ent)                 log_amx("RemoveEntity completed");                 ColorChat(id, RED, "^4[SkazzY LaserMine] ^1You have succesfully ^3DETONATED ^1your lasermine")                 log_amx("ColorChat completed");                                 ent = -99;                 break             }         }     }     log_amx("Loop completed");
And as a side note, almost all code is instant. There is only one thread in AMXX and HLDS for that matter. Otherwise you would not be able to manipulate hooks and stop them if necessary.
As far as plugin coding goes, as long as you're inside a function in your code, nothing else will run until that function is finished.
The exception is if a module creates another thread. But this can only be done with certain things, like sockets or heavy calculations that does not require any input to finish.

SkazzY 05-10-2016 14:52

Re: Finding certain entity in sphere
 
Server that i am making this for allows only 1 lasermine/player so that is not big of a problem. All of those messages were just for testing purposes, so I don't need to check logs, i just look at the chat and see what comes up, i'll just make 1 message "You detonated your lasermine" and "You don't have lasermine in radius of 512 units". First one is when the entity is found and when it gets destroyed before the break, and second one is when loop ends i'll just check if ent == -99 or not. In theory that should work. For log_amx I'll add that and i'll edit this post later today with results (Double posts are not allowed, correct me if i am wrong).

Edited
Code:

L 05/10/2016 - 21:58:31: [lasermine_test.amxx] Looping entity 40
Log for starting loop is shown and then this log (The one in [code]) is repeated 187101 times.

Black Rose 05-11-2016 15:56

Re: Finding certain entity in sphere
 
With the same entity? (40)

What version of Engine are you using. Write "meta list" in your console to find out.

Try using the fakemeta alternative just to see if you get a different result.
engfunc(EngFunc_FindEntityInSphere, index, Float:origin[3], Float:radius)

I can't see a reason within your code that will cause this error. For all I know, this is how that function is supposed to be used.

SkazzY 05-11-2016 18:51

Re: Finding certain entity in sphere
 
PHP Code:

Currently loaded plugins:
      
description      stat pend  file              vers      src  load  unlod
 
1AMX Mod X        RUN   -    amxmodx_mm.dll    v1.8.1.3  ini  Start ANY  
 
2Fun              RUN   -    fun_amxx.dll      v1.8.1.3  pl1  ANY   ANY  
 
3Engine           RUN   -    engine_amxx.dll   v1.8.1.3  pl1  ANY   ANY  
 
4FakeMeta         RUN   -    fakemeta_amxx.dl  v1.8.1.3  pl1  ANY   ANY  
 
5CStrike          RUN   -    cstrike_amxx.dll  v1.8.1.3  pl1  ANY   ANY  
 
6CSX              RUN   -    csx_amxx.dll      v1.8.1.3  pl1  ANY   ANY  
 
7Ham Sandwich     RUN   -    hamsandwich_amxx  v1.8.1.3  pl1  ANY   ANY  
 
8MySQL            RUN   -    mysql_amxx.dll    v1.8.1.3  pl1  ANY   ANY  
8 plugins
8 running 

Yes, it was same entity (40) whole time.
I changed from :
PHP Code:

while((ent find_ent_in_sphere(id,origin,512.0)) != 0

to
PHP Code:

while((ent engfunc(EngFunc_FindEntityInSphere,id,origin,512.0)) != 0

error is still there, but i just wondered what would happen if i did it multiple times at different places. First time same error with entity 50, second time on different side of the map same error with entity 40, third time same place as first time error with entity 40.


All times are GMT -4. The time now is 18:37.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.