[SOLUCIONADO] como eliminar una entidad
#1
Buenas, acudo por una duda que me rompe el cerebro Whatdone

estoy tratando de eliminar una entidad especifica al crearse! ejemplo (eliminar un arma especifica al caer al suelo)

Código PHP:
if(ent "weapon_ak47")
  
remove_entity(ent
<- esto es un ejemplo equis...!!

hice esto:
Código PHP:
// plugin init
RegisterHam(Ham_Spawn"weaponbox""weapon_spawn"1)

public 
weapon_spawn(ent)
{
    if( !
pev_valid(ent))
        return 
HAM_IGNORED
    
    
while((ent engfunc(EngFunc_FindEntityByString, -1"classname""weapon_awp")) != 0)
        
engfunc(EngFunc_RemoveEntityent)
        
    return 
HAM_SUPERCEDE

pero me tumba el serverr jajaj!
Mi 250 :3
[Imagen: anigif2.gif]
Responder
#2
EDIT: si no funciona aca tenes creo q esto te servira https://amxmodx-es.com/Thread-Plugin-desaparecer-armas

Código PHP:
/**
 * Hooks the virtual table for the specified entity class.
 * An example would be: RegisterHam(Ham_TakeDamage, "player", "player_hurt");
 * Look at the Ham enum for parameter lists.
 *
 * @param function        The function to hook.
 * @param EntityClass    The entity classname to hook.
 * @param callback        The forward to call.
 * @param post            Whether or not to forward this in post.
 * @return                 Returns a handle to the forward.  Use EnableHamForward/DisableHamForward to toggle the forward on or off.
 */
native HamHook:RegisterHam(Ham:function, const EntityClass[], const Callback[], Post=0); 

Cita: * @param2 EntityClass The entity classname to hook.

Código PHP:
RegisterHam(Ham_Spawn"weaponbox""weapon_spawn"1
->
Código PHP:
RegisterHam(Ham_Spawn"weapon_awp""weapon_spawn"1

Código PHP:
public weapon_spawn(ent)
{
    if( !
pev_valid(ent)) // este if en todo caso sirve para rehlds que se bugea todo la kk esa
        
return HAM_IGNORED
        
    
return HAM_SUPERCEDE


[Imagen: giphy.gif]
Responder
#3
cada intento me ha terminado tumbando el servidor al dropear cualquier arma al utilizar el weaponbox y al comprar o dropear cualquier awp al utilizarlo como weapon_awp

solucion?
Mi 250 :3
[Imagen: anigif2.gif]
Responder
#4
https://forums.alliedmods.net/showthread.php?t=169404
Responder
#5
si, ese metodo esta en la respuesta de pan bimbo, pero con ese metodo se eliminan todas weapobox es decir TODA arma que sea dropeada...

trato de hookear que se elimine solamente 1 tipo de arma especifica "weapon_###"

encontre esta guia sobre entidades
https://amxmodx-es.com/Thread-GUIA-FindE...-derivados

y con los findentity uno puede encontrar el armoury_entity que vendria siendo Un ama en el suelo por lo que se, pero no tengo idea de como averiguar "QUE ARMA" hay en el suelo

al utilizarse "classname" hacemos enfasis en una entidad general como lo seria weaponbox o armoury_entity... pero como averiguo o como le haria para manipular el hecho de que en el suelo exista una entidad especificamente llamada weapon_#### bien sea cualquier arma

ejemplo: que alguien dropee una AK47
detectamos que hay un weapon_ak47 o csw_ak47 y hacemos equis funcion con ella!
Mi 250 :3
[Imagen: anigif2.gif]
Responder
#6
->

Código PHP:
RegisterHam(Ham_Spawn"weapon_awp""weapon_spawn"1

por ahi algo rescatas de este tuto que esta hecho como mis códigos, una verga.

https://amxmodx-es.com/Thread-TUT-Como-c...des-ENGINE
Responder
#7

Cuando dropeas un arma, la forma en que se "conecta" con el jugador que la dropeo es la siguiente: player -> weaponbox -> weapon_*. Esta "conexión" se establece mediante el pev->owner, y es jerárquica.

Con ello me refiero, a que al dropear un arma X, su pev->owner se actualiza con la ID de la entidad weaponbox, la cual a su ves tiene su pev->owner apuntando al (guardando la ID de el) jugador que la dropeo.

Teniendo eso en mente, existen varias formas de hacer lo que pides.



Una manera rápida sin hacer uso de pfnSetModel, es hookear el comando "drop", cosa de almacenar el arma a ser dropeada (m_pActiveItem), y chequear si el arma es la que se busca ("weapon_*"):

Código PHP:
register_clcmd("drop""OnCommand_Drop");

const 
m_pActiveItem 373;
const 
XO_CBASEPLAYER 5;

public 
OnCommand_Drop(iClient)
{
    new 
iWeapon
    
new szWeaponName[21];
    
    
// Primero verificar si esta dropeando un arma especifica -> drop weapon_*
    
if (get_argv(1szWeaponNamecharsmax(szWeaponName)))
    {
        if (
equal(szWeaponName"weapon_*"))
        {
            
// buscamos aquella entidad que
            // tenga el pev->owner == iClient.
            
            // no me interesan los jugadores, por eso comienzo
            // desde el primer index de una entidad non-player.
            
iWeapon find_ent_by_owner(get_maxplayers(), szWeaponNameiClient);
            
            if (
iWeapon)
            {
                
// Le doy chance al juego de que remueva correctamente el arma al jugador
                // para luego removerla del mundo completamente.
                
set_task(0.1"OnTask_RemoveWeapon"iWeapon);
                
                return;
            }
        }
    }
    
    
iWeapon get_pdata_cbase(iClientm_pActiveItemXO_CBASEPLAYER);
    
    if (
iWeapon)
    {
        new 
szClassname[32];
        
        
entity_get_string(iWeaponEV_SZ_classnameszClassnamecharsmax(szClassname));
        
        if (
equal(szClassname"weapon_*"))
        {
            
// Le doy chance al juego de que remueva correctamente el arma al jugador
            // para luego removerla del mundo completamente.
            
set_task(0.1"OnTask_RemoveWeapon"iWeapon);
        }
    }
}

public 
OnTask_RemoveWeapon(iWeapon)
    
remove_entity(iWeapon); 



Teniendo en cuenta lo anteriormente dicho, otra forma seria buscar: la entidad que tenga su pev->owner igual al weaponbox al que se le aplica el modelo en pfnSetModel:

Código PHP:
register_forward(FM_SetModel"On_SetModel_Post"true);

public 
On_SetModel_Post(const iEnt)
{
    new 
szClassName[32];
    
    
entity_get_string(iEntityEV_SZ_classnameszClassNamecharsmax(szClassName));
    
    
//...
    
if (!equal(szClassName"weaponbox"))
        return;
    
    new 
iWeaponEnt UTIL_GetWeaponEntFromWeaponBox(iEntity);
    
    
// asegurarse de que se obtuvo un arma.
    
if (!iWeaponEnt)
        return;
    
    
entity_get_string(iWeaponEntEV_SZ_classnameszClassNamecharsmax(szClassName));
    
    if (
equal(szClassName"weapon_*"))
    {
        
remove_entity(iWeaponEnt);
        
        
// por precaucion, eliminemos tambien el weaponbox
        // para que no se bugee al intentar recoger el arma del suelo.
        
entity_set_float(iEntEV_FL_nexttinkget_gametime());
    }
}

// lo arme hace unos meses por temas de testing.
UTIL_GetWeaponEntFromWeaponBox(const iWeaponBoxEnt)
{
    static 
szWeaponClassName[MAX_WEAPON_CLASSNAME_LEN];
    
    new 
iWeaponEnt;
    
    for (new 
iCSW CSW_P228iCSW <= CSW_P90iCSW++)
    {
        if (
get_weaponname(iCSWszWeaponClassNamecharsmax(szWeaponClassName)))
        {
            
// solo me interesa encontrar un arma
            // que tenga su pev->owner == iWeaponBoxEnt
            // de ahi que si se encuentra alguna, detengo el ciclo
            // y devuelvo la ID encontrada.
            
            
            // no me interesan los jugadores, por eso comienzo
            // desde el primer index de una entidad non-player.
            
iWeaponEnt find_ent_by_owner(get_maxplayers()/*g_iMaxPlayers*/szWeaponClassNameiWeaponBoxEnt);
            
            if (
iWeaponEnt)
                break;
        }
    }
    
    return 
iWeaponEnt;




Y ya para terminar, me parece que la manera correcta de realizar esto seria hookeando CBasePlayer:Gran sonrisaropPlayerItem con Orpheu u algún otro modulo. Así se consigue interceptar el dropeo del arma propiamente y se puede verificar de una manera mas sencilla si es el arma que se busca.

Pero eso lo dejo a tu imaginación, ya que no doy para buscar firmas ahorita Roflmao.

Responder
#8
(16/12/2018, 10:49 PM)SVC escribió:
Cuando dropeas un arma, la forma en que se "conecta" con el jugador que la dropeo es la siguiente: player -> weaponbox -> weapon_*. Esta "conexión" se establece mediante el pev->owner, y es jerárquica.

Con ello me refiero, a que al dropear un arma X, su pev->owner se actualiza con la ID de la entidad weaponbox, la cual a su ves tiene su pev->owner apuntando al (guardando la ID de el) jugador que la dropeo.

Teniendo eso en mente, existen varias formas de hacer lo que pides.



Una manera rápida sin hacer uso de pfnSetModel, es hookear el comando "drop", cosa de almacenar el arma a ser dropeada (m_pActiveItem), y chequear si el arma es la que se busca ("weapon_*"):

Código PHP:
register_clcmd("drop""OnCommand_Drop");

const 
m_pActiveItem 373;
const 
XO_CBASEPLAYER 5;

public 
OnCommand_Drop(iClient)
{
    new 
iWeapon
    
new szWeaponName[21];
    
    
// Primero verificar si esta dropeando un arma especifica -> drop weapon_*
    
if (get_argv(1szWeaponNamecharsmax(szWeaponName)))
    {
        if (
equal(szWeaponName"weapon_*"))
        {
            
// buscamos aquella entidad que
            // tenga el pev->owner == iClient.
            
            // no me interesan los jugadores, por eso comienzo
            // desde el primer index de una entidad non-player.
            
iWeapon find_ent_by_owner(get_maxplayers(), szWeaponNameiClient);
            
            if (
iWeapon)
            {
                
// Le doy chance al juego de que remueva correctamente el arma al jugador
                // para luego removerla del mundo completamente.
                
set_task(0.1"OnTask_RemoveWeapon"iWeapon);
                
                return;
            }
        }
    }
    
    
iWeapon get_pdata_cbase(iClientm_pActiveItemXO_CBASEPLAYER);
    
    if (
iWeapon)
    {
        new 
szClassname[32];
        
        
entity_get_string(iWeaponEV_SZ_classnameszClassnamecharsmax(szClassname));
        
        if (
equal(szClassname"weapon_*"))
        {
            
// Le doy chance al juego de que remueva correctamente el arma al jugador
            // para luego removerla del mundo completamente.
            
set_task(0.1"OnTask_RemoveWeapon"iWeapon);
        }
    }
}

public 
OnTask_RemoveWeapon(iWeapon)
    
remove_entity(iWeapon); 



Teniendo en cuenta lo anteriormente dicho, otra forma seria buscar: la entidad que tenga su pev->owner igual al weaponbox al que se le aplica el modelo en pfnSetModel:

Código PHP:
register_forward(FM_SetModel"On_SetModel_Post"true);

public 
On_SetModel_Post(const iEnt)
{
    new 
szClassName[32];
    
    
entity_get_string(iEntityEV_SZ_classnameszClassNamecharsmax(szClassName));
    
    
//...
    
if (!equal(szClassName"weaponbox"))
        return;
    
    new 
iWeaponEnt UTIL_GetWeaponEntFromWeaponBox(iEntity);
    
    
// asegurarse de que se obtuvo un arma.
    
if (!iWeaponEnt)
        return;
    
    
entity_get_string(iWeaponEntEV_SZ_classnameszClassNamecharsmax(szClassName));
    
    if (
equal(szClassName"weapon_*"))
    {
        
remove_entity(iWeaponEnt);
        
        
// por precaucion, eliminemos tambien el weaponbox
        // para que no se bugee al intentar recoger el arma del suelo.
        
entity_set_float(iEntEV_FL_nexttinkget_gametime());
    }
}

// lo arme hace unos meses por temas de testing.
UTIL_GetWeaponEntFromWeaponBox(const iWeaponBoxEnt)
{
    static 
szWeaponClassName[MAX_WEAPON_CLASSNAME_LEN];
    
    new 
iWeaponEnt;
    
    for (new 
iCSW CSW_P228iCSW <= CSW_P90iCSW++)
    {
        if (
get_weaponname(iCSWszWeaponClassNamecharsmax(szWeaponClassName)))
        {
            
// solo me interesa encontrar un arma
            // que tenga su pev->owner == iWeaponBoxEnt
            // de ahi que si se encuentra alguna, detengo el ciclo
            // y devuelvo la ID encontrada.
            
            
            // no me interesan los jugadores, por eso comienzo
            // desde el primer index de una entidad non-player.
            
iWeaponEnt find_ent_by_owner(get_maxplayers()/*g_iMaxPlayers*/szWeaponClassNameiWeaponBoxEnt);
            
            if (
iWeaponEnt)
                break;
        }
    }
    
    return 
iWeaponEnt;




Y ya para terminar, me parece que la manera correcta de realizar esto seria hookeando CBasePlayer:Gran sonrisaropPlayerItem con Orpheu u algún otro modulo. Así se consigue interceptar el dropeo del arma propiamente y se puede verificar de una manera mas sencilla si es el arma que se busca.

Pero eso lo dejo a tu imaginación, ya que no doy para buscar firmas ahorita Roflmao.


te la comiste bro, me sirvio al 100 con el forward ya que no queria hookear el drop (aunque no lo he probado con el drop) pero a simple vista tambien se ve que funciona, otra solucion que habia realizado era en el curweapon setie un if(is_user_admin(id) donde si el arma era un "weapon_awp" se la quitaba y le soltaba un mensaje pero con tus dos soluciones voy a jugar un monton

+1000
Mi 250 :3
[Imagen: anigif2.gif]
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)