Raised This Month: $51 Target: $400
 12% 

Correct safety remove entity


Post New Thread Reply   
 
Thread Tools Display Modes
DeMNiX
Veteran Member
Join Date: Nov 2011
Location: Russia
Old 10-13-2023 , 04:53   Re: Correct safety remove entity
Reply With Quote #11

Quote:
Originally Posted by MrPickles View Post
error will throw, u are starting the think to an invalid entity, u removed it before with FL_KILLME

setting KILL ME or with remove_entity( ent ) its more than enough.
Nope. FL_KILLME will remove object on next server tick.
On current server tick we just forcing to call Think function by DLLFunc_Think
__________________
My channel with test codes
https://www.youtube.com/user/demnix03

Zombie Riot [Scenario & bots-zombie 11.11.2023]
https://youtu.be/8ZZan-aq2sc
DeMNiX is offline
lexzor
Veteran Member
Join Date: Nov 2020
Old 10-13-2023 , 04:54   Re: Correct safety remove entity
Reply With Quote #12

not the next server tick, next entity tick
lexzor is offline
Jhob94
AMX Mod X Donor
Join Date: Jul 2012
Old 10-13-2023 , 05:24   Re: Correct safety remove entity
Reply With Quote #13

Quote:
Originally Posted by mlibre View Post
OR

PHP Code:
stock kill_entity(ent)
{
    
entity_set_int(entEV_INT_flagsFL_KILLME)

Why do you make a stock for 1 single line?

Anyway lexzor and natesh are right. Depending on what entity you are managing you may or may not need to call the entity think.
If you know that the entity think won't be called in a very short period of time you must call it yourself.
__________________
Jhob94 is offline
lexzor
Veteran Member
Join Date: Nov 2020
Old 10-13-2023 , 05:29   Re: Correct safety remove entity
Reply With Quote #14

you guys are just turning a simple situation into a complex one

to delete an entity, on it's next think must have flag FL_KILLME

is not important how do you call next think
lexzor is offline
DeMNiX
Veteran Member
Join Date: Nov 2011
Location: Russia
Old 10-13-2023 , 05:42   Re: Correct safety remove entity
Reply With Quote #15

unexpected result

Code:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>

new g_iFrame;

public plugin_init()
{
	RegisterHookChain(RH_ED_Free, "fw_OnFreeEdictPre");
	register_forward(FM_StartFrame, "fw_OnStartFrame")
	RegisterHam(Ham_Think, "info_target", "fw_NextThink");	
	RegisterHam(Ham_Think, "info_target", "fw_NextThink", true);	
}

public plugin_cfg()
{
	set_task(5.0, "test_func");
}

public fw_OnStartFrame()
{
	g_iFrame++;
}

public test_func()
{
	new iEnt = rg_create_entity("info_target");

	if (iEnt > 0) {

		set_entvar(iEnt, var_classname, "test_kill");

		new szClassname[32]; get_entvar(iEnt, var_classname, szClassname, charsmax(szClassname));
		server_print("~~~ OnSpawn [%s][%f][%d]", szClassname, get_gametime(), g_iFrame);

		dllfunc(DLLFunc_Think, iEnt);
		set_entvar(iEnt, var_nextthink, get_gametime());
		set_entvar(iEnt, var_flags, FL_KILLME);
		dllfunc(DLLFunc_Think, iEnt);
                dllfunc(DLLFunc_Think, iEnt);
	}
}

public fw_NextThink(iEnt)
{
	new szClassname[32]; get_entvar(iEnt, var_classname, szClassname, charsmax(szClassname));
	server_print("~~~ OnEntThink [%s][%f][%d]", szClassname, get_gametime(), g_iFrame);
}

public fw_OnFreeEdictPre(iEnt)
{
	new szClassname[32]; get_entvar(iEnt, var_classname, szClassname, charsmax(szClassname));
	server_print("~~~ OnEntRemove [%s][%f][%d]", szClassname, get_gametime(), g_iFrame);
}
Code:
~~~ OnSpawn [test_kill][6.074496][4047]
~~~ OnEntThink [test_kill][6.074496][4047]
~~~ OnEntThink [test_kill][6.074496][4047]
~~~ OnEntThink [test_kill][6.074496][4047]
~~~ OnEntThink [test_kill][6.074496][4047]
~~~ OnEntThink [test_kill][6.074496][4047]
~~~ OnEntThink [test_kill][6.074496][4047]
~~~ OnEntRemove [test_kill][6.074496][4047]
seems like not on think? but on end of the server's frame tick?

or OnStartFrame call after check all ents on flkillme flag?
__________________
My channel with test codes
https://www.youtube.com/user/demnix03

Zombie Riot [Scenario & bots-zombie 11.11.2023]
https://youtu.be/8ZZan-aq2sc
DeMNiX is offline
DeMNiX
Veteran Member
Join Date: Nov 2011
Location: Russia
Old 10-13-2023 , 05:42   Re: Correct safety remove entity
Reply With Quote #16

>is not important how do you call next think
its true, but interesting


seems like on the end of the server frame ent removes

Code:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>

new g_iFrame;
new g_bShouldPrintNewFrame;

public plugin_init()
{
	RegisterHookChain(RH_ED_Free, "fw_OnFreeEdictPre");
	RegisterHookChain(RH_ED_Free, "fw_OnFreeEdictPost", true);
	register_forward(FM_StartFrame, "fw_OnStartFrame")
	RegisterHam(Ham_Think, "info_target", "fw_NextThink");	
	RegisterHam(Ham_Think, "info_target", "fw_NextThink", true);	
}

public plugin_cfg()
{
	set_task(5.0, "test_func");
}

public fw_OnStartFrame()
{
	g_iFrame++;

	if (g_bShouldPrintNewFrame) {
		server_print("~~~ OnStartFrame [%f][%d]", get_gametime(), g_iFrame);
		g_bShouldPrintNewFrame = false;
	}
}

public test_func()
{
	new iEnt = rg_create_entity("info_target");

	if (iEnt > 0) {

		set_entvar(iEnt, var_classname, "test_kill");

		new szClassname[32]; get_entvar(iEnt, var_classname, szClassname, charsmax(szClassname));
		server_print("~~~ OnSpawn [%s][%f][%d]", szClassname, get_gametime(), g_iFrame);

		dllfunc(DLLFunc_Think, iEnt);
		set_entvar(iEnt, var_nextthink, get_gametime());
		set_entvar(iEnt, var_flags, FL_KILLME);
		dllfunc(DLLFunc_Think, iEnt);
		dllfunc(DLLFunc_Think, iEnt);

		g_bShouldPrintNewFrame = true;
	}
}

public fw_NextThink(iEnt)
{
	new szClassname[32]; get_entvar(iEnt, var_classname, szClassname, charsmax(szClassname));
	server_print("~~~ OnEntThink [%s][%f][%d]", szClassname, get_gametime(), g_iFrame);
}

public fw_OnFreeEdictPre(iEnt)
{
	new szClassname[32]; get_entvar(iEnt, var_classname, szClassname, charsmax(szClassname));
	server_print("~~~ OnEntRemove [%s][%f][%d]", szClassname, get_gametime(), g_iFrame);
}

public fw_OnFreeEdictPost(iEnt)
{
	server_print("~~~ OnEntRemovePost [%f][%d]", get_gametime(), g_iFrame);
	RequestFrame("fw_OnNextFrame");
}

public fw_OnNextFrame()
{
	server_print("~~~ 	OnNextFrame [%f][%d]", get_gametime(), g_iFrame);
}

Code:
~~~ OnSpawn [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntRemove [test_kill][6.081494][4052]
~~~ OnEntRemovePost [6.081494][4052]
~~~ OnStartFrame [6.081494][4053]
~~~     OnNextFrame [6.081494][4053]
so, with fl_killme none requires to checks on valid ents with dllfunc_think
__________________
My channel with test codes
https://www.youtube.com/user/demnix03

Zombie Riot [Scenario & bots-zombie 11.11.2023]
https://youtu.be/8ZZan-aq2sc

Last edited by DeMNiX; 10-13-2023 at 05:56.
DeMNiX is offline
mlibre
Veteran Member
Join Date: Nov 2015
Location: return PLUGIN_CONTINUE
Old 10-13-2023 , 10:12   Re: Correct safety remove entity
Reply With Quote #17

Quote:
Originally Posted by Jhob94 View Post
Why do you make a stock for 1 single line?
It is a simplified example to use in more functions. I always prefer to use the engine instead of fakemeta
__________________
mlibre is offline
Jhob94
AMX Mod X Donor
Join Date: Jul 2012
Old 10-13-2023 , 11:42   Re: Correct safety remove entity
Reply With Quote #18

Quote:
Originally Posted by DeMNiX View Post
>is not important how do you call next think
its true, but interesting


seems like on the end of the server frame ent removes

Code:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>

new g_iFrame;
new g_bShouldPrintNewFrame;

public plugin_init()
{
	RegisterHookChain(RH_ED_Free, "fw_OnFreeEdictPre");
	RegisterHookChain(RH_ED_Free, "fw_OnFreeEdictPost", true);
	register_forward(FM_StartFrame, "fw_OnStartFrame")
	RegisterHam(Ham_Think, "info_target", "fw_NextThink");	
	RegisterHam(Ham_Think, "info_target", "fw_NextThink", true);	
}

public plugin_cfg()
{
	set_task(5.0, "test_func");
}

public fw_OnStartFrame()
{
	g_iFrame++;

	if (g_bShouldPrintNewFrame) {
		server_print("~~~ OnStartFrame [%f][%d]", get_gametime(), g_iFrame);
		g_bShouldPrintNewFrame = false;
	}
}

public test_func()
{
	new iEnt = rg_create_entity("info_target");

	if (iEnt > 0) {

		set_entvar(iEnt, var_classname, "test_kill");

		new szClassname[32]; get_entvar(iEnt, var_classname, szClassname, charsmax(szClassname));
		server_print("~~~ OnSpawn [%s][%f][%d]", szClassname, get_gametime(), g_iFrame);

		dllfunc(DLLFunc_Think, iEnt);
		set_entvar(iEnt, var_nextthink, get_gametime());
		set_entvar(iEnt, var_flags, FL_KILLME);
		dllfunc(DLLFunc_Think, iEnt);
		dllfunc(DLLFunc_Think, iEnt);

		g_bShouldPrintNewFrame = true;
	}
}

public fw_NextThink(iEnt)
{
	new szClassname[32]; get_entvar(iEnt, var_classname, szClassname, charsmax(szClassname));
	server_print("~~~ OnEntThink [%s][%f][%d]", szClassname, get_gametime(), g_iFrame);
}

public fw_OnFreeEdictPre(iEnt)
{
	new szClassname[32]; get_entvar(iEnt, var_classname, szClassname, charsmax(szClassname));
	server_print("~~~ OnEntRemove [%s][%f][%d]", szClassname, get_gametime(), g_iFrame);
}

public fw_OnFreeEdictPost(iEnt)
{
	server_print("~~~ OnEntRemovePost [%f][%d]", get_gametime(), g_iFrame);
	RequestFrame("fw_OnNextFrame");
}

public fw_OnNextFrame()
{
	server_print("~~~ 	OnNextFrame [%f][%d]", get_gametime(), g_iFrame);
}

Code:
~~~ OnSpawn [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntThink [test_kill][6.081494][4052]
~~~ OnEntRemove [test_kill][6.081494][4052]
~~~ OnEntRemovePost [6.081494][4052]
~~~ OnStartFrame [6.081494][4053]
~~~     OnNextFrame [6.081494][4053]
so, with fl_killme none requires to checks on valid ents with dllfunc_think
As you can see it removes the Ent after think is called and before start frame.
So it is called on think. Anyway, this is irrelevant on most of cases.
__________________
Jhob94 is offline
metal_upa
Senior Member
Join Date: Jun 2016
Old 10-14-2023 , 05:45   Re: Correct safety remove entity
Reply With Quote #19

If you are using ReAPI then you can explore my code.
This is a template that i use on my custom entity.

Spoiler

Last edited by metal_upa; 10-14-2023 at 06:45. Reason: Typo
metal_upa is offline
Arje
Senior Member
Join Date: Apr 2020
Location: Córdoba, Argentina
Old 10-15-2023 , 12:04   Re: Correct safety remove entity
Reply With Quote #20

Quote:
Originally Posted by Natsheh View Post
This is the proper way to remove entities with specific classname by owner...

PHP Code:
new ent MAX_PLAYERS 1;

while( (
ent find_ent_by_owner(entgBlackHole_EntNameid)) > 0)
{
    
set_pev(entpev_flagsFL_KILLME);
    
dllfunc(DLLFunc_Thinkent);

Thanks lexzor and Natsheh for the help, both codes worked, although I stick with what you said that it is the best way to eliminate entities so I will use it,

On the other hand, I have a question regarding eliminating by owner, that is, it will only eliminate the entities that were created by that owner, or it will eliminate all entities independently of the owner, that is, I do not have to create a array for each entity created to correspond to each player,and then eliminate the entities that player is the owner?
Arje is offline
Reply



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 09:35.


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