AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   Solved Multiple TraceHull (https://forums.alliedmods.net/showthread.php?t=329877)

ConorCC 01-11-2021 12:45

Multiple TraceHull
 
Using a TraceHull is very cool but can we detect multiple targets with it?
For example more than one player stant between the points and I want to print their names.

With TraceLine we can create multiple lines from the last endpoint to a new one but it is not possible here. Any solution?

Natsheh 01-11-2021 13:03

Re: Multiple TraceHull
 
we sure can, such an issue already was mentioned, you need to call tracehull multiplie times.

ConorCC 01-11-2021 13:10

Re: Multiple TraceHull
 
The solution working with traceline cause you can set the ignored ent with the last targeted ent and the new startpoint with the last endpoint.

In this case if I set the ignored ent to the last targeted ent nothing will change except that one will be ignored. But if you have at least 3 players in the range you won't be able to detect the 3rd one cause you only can ignore one ent.

That's why I think it doesn't work here.

Natsheh 01-11-2021 13:24

Re: Multiple TraceHull
 
https://forums.alliedmods.net/showthread.php?t=292114

PHP Code:

/* Plugin generated by AMXX-Studio */

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <xs>

#define PLUGIN "Entity Hit Effects"
#define VERSION "1.0"
#define AUTHOR "Natsheh"

new attacker_trace[33];

public 
plugin_init()
{
    
register_plugin(PLUGINVERSIONAUTHOR)
    
    
RegisterHam(Ham_TraceAttack"info_target""fw_TraceAttack_infotarget")
    
RegisterHam(Ham_TraceAttack"func_breakable""fw_TraceAttack_infotarget")
    
RegisterHam(Ham_TraceAttack"player""fw_TraceAttack_player")
}

public 
fw_TraceAttack_player(victimattackerFloat:damageFloat:direction[3], traceresultdamagebits)
{
    if(!
is_user_connected(attacker) || !(damagebits DMG_BULLET)) return FMRES_IGNORED;
    
    if((
attacker_trace[attacker] & (1<<(victim-1))))
    {
        
attacker_trace[attacker] &= ~(1<<(victim-1));
        
SetHamParamFloat(30.0)
        return 
HAM_SUPERCEDE;
    }
    return 
HAM_IGNORED;
}

public 
fw_TraceAttack_infotarget(victimattackerFloat:damageFloat:direction[3], traceresultdamagebits)
{
    if(!
is_user_connected(attacker) || !(damagebits DMG_BULLET)) return FMRES_IGNORED;
    
    new 
Float:start_origin[3], Float:scanhit_end[3], Float:end_origin[3], tr3iHit 1Float:vDir[3], oldsolid pev(victimpev_solid);
    
get_tr2(traceresultTR_vecEndPosscanhit_end)
    
xs_vec_add(start_originscanhit_endstart_origin)
    
end_origin scanhit_end;
    
    
set_pev(victimpev_solidSOLID_NOT// ignoring the entity...
    
    
tr3 create_tr2();
    
vDir direction;
    
xs_vec_mul_scalar(vDir999.0vDir)
    
xs_vec_add(scanhit_endvDirscanhit_end)
    
    new 
oldents[33], oldsolids[33], iHitssizehits sizeof oldents;
    
    while( 
iHit )
    {
        
engfunc(EngFunc_TraceLinestart_originscanhit_end, (DONT_IGNORE_MONSTERS), attackertr3)
        
iHit get_tr2(tr3TR_pHit);
        
        if( 
iHit 0)
        {
            if( !(
sizehits iHits) ) break;
            
oldents[iHits] = iHit;
            
oldsolids[iHits] = pev(iHitpev_solid);
            
iHits ++;
            
set_pev(iHitpev_solidSOLID_NOT)
            if(
is_user_alive(iHit)) attacker_trace[attacker] |= (1<<(iHit-1));
        }
        
        
get_tr2(tr3TR_vecEndPosstart_origin)
    }
    
    
free_tr2(tr3)
    
    
// set back old solids....
    
set_pev(victimpev_solidoldsolid)
    
    for(new 
iiHitsi++)
    {
        
set_pev(oldents[i], pev_solidoldsolids[i])
    }
    
    
message_begin(MSG_BROADCASTSVC_TEMPENTITY)
    
write_byte(TE_GUNSHOT)
    
engfunc(EngFunc_WriteCoordend_origin[0])
    
engfunc(EngFunc_WriteCoordend_origin[1])
    
engfunc(EngFunc_WriteCoordend_origin[2])
    
message_end()
    
    
message_begin(MSG_BROADCASTSVC_TEMPENTITY)
    
write_byte(TE_SPARKS)
    
engfunc(EngFunc_WriteCoordend_origin[0])
    
engfunc(EngFunc_WriteCoordend_origin[1])
    
engfunc(EngFunc_WriteCoordend_origin[2])
    
message_end()
    
    return 
HAM_IGNORED;


also you can change the start position to the hit position of the traceline and then use the ignore ent thingy.

ConorCC 01-11-2021 15:37

Re: Multiple TraceHull
 
Super Cool! Thank you a lot. :)

Here is my code based on yours:
PHP Code:

new const FloatMulti[] = {

    
1.0,      // HIT_GENERIC
    
4.0,      // HIT_HEAD
    
1.0,      // HIT_CHEST
    
1.25,     // HIT_STOMACH
    
1.0,      // HIT_LEFTARM
    
1.0,      // HIT_RIGHTARM
    
0.75,     // HIT_LEFTLEG
    
0.75,      // HIT_RIGHTLEG
    
0.0      // HIT_SHIELD
}

public 
CreateMultipleTraceAttack_Hull(Floatorigin[3], Floatend_origin[3], Floatv_angle[3], Floatdamageidweapon) {

    static 
tracetrace create_tr2();

    
engfunc(EngFunc_TraceLineoriginend_originDONT_IGNORE_MONSTERSidtrace);

    static 
Floatfractionget_tr2(traceTR_flFractionfraction);
    static 
victim_idvictim_id get_tr2(traceTR_pHit);
    static 
boolis_hit_playeris_hit_player false;
    static 
boolis_hit_wallis_hit_wall false;

    static Array: 
entitiesentities ArrayCreate(2);
    static 
entity_data[2];

    if ( 
pev_valid(victim_id) ) {

        static 
tmp_damagetmp_damage *= Multi[get_tr2(traceTR_iHitgroup)];

        
rg_multidmg_clear();

        
ExecuteHamB(Ham_TraceAttackvictim_ididdamagev_angletraceDMG_NEVERGIB|DMG_BULLET);

        
rg_multidmg_apply(weaponid);

        
entity_data[0] = victim_id;
        
entity_data[1] = get_entvar(victim_idvar_solid);

        
set_entvar(victim_idvar_solidSOLID_NOT);

        if ( 
is_user_connected(victim_id) )
            
is_hit_player true;
        else
            
is_hit_wall true;

        
ArrayPushArray(entitiesentity_data);
    }
    else if ( 
fraction != 1.0 )
        
is_hit_wall true;

    static 
boolcompletedcompleted false;

    while ( !
completed ) {

        
engfunc(EngFunc_TraceHulloriginend_originDONT_IGNORE_MONSTERSHULL_HUMANidtrace);

        
victim_id get_tr2(traceTR_pHit);
        
get_tr2(traceTR_flFractionfraction);

        if ( 
pev_valid(victim_id) ) {

            
rg_multidmg_clear();

            
ExecuteHamB(Ham_TraceAttackvictim_ididdamagev_angletraceDMG_NEVERGIB|DMG_BULLET);

            
rg_multidmg_apply(weaponid);

            
entity_data[0] = victim_id;
            
entity_data[1] = get_entvar(victim_idvar_solid);

            
ArrayPushArray(entitiesentity_data);

            
set_entvar(victim_idvar_solidSOLID_NOT);

            if ( 
is_user_connected(victim_id) )
                
is_hit_player true
        
}
        else
            
completed true;
    }

    for ( new 
iArraySize(entities); ++ ) {

        
ArrayGetArray(entitiesientity_data);
        
set_entvar(entity_data[0], var_solidentity_data[1]);
    }

    
ArrayDestroy(entities);

    static 
resultresult is_hit_player : ((!is_hit_player && is_hit_wall) ? -0);

    
free_tr2(trace);

    return 
result;



baneado 03-19-2022 19:50

Re: Multiple TraceHull
 
For documentation

This can be done hooking RG_CBaseEntity_FireBullets3 with ReAPI and modifying iPenetration parameter.

Or if it isn't a weapon (a turret for example), just use rg_fire_bullets3/rg_fire_bullets native on ReAPI too.


All times are GMT -4. The time now is 13:30.

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