Raised This Month: $ Target: $400
 0% 

Finding certain entity in sphere


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
SkazzY
AlliedModders Donor
Join Date: Nov 2014
Location: Forbidden Forest
Old 05-07-2016 , 19:26   Finding certain entity in sphere
Reply With Quote #1

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.

Last edited by SkazzY; 05-07-2016 at 19:59. Reason: Updated code
SkazzY is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 05-08-2016 , 12:57   Re: Finding certain entity in sphere
Reply With Quote #2

LASERMINE_OWNER should probably be set to pev_iuser1 or something similar, depending on what the plugin uses to define the owner of it.
__________________
Black Rose is offline
SkazzY
AlliedModders Donor
Join Date: Nov 2014
Location: Forbidden Forest
Old 05-08-2016 , 16:19   Re: Finding certain entity in sphere
Reply With Quote #3

Yes, it is define as pev_iuser2
PHP Code:
#define LASERMINE_OWNER        pev_iuser2 
SkazzY is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 05-08-2016 , 17:05   Re: Finding certain entity in sphere
Reply With Quote #4

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

Last edited by Black Rose; 05-08-2016 at 17:06.
Black Rose is offline
Xalus
Veteran Member
Join Date: Dec 2009
Location: Belgium
Old 05-08-2016 , 23:36   Re: Finding certain entity in sphere
Reply With Quote #5

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
}
__________________
Retired.
Xalus is offline
SkazzY
AlliedModders Donor
Join Date: Nov 2014
Location: Forbidden Forest
Old 05-09-2016 , 15:30   Re: Finding certain entity in sphere
Reply With Quote #6

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

Last edited by SkazzY; 05-09-2016 at 16:21.
SkazzY is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 05-10-2016 , 11:15   Re: Finding certain entity in sphere
Reply With Quote #7

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

Last edited by Black Rose; 05-10-2016 at 11:19.
Black Rose is offline
SkazzY
AlliedModders Donor
Join Date: Nov 2014
Location: Forbidden Forest
Old 05-10-2016 , 14:52   Re: Finding certain entity in sphere
Reply With Quote #8

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.

Last edited by SkazzY; 05-10-2016 at 16:02. Reason: Adding info
SkazzY is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 05-11-2016 , 15:56   Re: Finding certain entity in sphere
Reply With Quote #9

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

Last edited by Black Rose; 05-11-2016 at 16:16.
Black Rose is offline
SkazzY
AlliedModders Donor
Join Date: Nov 2014
Location: Forbidden Forest
Old 05-11-2016 , 18:51   Re: Finding certain entity in sphere
Reply With Quote #10

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.
SkazzY is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


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


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