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

Cluster Grenade that doesn't go behind walls


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Ark_Procession
Senior Member
Join Date: Jun 2020
Location: Argentina
Old 06-06-2022 , 13:24   Cluster Grenade that doesn't go behind walls
Reply With Quote #1

As you know Condition Zero implemented the no damage through walls for Hegrenades

In this plugin damage still go through walls, how could i make it not to?

HTML Code:
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/

#include <amxmodx>
#include <amxmisc>
#include < engine >
#include <fakemeta>
#include <cstrike>
#include <fun>
#include <hamsandwich>

#define is_grenade_c4(%1)	(get_pdata_int(%1, 96) & (1<<8))	// 96 is the C4 offset

// CVAR pointers
new pClusterMinFly, pClusterMaxFly, pCluster_obeyffcvar, pClusterArk
new pClusterTotal, pClusterDamage, pClusterRadius, pClusterKnockback, pCluster_botallow

// Global variables
new mod_name[1]
new bool:g_is_cstrike
new explosion1, explosion2
new g_ClusterMinFly, g_ClusterMaxFly, g_Clusterobeyffcvar,g_ClusterUpwardArk
new g_ClusterTotal, g_ClusterDamage, g_ClusterRadius, Float:g_Clusterknockback, g_Cluster_botallow

// Message ID's
new g_msgScoreInfo, g_msgDeathMsg

public plugin_precachce() {
	precache_sound( "sound/weapons/explode3.wav" )
	explosion1 = precache_model( "sprites/zerogxplode.spr" )
	explosion2 = precache_model( "sprites/explode1.spr" )
}

public plugin_init() {
	
	register_plugin( "Cluster Grenades", "3.1 Final", "doomy/Can'tShoot" )
	
	// Ham
	RegisterHam(Ham_Think, "grenade", "fw_think_post")

	// Events
	register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0")
	
	// CVARs
	pClusterTotal = register_cvar("cluster_total", "4") // TOTAL CLUSTERS
	pClusterDamage = register_cvar("cluster_damage", "20") // MAX_CLUSTER_DAMAGE
	pClusterRadius = register_cvar("cluster_radius", "280") //CLUSTER_DAMAGE_RADIUS
	pClusterMinFly = register_cvar("cluster_min_fly", "150") //MIN_FLY_DISTANCE
	pClusterMaxFly = register_cvar("cluster_max_fly", "300") //MAX_FLY_DISTANCE
	pClusterArk = register_cvar("cluster_upward_ark", "200") //UPWARD_ARC
	pCluster_botallow = register_cvar("cluster_botallow","1") //BOTS USE CLUSTERS 0/1
	pClusterKnockback = register_cvar("cluster_knockback", "20") //KNOCKBACK FROM BLAST
	pCluster_obeyffcvar = register_cvar("cluster_obeyffcvar","0") //OBEY FRIENDLY FIRE 0/1
	
	g_ClusterTotal = get_pcvar_num(pClusterTotal)
	g_ClusterDamage = get_pcvar_num(pClusterDamage)
	g_ClusterRadius = get_pcvar_num(pClusterRadius)
	g_ClusterMinFly = get_pcvar_num(pClusterMinFly)
	g_ClusterMaxFly = get_pcvar_num(pClusterMaxFly)
	g_ClusterUpwardArk = get_pcvar_num(pClusterArk)
	g_Cluster_botallow = get_pcvar_num(pCluster_botallow)
	g_Clusterknockback = get_pcvar_float(pClusterKnockback)
	g_Clusterobeyffcvar = get_pcvar_num(pCluster_obeyffcvar)
	
	get_modname(mod_name,31)
	g_is_cstrike = equal(mod_name,"cstrike") ? true : false

	g_msgScoreInfo = get_user_msgid("ScoreInfo")
	g_msgDeathMsg = get_user_msgid("DeathMsg")
	
	return PLUGIN_CONTINUE	
}

// New round started
public Event_NewRound() {
	
	g_ClusterTotal = get_pcvar_num(pClusterTotal)
	g_ClusterDamage = get_pcvar_num(pClusterDamage)
	g_ClusterRadius = get_pcvar_num(pClusterRadius)
	g_ClusterMinFly = get_pcvar_num(pClusterMinFly)
	g_ClusterMaxFly = get_pcvar_num(pClusterMaxFly)
	g_ClusterUpwardArk = get_pcvar_num(pClusterArk)
	g_Cluster_botallow = get_pcvar_num(pCluster_botallow)
	g_Clusterknockback = get_pcvar_float(pClusterKnockback)
	g_Clusterobeyffcvar = get_pcvar_num(pCluster_obeyffcvar)
}

public fw_think_post(ent) {
	
	// Leave if grenade entity is not valid or it's a C4
	if ( !is_valid_ent( ent ) || is_grenade_c4( ent ) ) return HAM_IGNORED
	
	static owner, Float:origin1[3], Float:gametime
	gametime = get_gametime()
	
	owner = entity_get_edict( ent, EV_ENT_owner )
	
	// If owner = 0, or it's a bot not allow or still in delay then leave
	if( owner == 0 	|| ( !g_Cluster_botallow && is_user_bot( owner ) ) ) return HAM_IGNORED
	
	if (entity_get_float(ent, EV_FL_dmgtime) > gametime)
		return HAM_IGNORED
	
	if ( !is_user_connected( owner ) || is_user_connecting( owner ) )
	{
		entity_set_int( ent, EV_INT_flags, entity_get_int( ent, EV_INT_flags ) | FL_KILLME )
		return HAM_IGNORED
	}
	
	// make sure it the he nade	
	new sModel[32];
	pev( ent, pev_model, sModel, 31 )
	if ( !equal( sModel[7], "w_he", 4 ) ) return HAM_IGNORED
	
	entity_get_vector( ent, EV_VEC_origin, origin1 )
	
	static pos[3]
	pos[0] = floatround( origin1[0] )
	pos[1] = floatround( origin1[1] )
	pos[2] = floatround( origin1[2] + random_num(45,80))
	
	static cluster, Float:vAngle[3], Float:angles[3], Float:velocity[3],
	Rvelocity[3], Float:distance, Float:actualDistance, Float:multiplier
	
	static Float:origin[3] 
	origin[0] = float( pos[0] )
	origin[1] = float( pos[1] )
	origin[2] = float( pos[2] )
	
	static Float:minBox[3] = { -1.0, ... }
	static Float:maxBox[3] = { 1.0, ... }
	
	//This will launch the above specified number of clusters max of 10
	if ( g_ClusterTotal > 10 ) g_ClusterTotal = 10
	for ( new i = 0; i < g_ClusterTotal; i++ ) {
		
		// create a random velocity
		velocity[0] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )
		velocity[1] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )
		//velocity[2] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )
		velocity[2] = float( g_ClusterUpwardArk )
		
		Rvelocity[0] = pos[0] + floatround( velocity[0] )
		Rvelocity[1] = pos[1] + floatround( velocity[1] )
		Rvelocity[2] = pos[2] + floatround( velocity[2] )
		
		//Create the distance the cluster will fly
		distance = random_float( float( g_ClusterMinFly ), float( g_ClusterMaxFly ) )
		actualDistance = float( get_distance( pos, Rvelocity ) )
		multiplier = floatdiv( distance, actualDistance )
		
		velocity[0] = floatmul( velocity[0], multiplier )
		velocity[1] = floatmul( velocity[1], multiplier )
		velocity[2] = floatmul( velocity[2], multiplier )
		
		//Create the angles for the facing of the cluster.
		//PS: I have no idea how to do the angle thing really. This is a blind attempt.
		vector_to_angle( velocity, angles ) // orientation of the entity
		vector_to_angle( velocity, vAngle ) // view angle
		
		//Create the entity of the cluster
		cluster = create_entity( "info_target" )
		
		//Set the identifying string of the cluster's entity
		entity_set_string( cluster, EV_SZ_classname, "grenade_cluster") 
		
		//Set the model for the cluster's entity
		entity_set_model( cluster, "models/grenade.mdl" ) 	
		
		//Set the bounds for the cluster's entity	
		entity_set_vector( cluster, EV_VEC_mins, minBox)
		entity_set_vector( cluster, EV_VEC_maxs, maxBox )
		
		//Set the origin for the cluster's entity (NOTE: The clusters will spawn in the same spot, but they will be set to ignore eachother
		entity_set_origin( cluster, origin )
		
		//Set the angles of the cluster's entity	
		entity_set_vector( cluster, EV_VEC_angles, angles )
		entity_set_vector( cluster, EV_VEC_v_angle, vAngle )
		
		//Set the behavior specific variables for the cluster's entity
		entity_set_int( cluster, EV_INT_movetype, MOVETYPE_TOSS ) // 6 Has gravity and registers collisions === MOVETYPE_TOSS
		entity_set_int( cluster, EV_INT_solid, SOLID_TRIGGER ) // 1 Collisions do not block === SOLID_TRIGGER
		
		//Record who the owner of this nade is
		entity_set_edict( cluster, EV_ENT_owner, owner )
		
		//Make the cluster fly!
		entity_set_vector( cluster, EV_VEC_velocity, velocity ) 
	}
	
	return HAM_IGNORED
}

public pfn_touch( ptr, ptd ) { 
	
	//Gets the indentifying strings of each entity
	new identify[15], compare[15], Float:origin[3]
	if ( ptr == 0 || !is_valid_ent( ptr ) ) identify = "world"
	else entity_get_string( ptr, EV_SZ_classname, identify, 15 )
	if ( ptd == 0 || !is_valid_ent( ptd ) ) compare = "world"
	else if ( is_valid_ent( ptd ) ) entity_get_string( ptd, EV_SZ_classname, compare, 15 )
		
	//Ensures that the grenade cluster argument is always the 'ptr'
	if ( ptr == 0 || equali( compare, "grenade_cluster" ) ) return PLUGIN_HANDLED
	
	//Checks to see if it is a grenade cluster hitting another object. If it is it explodes and deals damage
	if ( equali( identify, "grenade_cluster" ) ) {
		entity_get_vector( ptr, EV_VEC_origin, origin )
		
		//Deals radius damage to the spot of collision
		new player[32], players, location[3], origin2[3], distance, Float:multiplier, owner
		origin2[0] = floatround( origin[0] )
		origin2[1] = floatround( origin[1] )
		origin2[2] = floatround( origin[2] )
		
		owner = entity_get_edict( ptr, EV_ENT_owner )
		
		get_players( player, players, "a" )
		for ( new i = 0; i < players; i++ ) {
			
			// Zombie/Nemesis and don't have godmode
			if ( cs_get_user_team(owner) !=  cs_get_user_team(player[i]) 
				&& get_user_godmode(player[i]) == 0 
				|| g_Clusterobeyffcvar == 0 ) {

				get_user_origin( player[i], location )
				distance = get_distance( origin2, location )
				if ( distance < g_ClusterRadius ) {
					
					new health = get_user_health( player[i] ), damage
					multiplier = floatdiv( float( g_ClusterRadius - distance ), float( g_ClusterRadius ) )
					damage = floatround( floatmul( multiplier, float( g_ClusterDamage ) ) )
					
					// Make some Fake damage & knockback
					fakedamage(player[i], "grenade", 0.0, DMG_BLAST)
					make_knockback( player[i], origin, g_Clusterknockback * damage )	

					if ( health - floatmul( multiplier, float( g_ClusterDamage ) ) >= 1 ) {
						set_user_health( player[i], get_user_health( player[i] ) - damage )
						
						//client_print( 0, print_chat, "===>DAMADE %d<===", damage )
					}
					else {
						Create_Kill(player[i],  owner, "grenade")							
					}
				}
			}
		}
		
		//Paints the explosion
		message_begin( MSG_BROADCAST, SVC_TEMPENTITY ) 
		write_byte( TE_EXPLOSION ) 
		write_coord( floatround( origin[0] ) ) 
		write_coord( floatround( origin[1] ) ) 
		write_coord( floatround( origin[2] ) ) 
		write_short( explosion1 ) 
		write_byte( 50 ) 
		write_byte( 15 ) 
		write_byte( 0 )
		message_end() 
		
		message_begin( MSG_BROADCAST, SVC_TEMPENTITY ) 
		write_byte( TE_EXPLOSION ) 
		write_coord( floatround( origin[0] ) ) 
		write_coord( floatround( origin[1] ) ) 
		write_coord( floatround( origin[2] ) ) 
		write_short( explosion2 ) 
		write_byte( 50 ) 
		write_byte( 15 ) 
		write_byte( 0 )
		message_end() 
		
		//If the grenade hit the ground or a wall then this draws a land scar
		if ( ptd == 0 ) {
			message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
			write_byte( TE_WORLDDECAL )
			write_coord( floatround( origin[0] ) ) 
			write_coord( floatround( origin[1] ) ) 
			write_coord( floatround( origin[2] ) )
			
			/* --| Random the burn decal For CS/CZ */ 
			if (g_is_cstrike) write_byte(random_num(46,48))  // decal
			if (!g_is_cstrike) write_byte(random_num(58,60)) // decal
	
			message_end()
		}
		
		remove_entity( ptr ) //Removes the grenade cluster so that it does not enter an infinite loop
		
		return PLUGIN_HANDLED
	}
	
	return PLUGIN_CONTINUE
}

/* MISCELLANEOUS FUNCTIONS */

stock make_knockback( victim, Float:origin[3], Float:maxspeed ) {
	
	// Get and set velocity
	new Float:fVelocity[3], Float:fEntOrigin[3]
	entity_get_vector( victim, EV_VEC_origin, fEntOrigin )
	
	// Do some calculations
	new Float:fDistance[3]
	fDistance[0] = fEntOrigin[0] - origin[0]
	fDistance[1] = fEntOrigin[1] - origin[1]
	fDistance[2] = fEntOrigin[2] - origin[2]
	
	new Float:fTime = ( vector_distance( fEntOrigin,origin ) / maxspeed )
	fVelocity[0] = fDistance[0] / fTime
	fVelocity[1] = fDistance[1] / fTime
	fVelocity[2] = fDistance[2] / fTime
	
	entity_set_vector( victim, EV_VEC_velocity, fVelocity )
	
}

Create_Kill(attacked, attacker, weaponDescription[]) 
{
	new FFon = get_cvar_num("mp_friendlyfire") 

	if(FFon && get_user_team(attacked) == get_user_team(attacker)) { 
	
		set_user_frags(attacker, get_user_frags(attacker) - 1) 
		client_print(attacker, print_center, "You killed a teammate") 
	
		new money = cs_get_user_money(attacker) 
		
		if(money != 0) cs_set_user_money(attacker, money - 150, 1) 
	} 
	else if( get_user_team(attacked) != get_user_team(attacker)) { 
	
		set_user_frags(attacker, get_user_frags(attacker) + 1) 
		new money = cs_get_user_money(attacker) 
	
		if(money < 16000) cs_set_user_money(attacker,money + 300,1) 
	} 

	logKill(attacker, attacked, weaponDescription) 

	//Kill the victim and block the messages 
	set_msg_block(g_msgDeathMsg,BLOCK_ONCE) 
	set_msg_block(g_msgScoreInfo,BLOCK_ONCE) 
	user_kill(attacked) 
	
	//user_kill removes a frag, this gives it back 
	set_user_frags(attacked,get_user_frags(attacked) + 1) 

	//Replaced HUD death message 
	message_begin(MSG_ALL,g_msgDeathMsg,{0,0,0},0) 
	write_byte(attacker) 
	write_byte(attacked) 
	write_byte(0) 
	write_string( weaponDescription )
	message_end() 
	
	//Update killers scorboard with new info 
	message_begin(MSG_ALL,g_msgScoreInfo) 
	write_byte(attacker) 
	write_short(get_user_frags(attacker)) 
	write_short(get_user_deaths(attacker)) 
	write_short(0) 
	write_short(get_user_team(attacker)) 
	message_end() 
	
	//Update victims scoreboard with correct info 
	message_begin(MSG_ALL,g_msgScoreInfo) 
	write_byte(attacked) 
	write_short(get_user_frags(attacked)) 
	write_short(get_user_deaths(attacked)) 
	write_short(0) 
	write_short(get_user_team(attacked)) 
	message_end()
}

public logKill(	attacker, victim, weaponDescription[] ) { 

	new namea[32],namev[32],authida[35],authidv[35],teama[16],teamv[16] 

	//Info On Attacker 
	get_user_name(attacker,namea,31) 
	get_user_team(attacker,teama,15) 
	get_user_authid(attacker,authida,34) 
	
	//Info On Victim 
	get_user_name(victim,namev,31) 
	get_user_team(victim,teamv,15) 
	get_user_authid(victim,authidv,34) 

	//Log This Kill 
	if( attacker != victim ) 
	{ 
		log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^"", 
		namea,get_user_userid(attacker),authida,teama,namev,get_user_userid(victim),authidv,teamv, weaponDescription ) 
	} 
	else 
	{ 
		log_message("^"%s<%d><%s><%s>^" committed suicide with ^"%s^"", 
		namea,get_user_userid(attacker),authida,teama, weaponDescription ) 
	} 
}
Ark_Procession is offline
Celena Luna
Veteran Member
Join Date: Aug 2013
Location: Nagazora
Old 06-06-2022 , 23:12   Re: Cluster Grenade that doesn't go behind walls
Reply With Quote #2

Try to update this part

PHP Code:
for ( new 0playersi++ ) {
            
    
// Zombie/Nemesis and don't have godmode
    
if ( cs_get_user_team(owner) !=  cs_get_user_team(player[i]) 
        && 
get_user_godmode(player[i]) == 
        
|| g_Clusterobeyffcvar == ) {

        
get_user_originplayer[i], location )
        
distance get_distanceorigin2location )
        if ( 
distance g_ClusterRadius && !is_wall_between_points(origin2locationtrue)) {
            
            new 
health get_user_healthplayer[i] ), damage
            multiplier 
floatdivfloatg_ClusterRadius distance ), floatg_ClusterRadius ) )
            
damage floatroundfloatmulmultiplierfloatg_ClusterDamage ) ) )
            
            
// Make some Fake damage & knockback
            
fakedamage(player[i], "grenade"0.0DMG_BLAST)
            
make_knockbackplayer[i], origing_Clusterknockback damage )    

            if ( 
health floatmulmultiplierfloatg_ClusterDamage ) ) >= ) {
                
set_user_healthplayer[i], get_user_healthplayer[i] ) - damage )
                
                
//client_print( 0, print_chat, "===>DAMADE %d<===", damage )
            
}
            else {
                
Create_Kill(player[i],  owner"grenade")                            
            }
        }
    }

PHP Code:
stock is_wall_between_points(Float:start[3], Float:end[3], ignore_ent)
{
    static 
ptr
    ptr 
create_tr2()

    
engfunc(EngFunc_TraceLinestartendIGNORE_MONSTERSignore_entptr)
    
    static 
Float:EndPos[3]
    
get_tr2(ptrTR_vecEndPosEndPos)

    
free_tr2(ptr)
    return 
floatround(get_distance_f(endEndPos))

__________________
My plugin:
Celena Luna is offline
Ark_Procession
Senior Member
Join Date: Jun 2020
Location: Argentina
Old 06-06-2022 , 23:35   Re: Cluster Grenade that doesn't go behind walls
Reply With Quote #3

Quote:
Originally Posted by Celena Luna View Post
Try to update this part

PHP Code:
for ( new 0playersi++ ) {
            
    
// Zombie/Nemesis and don't have godmode
    
if ( cs_get_user_team(owner) !=  cs_get_user_team(player[i]) 
        && 
get_user_godmode(player[i]) == 
        
|| g_Clusterobeyffcvar == ) {

        
get_user_originplayer[i], location )
        
distance get_distanceorigin2location )
        if ( 
distance g_ClusterRadius && !is_wall_between_points(origin2locationtrue)) {
            
            new 
health get_user_healthplayer[i] ), damage
            multiplier 
floatdivfloatg_ClusterRadius distance ), floatg_ClusterRadius ) )
            
damage floatroundfloatmulmultiplierfloatg_ClusterDamage ) ) )
            
            
// Make some Fake damage & knockback
            
fakedamage(player[i], "grenade"0.0DMG_BLAST)
            
make_knockbackplayer[i], origing_Clusterknockback damage )    

            if ( 
health floatmulmultiplierfloatg_ClusterDamage ) ) >= ) {
                
set_user_healthplayer[i], get_user_healthplayer[i] ) - damage )
                
                
//client_print( 0, print_chat, "===>DAMADE %d<===", damage )
            
}
            else {
                
Create_Kill(player[i],  owner"grenade")                            
            }
        }
    }

PHP Code:
stock is_wall_between_points(Float:start[3], Float:end[3], ignore_ent)
{
    static 
ptr
    ptr 
create_tr2()

    
engfunc(EngFunc_TraceLinestartendIGNORE_MONSTERSignore_entptr)
    
    static 
Float:EndPos[3]
    
get_tr2(ptrTR_vecEndPosEndPos)

    
free_tr2(ptr)
    return 
floatround(get_distance_f(endEndPos))

Hi , thanks for your time:

Error: invalid expression, asssumed zero on line 219
error: undefined symbol "is_wall_between_points" on line 219

Should i have replaced that exact amount of code for yours?

No coder here.. sorry
Ark_Procession is offline
Celena Luna
Veteran Member
Join Date: Aug 2013
Location: Nagazora
Old 06-06-2022 , 23:47   Re: Cluster Grenade that doesn't go behind walls
Reply With Quote #4

Quote:
Originally Posted by Ark_Procession View Post
Hi , thanks for your time:

Error: invalid expression, asssumed zero on line 219
error: undefined symbol "is_wall_between_points" on line 219

Should i have replaced that exact amount of code for yours?

No coder here.. sorry
If you is not a coder then you should post in the request section (Here)
Scripting Help is for coder who have trouble while coding so most reply is assumed that you know what to do.

anyway, here is the full code.
PHP Code:
#include <amxmodx>
#include <amxmisc>
#include < engine >
#include <fakemeta>
#include <cstrike>
#include <fun>
#include <hamsandwich>

#define is_grenade_c4(%1)    (get_pdata_int(%1, 96) & (1<<8))    // 96 is the C4 offset

// CVAR pointers
new pClusterMinFlypClusterMaxFlypCluster_obeyffcvarpClusterArk
new pClusterTotalpClusterDamagepClusterRadiuspClusterKnockbackpCluster_botallow

// Global variables
new mod_name[1]
new 
bool:g_is_cstrike
new explosion1explosion2
new g_ClusterMinFlyg_ClusterMaxFlyg_Clusterobeyffcvar,g_ClusterUpwardArk
new g_ClusterTotalg_ClusterDamageg_ClusterRadiusFloat:g_Clusterknockbackg_Cluster_botallow

// Message ID's
new g_msgScoreInfog_msgDeathMsg

public plugin_precachce() {
    
precache_sound"sound/weapons/explode3.wav" )
    
explosion1 precache_model"sprites/zerogxplode.spr" )
    
explosion2 precache_model"sprites/explode1.spr" )
}

public 
plugin_init() {
    
    
register_plugin"Cluster Grenades""3.1 Final""doomy/Can'tShoot" )
    
    
// Ham
    
RegisterHam(Ham_Think"grenade""fw_think_post")

    
// Events
    
register_event("HLTV""Event_NewRound""a""1=0""2=0")
    
    
// CVARs
    
pClusterTotal register_cvar("cluster_total""4"// TOTAL CLUSTERS
    
pClusterDamage register_cvar("cluster_damage""20"// MAX_CLUSTER_DAMAGE
    
pClusterRadius register_cvar("cluster_radius""280"//CLUSTER_DAMAGE_RADIUS
    
pClusterMinFly register_cvar("cluster_min_fly""150"//MIN_FLY_DISTANCE
    
pClusterMaxFly register_cvar("cluster_max_fly""300"//MAX_FLY_DISTANCE
    
pClusterArk register_cvar("cluster_upward_ark""200"//UPWARD_ARC
    
pCluster_botallow register_cvar("cluster_botallow","1"//BOTS USE CLUSTERS 0/1
    
pClusterKnockback register_cvar("cluster_knockback""20"//KNOCKBACK FROM BLAST
    
pCluster_obeyffcvar register_cvar("cluster_obeyffcvar","0"//OBEY FRIENDLY FIRE 0/1
    
    
g_ClusterTotal get_pcvar_num(pClusterTotal)
    
g_ClusterDamage get_pcvar_num(pClusterDamage)
    
g_ClusterRadius get_pcvar_num(pClusterRadius)
    
g_ClusterMinFly get_pcvar_num(pClusterMinFly)
    
g_ClusterMaxFly get_pcvar_num(pClusterMaxFly)
    
g_ClusterUpwardArk get_pcvar_num(pClusterArk)
    
g_Cluster_botallow get_pcvar_num(pCluster_botallow)
    
g_Clusterknockback get_pcvar_float(pClusterKnockback)
    
g_Clusterobeyffcvar get_pcvar_num(pCluster_obeyffcvar)
    
    
get_modname(mod_name,31)
    
g_is_cstrike equal(mod_name,"cstrike") ? true false

    g_msgScoreInfo 
get_user_msgid("ScoreInfo")
    
g_msgDeathMsg get_user_msgid("DeathMsg")
    
    return 
PLUGIN_CONTINUE    
}

// New round started
public Event_NewRound() {
    
    
g_ClusterTotal get_pcvar_num(pClusterTotal)
    
g_ClusterDamage get_pcvar_num(pClusterDamage)
    
g_ClusterRadius get_pcvar_num(pClusterRadius)
    
g_ClusterMinFly get_pcvar_num(pClusterMinFly)
    
g_ClusterMaxFly get_pcvar_num(pClusterMaxFly)
    
g_ClusterUpwardArk get_pcvar_num(pClusterArk)
    
g_Cluster_botallow get_pcvar_num(pCluster_botallow)
    
g_Clusterknockback get_pcvar_float(pClusterKnockback)
    
g_Clusterobeyffcvar get_pcvar_num(pCluster_obeyffcvar)
}

public 
fw_think_post(ent) {
    
    
// Leave if grenade entity is not valid or it's a C4
    
if ( !is_valid_entent ) || is_grenade_c4ent ) ) return HAM_IGNORED
    
    
static ownerFloat:origin1[3], Float:gametime
    gametime 
get_gametime()
    
    
owner entity_get_edictentEV_ENT_owner )
    
    
// If owner = 0, or it's a bot not allow or still in delay then leave
    
if( owner == 0     || ( !g_Cluster_botallow && is_user_botowner ) ) ) return HAM_IGNORED
    
    
if (entity_get_float(entEV_FL_dmgtime) > gametime)
        return 
HAM_IGNORED
    
    
if ( !is_user_connectedowner ) || is_user_connectingowner ) )
    {
        
entity_set_intentEV_INT_flagsentity_get_intentEV_INT_flags ) | FL_KILLME )
        return 
HAM_IGNORED
    
}
    
    
// make sure it the he nade    
    
new sModel[32];
    
peventpev_modelsModel31 )
    if ( !
equalsModel[7], "w_he") ) return HAM_IGNORED
    
    entity_get_vector
entEV_VEC_originorigin1 )
    
    static 
pos[3]
    
pos[0] = floatroundorigin1[0] )
    
pos[1] = floatroundorigin1[1] )
    
pos[2] = floatroundorigin1[2] + random_num(45,80))
    
    static 
clusterFloat:vAngle[3], Float:angles[3], Float:velocity[3],
    
Rvelocity[3], Float:distanceFloat:actualDistanceFloat:multiplier
    
    
static Float:origin[3
    
origin[0] = floatpos[0] )
    
origin[1] = floatpos[1] )
    
origin[2] = floatpos[2] )
    
    static 
Float:minBox[3] = { -1.0, ... }
    static 
Float:maxBox[3] = { 1.0, ... }
    
    
//This will launch the above specified number of clusters max of 10
    
if ( g_ClusterTotal 10 g_ClusterTotal 10
    
for ( new 0g_ClusterTotali++ ) {
        
        
// create a random velocity
        
velocity[0] = random_float100.0500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )
        
velocity[1] = random_float100.0500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )
        
//velocity[2] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )
        
velocity[2] = floatg_ClusterUpwardArk )
        
        
Rvelocity[0] = pos[0] + floatroundvelocity[0] )
        
Rvelocity[1] = pos[1] + floatroundvelocity[1] )
        
Rvelocity[2] = pos[2] + floatroundvelocity[2] )
        
        
//Create the distance the cluster will fly
        
distance random_floatfloatg_ClusterMinFly ), floatg_ClusterMaxFly ) )
        
actualDistance floatget_distanceposRvelocity ) )
        
multiplier floatdivdistanceactualDistance )
        
        
velocity[0] = floatmulvelocity[0], multiplier )
        
velocity[1] = floatmulvelocity[1], multiplier )
        
velocity[2] = floatmulvelocity[2], multiplier )
        
        
//Create the angles for the facing of the cluster.
        //PS: I have no idea how to do the angle thing really. This is a blind attempt.
        
vector_to_anglevelocityangles // orientation of the entity
        
vector_to_anglevelocityvAngle // view angle
        
        //Create the entity of the cluster
        
cluster create_entity"info_target" )
        
        
//Set the identifying string of the cluster's entity
        
entity_set_stringclusterEV_SZ_classname"grenade_cluster"
        
        
//Set the model for the cluster's entity
        
entity_set_modelcluster"models/grenade.mdl" )     
        
        
//Set the bounds for the cluster's entity    
        
entity_set_vectorclusterEV_VEC_minsminBox)
        
entity_set_vectorclusterEV_VEC_maxsmaxBox )
        
        
//Set the origin for the cluster's entity (NOTE: The clusters will spawn in the same spot, but they will be set to ignore eachother
        
entity_set_originclusterorigin )
        
        
//Set the angles of the cluster's entity    
        
entity_set_vectorclusterEV_VEC_anglesangles )
        
entity_set_vectorclusterEV_VEC_v_anglevAngle )
        
        
//Set the behavior specific variables for the cluster's entity
        
entity_set_intclusterEV_INT_movetypeMOVETYPE_TOSS // 6 Has gravity and registers collisions === MOVETYPE_TOSS
        
entity_set_intclusterEV_INT_solidSOLID_TRIGGER // 1 Collisions do not block === SOLID_TRIGGER
        
        //Record who the owner of this nade is
        
entity_set_edictclusterEV_ENT_ownerowner )
        
        
//Make the cluster fly!
        
entity_set_vectorclusterEV_VEC_velocityvelocity 
    }
    
    return 
HAM_IGNORED
}

public 
pfn_touchptrptd ) { 
    
    
//Gets the indentifying strings of each entity
    
new identify[15], compare[15], Float:origin[3]
    if ( 
ptr == || !is_valid_entptr ) ) identify "world"
    
else entity_get_stringptrEV_SZ_classnameidentify15 )
    if ( 
ptd == || !is_valid_entptd ) ) compare "world"
    
else if ( is_valid_entptd ) ) entity_get_stringptdEV_SZ_classnamecompare15 )
        
    
//Ensures that the grenade cluster argument is always the 'ptr'
    
if ( ptr == || equalicompare"grenade_cluster" ) ) return PLUGIN_HANDLED
    
    
//Checks to see if it is a grenade cluster hitting another object. If it is it explodes and deals damage
    
if ( equaliidentify"grenade_cluster" ) ) {
        
entity_get_vectorptrEV_VEC_originorigin )
        
        
//Deals radius damage to the spot of collision
        
new player[32], playerslocation[3], origin2[3], distanceFloat:multiplierownerFloat:origin3[3]
        
origin2[0] = floatroundorigin[0] )
        
origin2[1] = floatroundorigin[1] )
        
origin2[2] = floatroundorigin[2] )
        
        
owner entity_get_edictptrEV_ENT_owner )
        
        
get_playersplayerplayers"a" )
        for ( new 
0playersi++ ) {
            
            
// Zombie/Nemesis and don't have godmode
            
if ( cs_get_user_team(owner) !=  cs_get_user_team(player[i]) 
                && 
get_user_godmode(player[i]) == 
                
|| g_Clusterobeyffcvar == ) {

                
get_user_originplayer[i], location )
                
entity_get_vectorplayer[i], EV_VEC_originorigin3 )
                
distance get_distanceorigin2location )
                if ( 
distance g_ClusterRadius && !is_wall_between_points(originorigin31)) {
                    
                    new 
health get_user_healthplayer[i] ), damage
                    multiplier 
floatdivfloatg_ClusterRadius distance ), floatg_ClusterRadius ) )
                    
damage floatroundfloatmulmultiplierfloatg_ClusterDamage ) ) )
                    
                    
// Make some Fake damage & knockback
                    
fakedamage(player[i], "grenade"0.0DMG_BLAST)
                    
make_knockbackplayer[i], origing_Clusterknockback damage )    

                    if ( 
health floatmulmultiplierfloatg_ClusterDamage ) ) >= ) {
                        
set_user_healthplayer[i], get_user_healthplayer[i] ) - damage )
                        
                        
//client_print( 0, print_chat, "===>DAMADE %d<===", damage )
                    
}
                    else {
                        
Create_Kill(player[i],  owner"grenade")                            
                    }
                }
            }
        } 
        
        
//Paints the explosion
        
message_beginMSG_BROADCASTSVC_TEMPENTITY 
        
write_byteTE_EXPLOSION 
        
write_coordfloatroundorigin[0] ) ) 
        
write_coordfloatroundorigin[1] ) ) 
        
write_coordfloatroundorigin[2] ) ) 
        
write_shortexplosion1 
        
write_byte50 
        
write_byte15 
        
write_byte)
        
message_end() 
        
        
message_beginMSG_BROADCASTSVC_TEMPENTITY 
        
write_byteTE_EXPLOSION 
        
write_coordfloatroundorigin[0] ) ) 
        
write_coordfloatroundorigin[1] ) ) 
        
write_coordfloatroundorigin[2] ) ) 
        
write_shortexplosion2 
        
write_byte50 
        
write_byte15 
        
write_byte)
        
message_end() 
        
        
//If the grenade hit the ground or a wall then this draws a land scar
        
if ( ptd == ) {
            
message_beginMSG_BROADCASTSVC_TEMPENTITY )
            
write_byteTE_WORLDDECAL )
            
write_coordfloatroundorigin[0] ) ) 
            
write_coordfloatroundorigin[1] ) ) 
            
write_coordfloatroundorigin[2] ) )
            
            
/* --| Random the burn decal For CS/CZ */ 
            
if (g_is_cstrikewrite_byte(random_num(46,48))  // decal
            
if (!g_is_cstrikewrite_byte(random_num(58,60)) // decal
    
            
message_end()
        }
        
        
remove_entityptr //Removes the grenade cluster so that it does not enter an infinite loop
        
        
return PLUGIN_HANDLED
    
}
    
    return 
PLUGIN_CONTINUE
}

/* MISCELLANEOUS FUNCTIONS */

stock make_knockbackvictimFloat:origin[3], Float:maxspeed ) {
    
    
// Get and set velocity
    
new Float:fVelocity[3], Float:fEntOrigin[3]
    
entity_get_vectorvictimEV_VEC_originfEntOrigin )
    
    
// Do some calculations
    
new Float:fDistance[3]
    
fDistance[0] = fEntOrigin[0] - origin[0]
    
fDistance[1] = fEntOrigin[1] - origin[1]
    
fDistance[2] = fEntOrigin[2] - origin[2]
    
    new 
Float:fTime = ( vector_distancefEntOrigin,origin ) / maxspeed )
    
fVelocity[0] = fDistance[0] / fTime
    fVelocity
[1] = fDistance[1] / fTime
    fVelocity
[2] = fDistance[2] / fTime
    
    entity_set_vector
victimEV_VEC_velocityfVelocity )
    
}

Create_Kill(attackedattackerweaponDescription[]) 
{
    new 
FFon get_cvar_num("mp_friendlyfire"

    if(
FFon && get_user_team(attacked) == get_user_team(attacker)) { 
    
        
set_user_frags(attackerget_user_frags(attacker) - 1
        
client_print(attackerprint_center"You killed a teammate"
    
        new 
money cs_get_user_money(attacker
        
        if(
money != 0cs_set_user_money(attackermoney 1501
    } 
    else if( 
get_user_team(attacked) != get_user_team(attacker)) { 
    
        
set_user_frags(attackerget_user_frags(attacker) + 1
        new 
money cs_get_user_money(attacker
    
        if(
money 16000cs_set_user_money(attacker,money 300,1
    } 

    
logKill(attackerattackedweaponDescription

    
//Kill the victim and block the messages 
    
set_msg_block(g_msgDeathMsg,BLOCK_ONCE
    
set_msg_block(g_msgScoreInfo,BLOCK_ONCE
    
user_kill(attacked
    
    
//user_kill removes a frag, this gives it back 
    
set_user_frags(attacked,get_user_frags(attacked) + 1

    
//Replaced HUD death message 
    
message_begin(MSG_ALL,g_msgDeathMsg,{0,0,0},0
    
write_byte(attacker
    
write_byte(attacked
    
write_byte(0
    
write_stringweaponDescription )
    
message_end() 
    
    
//Update killers scorboard with new info 
    
message_begin(MSG_ALL,g_msgScoreInfo
    
write_byte(attacker
    
write_short(get_user_frags(attacker)) 
    
write_short(get_user_deaths(attacker)) 
    
write_short(0
    
write_short(get_user_team(attacker)) 
    
message_end() 
    
    
//Update victims scoreboard with correct info 
    
message_begin(MSG_ALL,g_msgScoreInfo
    
write_byte(attacked
    
write_short(get_user_frags(attacked)) 
    
write_short(get_user_deaths(attacked)) 
    
write_short(0
    
write_short(get_user_team(attacked)) 
    
message_end()
}

public 
logKill(    attackervictimweaponDescription[] ) { 

    new 
namea[32],namev[32],authida[35],authidv[35],teama[16],teamv[16

    
//Info On Attacker 
    
get_user_name(attacker,namea,31
    
get_user_team(attacker,teama,15
    
get_user_authid(attacker,authida,34
    
    
//Info On Victim 
    
get_user_name(victim,namev,31
    
get_user_team(victim,teamv,15
    
get_user_authid(victim,authidv,34

    
//Log This Kill 
    
if( attacker != victim 
    { 
        
log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^""
        
namea,get_user_userid(attacker),authida,teama,namev,get_user_userid(victim),authidv,teamvweaponDescription 
    } 
    else 
    { 
        
log_message("^"%s<%d><%s><%s>^" committed suicide with ^"%s^""
        
namea,get_user_userid(attacker),authida,teamaweaponDescription 
    } 
}



stock is_wall_between_points(Float:start[3], Float:end[3], ignore_ent)
{
    static 
ptr
    ptr 
create_tr2()

    
engfunc(EngFunc_TraceLinestartendIGNORE_MONSTERSignore_entptr)
    
    static 
Float:EndPos[3]
    
get_tr2(ptrTR_vecEndPosEndPos)

    
free_tr2(ptr)
    return 
floatround(get_distance_f(endEndPos))

Edit: Updated Code
__________________
My plugin:

Last edited by Celena Luna; 06-07-2022 at 00:25.
Celena Luna is offline
Ark_Procession
Senior Member
Join Date: Jun 2020
Location: Argentina
Old 06-06-2022 , 23:49   Re: Cluster Grenade that doesn't go behind walls
Reply With Quote #5

Quote:
Originally Posted by Celena Luna View Post
If you is not a coder then you should post in the request section (Here)
Scripting Help is for coder who have trouble while coding so most reply is assumed that you know what to do.

anyway, here is the full code.
PHP Code:
#include <amxmodx>
#include <amxmisc>
#include < engine >
#include <fakemeta>
#include <cstrike>
#include <fun>
#include <hamsandwich>

#define is_grenade_c4(%1)    (get_pdata_int(%1, 96) & (1<<8))    // 96 is the C4 offset

// CVAR pointers
new pClusterMinFlypClusterMaxFlypCluster_obeyffcvarpClusterArk
new pClusterTotalpClusterDamagepClusterRadiuspClusterKnockbackpCluster_botallow

// Global variables
new mod_name[1]
new 
bool:g_is_cstrike
new explosion1explosion2
new g_ClusterMinFlyg_ClusterMaxFlyg_Clusterobeyffcvar,g_ClusterUpwardArk
new g_ClusterTotalg_ClusterDamageg_ClusterRadiusFloat:g_Clusterknockbackg_Cluster_botallow

// Message ID's
new g_msgScoreInfog_msgDeathMsg

public plugin_precachce() {
    
precache_sound"sound/weapons/explode3.wav" )
    
explosion1 precache_model"sprites/zerogxplode.spr" )
    
explosion2 precache_model"sprites/explode1.spr" )
}

public 
plugin_init() {
    
    
register_plugin"Cluster Grenades""3.1 Final""doomy/Can'tShoot" )
    
    
// Ham
    
RegisterHam(Ham_Think"grenade""fw_think_post")

    
// Events
    
register_event("HLTV""Event_NewRound""a""1=0""2=0")
    
    
// CVARs
    
pClusterTotal register_cvar("cluster_total""4"// TOTAL CLUSTERS
    
pClusterDamage register_cvar("cluster_damage""20"// MAX_CLUSTER_DAMAGE
    
pClusterRadius register_cvar("cluster_radius""280"//CLUSTER_DAMAGE_RADIUS
    
pClusterMinFly register_cvar("cluster_min_fly""150"//MIN_FLY_DISTANCE
    
pClusterMaxFly register_cvar("cluster_max_fly""300"//MAX_FLY_DISTANCE
    
pClusterArk register_cvar("cluster_upward_ark""200"//UPWARD_ARC
    
pCluster_botallow register_cvar("cluster_botallow","1"//BOTS USE CLUSTERS 0/1
    
pClusterKnockback register_cvar("cluster_knockback""20"//KNOCKBACK FROM BLAST
    
pCluster_obeyffcvar register_cvar("cluster_obeyffcvar","0"//OBEY FRIENDLY FIRE 0/1
    
    
g_ClusterTotal get_pcvar_num(pClusterTotal)
    
g_ClusterDamage get_pcvar_num(pClusterDamage)
    
g_ClusterRadius get_pcvar_num(pClusterRadius)
    
g_ClusterMinFly get_pcvar_num(pClusterMinFly)
    
g_ClusterMaxFly get_pcvar_num(pClusterMaxFly)
    
g_ClusterUpwardArk get_pcvar_num(pClusterArk)
    
g_Cluster_botallow get_pcvar_num(pCluster_botallow)
    
g_Clusterknockback get_pcvar_float(pClusterKnockback)
    
g_Clusterobeyffcvar get_pcvar_num(pCluster_obeyffcvar)
    
    
get_modname(mod_name,31)
    
g_is_cstrike equal(mod_name,"cstrike") ? true false

    g_msgScoreInfo 
get_user_msgid("ScoreInfo")
    
g_msgDeathMsg get_user_msgid("DeathMsg")
    
    return 
PLUGIN_CONTINUE    
}

// New round started
public Event_NewRound() {
    
    
g_ClusterTotal get_pcvar_num(pClusterTotal)
    
g_ClusterDamage get_pcvar_num(pClusterDamage)
    
g_ClusterRadius get_pcvar_num(pClusterRadius)
    
g_ClusterMinFly get_pcvar_num(pClusterMinFly)
    
g_ClusterMaxFly get_pcvar_num(pClusterMaxFly)
    
g_ClusterUpwardArk get_pcvar_num(pClusterArk)
    
g_Cluster_botallow get_pcvar_num(pCluster_botallow)
    
g_Clusterknockback get_pcvar_float(pClusterKnockback)
    
g_Clusterobeyffcvar get_pcvar_num(pCluster_obeyffcvar)
}

public 
fw_think_post(ent) {
    
    
// Leave if grenade entity is not valid or it's a C4
    
if ( !is_valid_entent ) || is_grenade_c4ent ) ) return HAM_IGNORED
    
    
static ownerFloat:origin1[3], Float:gametime
    gametime 
get_gametime()
    
    
owner entity_get_edictentEV_ENT_owner )
    
    
// If owner = 0, or it's a bot not allow or still in delay then leave
    
if( owner == 0     || ( !g_Cluster_botallow && is_user_botowner ) ) ) return HAM_IGNORED
    
    
if (entity_get_float(entEV_FL_dmgtime) > gametime)
        return 
HAM_IGNORED
    
    
if ( !is_user_connectedowner ) || is_user_connectingowner ) )
    {
        
entity_set_intentEV_INT_flagsentity_get_intentEV_INT_flags ) | FL_KILLME )
        return 
HAM_IGNORED
    
}
    
    
// make sure it the he nade    
    
new sModel[32];
    
peventpev_modelsModel31 )
    if ( !
equalsModel[7], "w_he") ) return HAM_IGNORED
    
    entity_get_vector
entEV_VEC_originorigin1 )
    
    static 
pos[3]
    
pos[0] = floatroundorigin1[0] )
    
pos[1] = floatroundorigin1[1] )
    
pos[2] = floatroundorigin1[2] + random_num(45,80))
    
    static 
clusterFloat:vAngle[3], Float:angles[3], Float:velocity[3],
    
Rvelocity[3], Float:distanceFloat:actualDistanceFloat:multiplier
    
    
static Float:origin[3
    
origin[0] = floatpos[0] )
    
origin[1] = floatpos[1] )
    
origin[2] = floatpos[2] )
    
    static 
Float:minBox[3] = { -1.0, ... }
    static 
Float:maxBox[3] = { 1.0, ... }
    
    
//This will launch the above specified number of clusters max of 10
    
if ( g_ClusterTotal 10 g_ClusterTotal 10
    
for ( new 0g_ClusterTotali++ ) {
        
        
// create a random velocity
        
velocity[0] = random_float100.0500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )
        
velocity[1] = random_float100.0500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )
        
//velocity[2] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )
        
velocity[2] = floatg_ClusterUpwardArk )
        
        
Rvelocity[0] = pos[0] + floatroundvelocity[0] )
        
Rvelocity[1] = pos[1] + floatroundvelocity[1] )
        
Rvelocity[2] = pos[2] + floatroundvelocity[2] )
        
        
//Create the distance the cluster will fly
        
distance random_floatfloatg_ClusterMinFly ), floatg_ClusterMaxFly ) )
        
actualDistance floatget_distanceposRvelocity ) )
        
multiplier floatdivdistanceactualDistance )
        
        
velocity[0] = floatmulvelocity[0], multiplier )
        
velocity[1] = floatmulvelocity[1], multiplier )
        
velocity[2] = floatmulvelocity[2], multiplier )
        
        
//Create the angles for the facing of the cluster.
        //PS: I have no idea how to do the angle thing really. This is a blind attempt.
        
vector_to_anglevelocityangles // orientation of the entity
        
vector_to_anglevelocityvAngle // view angle
        
        //Create the entity of the cluster
        
cluster create_entity"info_target" )
        
        
//Set the identifying string of the cluster's entity
        
entity_set_stringclusterEV_SZ_classname"grenade_cluster"
        
        
//Set the model for the cluster's entity
        
entity_set_modelcluster"models/grenade.mdl" )     
        
        
//Set the bounds for the cluster's entity    
        
entity_set_vectorclusterEV_VEC_minsminBox)
        
entity_set_vectorclusterEV_VEC_maxsmaxBox )
        
        
//Set the origin for the cluster's entity (NOTE: The clusters will spawn in the same spot, but they will be set to ignore eachother
        
entity_set_originclusterorigin )
        
        
//Set the angles of the cluster's entity    
        
entity_set_vectorclusterEV_VEC_anglesangles )
        
entity_set_vectorclusterEV_VEC_v_anglevAngle )
        
        
//Set the behavior specific variables for the cluster's entity
        
entity_set_intclusterEV_INT_movetypeMOVETYPE_TOSS // 6 Has gravity and registers collisions === MOVETYPE_TOSS
        
entity_set_intclusterEV_INT_solidSOLID_TRIGGER // 1 Collisions do not block === SOLID_TRIGGER
        
        //Record who the owner of this nade is
        
entity_set_edictclusterEV_ENT_ownerowner )
        
        
//Make the cluster fly!
        
entity_set_vectorclusterEV_VEC_velocityvelocity 
    }
    
    return 
HAM_IGNORED
}

public 
pfn_touchptrptd ) { 
    
    
//Gets the indentifying strings of each entity
    
new identify[15], compare[15], Float:origin[3]
    if ( 
ptr == || !is_valid_entptr ) ) identify "world"
    
else entity_get_stringptrEV_SZ_classnameidentify15 )
    if ( 
ptd == || !is_valid_entptd ) ) compare "world"
    
else if ( is_valid_entptd ) ) entity_get_stringptdEV_SZ_classnamecompare15 )
        
    
//Ensures that the grenade cluster argument is always the 'ptr'
    
if ( ptr == || equalicompare"grenade_cluster" ) ) return PLUGIN_HANDLED
    
    
//Checks to see if it is a grenade cluster hitting another object. If it is it explodes and deals damage
    
if ( equaliidentify"grenade_cluster" ) ) {
        
entity_get_vectorptrEV_VEC_originorigin )
        
        
//Deals radius damage to the spot of collision
        
new player[32], playerslocation[3], origin2[3], distanceFloat:multiplierowner
        origin2
[0] = floatroundorigin[0] )
        
origin2[1] = floatroundorigin[1] )
        
origin2[2] = floatroundorigin[2] )
        
        
owner entity_get_edictptrEV_ENT_owner )
        
        
get_playersplayerplayers"a" )
        for ( new 
0playersi++ ) {
            
            
// Zombie/Nemesis and don't have godmode
            
if ( cs_get_user_team(owner) !=  cs_get_user_team(player[i]) 
                && 
get_user_godmode(player[i]) == 
                
|| g_Clusterobeyffcvar == ) {

                
get_user_originplayer[i], location )
                
distance get_distanceorigin2location )
                if ( 
distance g_ClusterRadius ) {
                    
                    new 
health get_user_healthplayer[i] ), damage
                    multiplier 
floatdivfloatg_ClusterRadius distance ), floatg_ClusterRadius ) )
                    
damage floatroundfloatmulmultiplierfloatg_ClusterDamage ) ) )
                    
                    
// Make some Fake damage & knockback
                    
fakedamage(player[i], "grenade"0.0DMG_BLAST)
                    
make_knockbackplayer[i], origing_Clusterknockback damage )    

                    if ( 
health floatmulmultiplierfloatg_ClusterDamage ) ) >= ) {
                        
set_user_healthplayer[i], get_user_healthplayer[i] ) - damage )
                        
                        
//client_print( 0, print_chat, "===>DAMADE %d<===", damage )
                    
}
                    else {
                        
Create_Kill(player[i],  owner"grenade")                            
                    }
                }
            }
        }
        
        
//Paints the explosion
        
message_beginMSG_BROADCASTSVC_TEMPENTITY 
        
write_byteTE_EXPLOSION 
        
write_coordfloatroundorigin[0] ) ) 
        
write_coordfloatroundorigin[1] ) ) 
        
write_coordfloatroundorigin[2] ) ) 
        
write_shortexplosion1 
        
write_byte50 
        
write_byte15 
        
write_byte)
        
message_end() 
        
        
message_beginMSG_BROADCASTSVC_TEMPENTITY 
        
write_byteTE_EXPLOSION 
        
write_coordfloatroundorigin[0] ) ) 
        
write_coordfloatroundorigin[1] ) ) 
        
write_coordfloatroundorigin[2] ) ) 
        
write_shortexplosion2 
        
write_byte50 
        
write_byte15 
        
write_byte)
        
message_end() 
        
        
//If the grenade hit the ground or a wall then this draws a land scar
        
if ( ptd == ) {
            
message_beginMSG_BROADCASTSVC_TEMPENTITY )
            
write_byteTE_WORLDDECAL )
            
write_coordfloatroundorigin[0] ) ) 
            
write_coordfloatroundorigin[1] ) ) 
            
write_coordfloatroundorigin[2] ) )
            
            
/* --| Random the burn decal For CS/CZ */ 
            
if (g_is_cstrikewrite_byte(random_num(46,48))  // decal
            
if (!g_is_cstrikewrite_byte(random_num(58,60)) // decal
    
            
message_end()
        }
        
        
remove_entityptr //Removes the grenade cluster so that it does not enter an infinite loop
        
        
return PLUGIN_HANDLED
    
}
    
    return 
PLUGIN_CONTINUE
}

/* MISCELLANEOUS FUNCTIONS */

stock make_knockbackvictimFloat:origin[3], Float:maxspeed ) {
    
    
// Get and set velocity
    
new Float:fVelocity[3], Float:fEntOrigin[3]
    
entity_get_vectorvictimEV_VEC_originfEntOrigin )
    
    
// Do some calculations
    
new Float:fDistance[3]
    
fDistance[0] = fEntOrigin[0] - origin[0]
    
fDistance[1] = fEntOrigin[1] - origin[1]
    
fDistance[2] = fEntOrigin[2] - origin[2]
    
    new 
Float:fTime = ( vector_distancefEntOrigin,origin ) / maxspeed )
    
fVelocity[0] = fDistance[0] / fTime
    fVelocity
[1] = fDistance[1] / fTime
    fVelocity
[2] = fDistance[2] / fTime
    
    entity_set_vector
victimEV_VEC_velocityfVelocity )
    
}

Create_Kill(attackedattackerweaponDescription[]) 
{
    new 
FFon get_cvar_num("mp_friendlyfire"

    if(
FFon && get_user_team(attacked) == get_user_team(attacker)) { 
    
        
set_user_frags(attackerget_user_frags(attacker) - 1
        
client_print(attackerprint_center"You killed a teammate"
    
        new 
money cs_get_user_money(attacker
        
        if(
money != 0cs_set_user_money(attackermoney 1501
    } 
    else if( 
get_user_team(attacked) != get_user_team(attacker)) { 
    
        
set_user_frags(attackerget_user_frags(attacker) + 1
        new 
money cs_get_user_money(attacker
    
        if(
money 16000cs_set_user_money(attacker,money 300,1
    } 

    
logKill(attackerattackedweaponDescription

    
//Kill the victim and block the messages 
    
set_msg_block(g_msgDeathMsg,BLOCK_ONCE
    
set_msg_block(g_msgScoreInfo,BLOCK_ONCE
    
user_kill(attacked
    
    
//user_kill removes a frag, this gives it back 
    
set_user_frags(attacked,get_user_frags(attacked) + 1

    
//Replaced HUD death message 
    
message_begin(MSG_ALL,g_msgDeathMsg,{0,0,0},0
    
write_byte(attacker
    
write_byte(attacked
    
write_byte(0
    
write_stringweaponDescription )
    
message_end() 
    
    
//Update killers scorboard with new info 
    
message_begin(MSG_ALL,g_msgScoreInfo
    
write_byte(attacker
    
write_short(get_user_frags(attacker)) 
    
write_short(get_user_deaths(attacker)) 
    
write_short(0
    
write_short(get_user_team(attacker)) 
    
message_end() 
    
    
//Update victims scoreboard with correct info 
    
message_begin(MSG_ALL,g_msgScoreInfo
    
write_byte(attacked
    
write_short(get_user_frags(attacked)) 
    
write_short(get_user_deaths(attacked)) 
    
write_short(0
    
write_short(get_user_team(attacked)) 
    
message_end()
}

public 
logKill(    attackervictimweaponDescription[] ) { 

    new 
namea[32],namev[32],authida[35],authidv[35],teama[16],teamv[16

    
//Info On Attacker 
    
get_user_name(attacker,namea,31
    
get_user_team(attacker,teama,15
    
get_user_authid(attacker,authida,34
    
    
//Info On Victim 
    
get_user_name(victim,namev,31
    
get_user_team(victim,teamv,15
    
get_user_authid(victim,authidv,34

    
//Log This Kill 
    
if( attacker != victim 
    { 
        
log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^""
        
namea,get_user_userid(attacker),authida,teama,namev,get_user_userid(victim),authidv,teamvweaponDescription 
    } 
    else 
    { 
        
log_message("^"%s<%d><%s><%s>^" committed suicide with ^"%s^""
        
namea,get_user_userid(attacker),authida,teamaweaponDescription 
    } 
}



stock is_wall_between_points(Float:start[3], Float:end[3], ignore_ent)
{
    static 
ptr
    ptr 
create_tr2()

    
engfunc(EngFunc_TraceLinestartendIGNORE_MONSTERSignore_entptr)
    
    static 
Float:EndPos[3]
    
get_tr2(ptrTR_vecEndPosEndPos)

    
free_tr2(ptr)
    return 
floatround(get_distance_f(endEndPos))

I understand. Thanks for being kind.

will do.

edit: tested your code, not only they still go behind walls, but amazing color display fireworks happen.

thanks and i will stick to the suggestions/request site, where i know i post waaay to many requests.

Last edited by Ark_Procession; 06-06-2022 at 23:53. Reason: actual answer
Ark_Procession is offline
Celena Luna
Veteran Member
Join Date: Aug 2013
Location: Nagazora
Old 06-07-2022 , 00:26   Re: Cluster Grenade that doesn't go behind walls
Reply With Quote #6

Quote:
Originally Posted by Ark_Procession View Post
edit: tested your code, not only they still go behind walls, but amazing color display fireworks happen.
I forget to paste the part of the code I edited in
I updated the previous post
__________________
My plugin:
Celena Luna is offline
Ark_Procession
Senior Member
Join Date: Jun 2020
Location: Argentina
Old 06-07-2022 , 00:30   Re: Cluster Grenade that doesn't go behind walls
Reply With Quote #7

Quote:
Originally Posted by Celena Luna View Post
I forget to paste the part of the code I edited in
I updated the previous post
Lol i believe it works now

but what is it with the color aberration? did not happen before, is this the same code i gave to you? weird

it makes impossible to actually see anything happening. and i dont even know how to start fixing it.

Edit:

i dont even know how but i managed to give you a totally random code.

This is the intended code to be fixed:


HTML Code:
#include < amxmodx >
#include < amxmisc >
#include < engine >
#include < fun >

#define TE_EXPLOSION 3
#define TE_WORLDDECAL 116

#define CLUSTERS 5

#define MAX_CLUSTER_DAMAGE 20
#define CLUSTER_DAMAGE_RADIUS 300

#define MIN_FLY_DISTANCE 200
#define MAX_FLY_DISTANCE 400

#define UPWARD_ARC 200

#define SCORCH 47

new explosion1, explosion2, grenade[32], last
new bool:enabled = true
new bool:catchdeath = false

public death_msg() {
	if ( catchdeath ) {
		catchdeath = false
		return PLUGIN_HANDLED
	}

	return PLUGIN_CONTINUE
}

public grenade_throw() {

	if ( get_msg_args() < 2 ) return PLUGIN_HANDLED_MAIN

	if ( get_msg_arg_int( 1 ) == 12 && get_msg_arg_int( 2 ) == 0 )
		add_grenade_owner( last )

	return PLUGIN_CONTINUE
}

public fire_in_the_hole( id, dest, ent ) {
	if ( get_msg_args() != 5 ) return PLUGIN_CONTINUE

	new temp[17]
	get_msg_arg_string( 5, temp, 17 )

	if ( equali( temp, "#Fire_in_the_hole" ) ) {
		new name[32]
		entity_get_string( ent, EV_SZ_netname, name, 32 )

		last = find_player( "a", name )
	}

	return PLUGIN_CONTINUE
}

public pfn_touch( ptr, ptd ) { 

	//Gets the indentifying strings of each entity
	new identify[15], compare[15], Float:origin[3]
	if ( ptr == 0 ) identify = "world"
	else entity_get_string( ptr, EV_SZ_classname, identify, 15 )
	if ( ptd == 0 ) compare = "world"
	else if ( is_valid_ent( ptd ) ) entity_get_string( ptd, EV_SZ_classname, compare, 15 )

	//Ensures that the grenade cluster argument is always the 'ptr'
	if ( ptr == 0 || equali( compare, "grenade_cluster" ) ) return PLUGIN_HANDLED

	//Checks to see if it is a grenade cluster hitting another object. If it is it explodes and deals damage
	if ( equali( identify, "grenade_cluster" ) ) {
		entity_get_vector( ptr, EV_VEC_origin, origin )

		//Deals radius damage to the spot of collision
		new player[32], players, location[3], origin2[3], distance, Float:multiplier, owner
		origin2[0] = floatround( origin[0] )
		origin2[1] = floatround( origin[1] )
		origin2[2] = floatround( origin[2] )

		owner = entity_get_edict( ptr, EV_ENT_owner )

		get_players( player, players, "a" )
		for ( new i = 0; i < players; i++ ) {
			get_user_origin( player[i], location )
			distance = get_distance( origin2, location )
			if ( distance < CLUSTER_DAMAGE_RADIUS ) {
				multiplier = floatdiv( float( CLUSTER_DAMAGE_RADIUS - distance ), float( CLUSTER_DAMAGE_RADIUS ) )
				deal_grenade_damage( player[i], owner, floatmul( multiplier, float( MAX_CLUSTER_DAMAGE ) ) )
			}
		}

		//Paints the explosion
		message_begin( MSG_BROADCAST, SVC_TEMPENTITY ) 
		write_byte( TE_EXPLOSION ) 
		write_coord( floatround( origin[0] ) ) 
		write_coord( floatround( origin[1] ) ) 
		write_coord( floatround( origin[2] ) ) 
		write_short( explosion1 ) 
		write_byte( 50 ) 
		write_byte( 15 ) 
		write_byte( 0 )
		message_end() 

		message_begin( MSG_BROADCAST, SVC_TEMPENTITY ) 
		write_byte( TE_EXPLOSION ) 
		write_coord( floatround( origin[0] ) ) 
		write_coord( floatround( origin[1] ) ) 
		write_coord( floatround( origin[2] ) ) 
		write_short( explosion2 ) 
		write_byte( 50 ) 
		write_byte( 15 ) 
		write_byte( 0 )
		message_end() 

		//If the grenade hit the ground or a wall then this draws a land scar
		if ( ptd == 0 ) {
			message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
			write_byte( TE_WORLDDECAL )
			write_coord( floatround( origin[0] ) ) 
			write_coord( floatround( origin[1] ) ) 
			write_coord( floatround( origin[2] ) ) 
			write_byte( SCORCH )
			message_end()
		}

		remove_entity( ptr ) //Removes the grenade cluster so that it does not enter an infinite loop

		return PLUGIN_HANDLED
	}

	return PLUGIN_CONTINUE
}

public grenade_explosion() {
	if (get_msg_arg_int( 1 ) == 3 && get_msg_arg_int ( 6 ) == 25 && get_msg_arg_int ( 7 ) == 30 && enabled) {
		new pos[3]
		pos[0] = floatround( get_msg_arg_float( 2 ) )
		pos[1] = floatround( get_msg_arg_float( 3 ) )
		pos[2] = floatround( get_msg_arg_float( 4 ) )

		new cluster, Float:vAngle[3], Float:angles[3], Float:velocity[3], Rvelocity[3], Float:distance, Float:actualDistance, Float:multiplier

		new Float:origin[3] 
		origin[0] = float( pos[0] )
		origin[1] = float( pos[1] )
		origin[2] = float( pos[2] )

		new Float:minBox[3] = { -1.0, ... }
		new Float:maxBox[3] = { 1.0, ... }
		
		//This will launch the above specified number of clusters
		for (new i = 0; i < CLUSTERS; i++) {
			//Create a random direction for the cluster to fly
			velocity[0] = random_float( float( MIN_FLY_DISTANCE ), float( MAX_FLY_DISTANCE ) )
			if ( random_num( 0, 1 ) == 1 ) velocity[0] = floatmul( velocity[0], -1.0 )
			velocity[1] = random_float( float( MIN_FLY_DISTANCE ), float( MAX_FLY_DISTANCE ) )
			if ( random_num( 0, 1 ) == 1 ) velocity[1] = floatmul( velocity[1], -1.0 )
			velocity[2] = float( UPWARD_ARC )

			Rvelocity[0] = pos[0] + floatround( velocity[0] )
			Rvelocity[1] = pos[1] + floatround( velocity[1] )
			Rvelocity[2] = pos[2] + floatround( velocity[2] )

			//Create the distance the cluster will fly
			distance = random_float( float( MIN_FLY_DISTANCE ), float( MAX_FLY_DISTANCE ) )
			actualDistance = float( get_distance( pos, Rvelocity ) )
			multiplier = floatdiv( distance, actualDistance )
			

			velocity[0] = floatmul( velocity[0], multiplier )
			velocity[1] = floatmul( velocity[1], multiplier )
			velocity[2] = floatmul( velocity[2], multiplier )

			//Create the angles for the facing of the cluster. PS: I have no idea how to do the angle thing really. This is a blind attempt.
			vector_to_angle( velocity, angles )
			vector_to_angle( velocity, vAngle )

			//Create the entity of the cluster
			cluster = create_entity( "info_target" )

			//Set the identifying string of the cluster's entity
			entity_set_string( cluster, EV_SZ_classname, "grenade_cluster") 

			//Set the model for the cluster's entity
			entity_set_model( cluster, "models/grenade.mdl" ) 	

			//Set the bounds for the cluster's entity	
			entity_set_vector( cluster, EV_VEC_mins, minBox)
			entity_set_vector( cluster, EV_VEC_maxs, maxBox)

			//Set the origin for the cluster's entity (NOTE: The clusters will spawn in the same spot, but they will be set to ignore eachother
			entity_set_origin( cluster, origin )

			//Set the angles of the cluster's entity	
			entity_set_vector( cluster, EV_VEC_angles, angles )
			entity_set_vector( cluster, EV_VEC_v_angle, vAngle )

			//Set the behavior specific variables for the cluster's entity
			entity_set_int( cluster, EV_INT_movetype, 6 ) //Has gravity and registers collisions
			entity_set_int( cluster, EV_INT_solid, 1 ) //Collisions do not block

			//Record who the owner of this nade is
			entity_set_edict( cluster, EV_ENT_owner, get_grenade_owner() )

			//Make the cluster fly!
			entity_set_vector( cluster, EV_VEC_velocity, velocity ) 
		}
	}

	return PLUGIN_CONTINUE
}

public enable_cluster_grenade( id ) {
	new argument[1], number

	read_argv( 1, argument, 1 )
	number = str_to_num( argument )

	if ( number == 0 ) {
		enabled = false
	}
	if ( number == 1 ) {
		enabled =true
	}

	return PLUGIN_HANDLED
}

public plugin_init() {
	register_plugin( "Cluster Grenades", "1.0beta", "doomy" )

	register_concmd( "amx_cluster_grenade_enable", "enable_cluster_grenade", ADMIN_KICK, "Enable or disable cluster grenades (1 = enable, 0 = false)" )

	register_message( 23, "grenade_explosion" )
	register_message( 77, "fire_in_the_hole" )
	register_message( 83, "death_msg" )
	register_message( 99,"grenade_throw" )

	return PLUGIN_CONTINUE	
}

public plugin_precachce() {
	precache_sound( "sound/weapons/explode3.wav" )
	explosion1 = precache_model( "sprites/zerogxplode.spr" )
	explosion2 = precache_model( "sprites/explode1.spr" )
}

//MISCELLANEOUS FUNCTIONS

deal_grenade_damage( attacked, attacker, Float:damage ) {
	//DeathMsg 85 -1 BYTE : killer index BYTE : victim index STRING : weapon 
	if ( get_user_health( attacked ) - floatround( damage ) <= 0 ) {
		//Stops the default death message from being displayed
		catchdeath = true
		user_kill( attacked )
		
		//Displays who killed who
		message_begin( 2, 83 )
		write_byte( attacker )
		write_byte( attacked )
		write_byte( 0 ) //No idea what this does
		write_string( "grenade" )
		message_end()

		//Adds a frag to the killer
		set_user_frags( attacker, get_user_frags( attacker ) + 1 )
	}
	else
		set_user_health( attacked, get_user_health( attacked ) - floatround( damage ) )
}

add_grenade_owner( owner ) {
	for ( new i = 0; i < 32; i++ ) {
		if ( grenade[i] == 0 ) {
			grenade[i] = owner
			return
		}
	}
}

stock get_grenade_owner() {
	new which = grenade[0]
	for ( new i = 1; i < 32; i++ ) {
		grenade[i - 1] = grenade[i]
	}
	grenade[31] = 0

	return which
}

Last edited by Ark_Procession; 06-07-2022 at 00:34.
Ark_Procession is offline
Celena Luna
Veteran Member
Join Date: Aug 2013
Location: Nagazora
Old 06-07-2022 , 00:41   Re: Cluster Grenade that doesn't go behind walls
Reply With Quote #8

OK, for the newer code
PHP Code:
#include < amxmodx >
#include < amxmisc >
#include < engine >
#include < fun >
#include < fakemeta >

#define TE_EXPLOSION 3
#define TE_WORLDDECAL 116

#define CLUSTERS 5

#define MAX_CLUSTER_DAMAGE 20
#define CLUSTER_DAMAGE_RADIUS 300

#define MIN_FLY_DISTANCE 200
#define MAX_FLY_DISTANCE 400

#define UPWARD_ARC 200

#define SCORCH 47

new explosion1explosion2grenade[32], last
new bool:enabled true
new bool:catchdeath false

public death_msg() {
    if ( 
catchdeath ) {
        
catchdeath false
        
return PLUGIN_HANDLED
    
}

    return 
PLUGIN_CONTINUE
}

public 
grenade_throw() {

    if ( 
get_msg_args() < ) return PLUGIN_HANDLED_MAIN

    
if ( get_msg_arg_int) == 12 && get_msg_arg_int) == )
        
add_grenade_ownerlast )

    return 
PLUGIN_CONTINUE
}

public 
fire_in_the_holeiddestent ) {
    if ( 
get_msg_args() != ) return PLUGIN_CONTINUE

    
new temp[17]
    
get_msg_arg_string5temp17 )

    if ( 
equalitemp"#Fire_in_the_hole" ) ) {
        new 
name[32]
        
entity_get_stringentEV_SZ_netnamename32 )

        
last find_player"a"name )
    }

    return 
PLUGIN_CONTINUE
}

public 
pfn_touchptrptd ) { 

    
//Gets the indentifying strings of each entity
    
new identify[15], compare[15], Float:origin[3]
    if ( 
ptr == identify "world"
    
else entity_get_stringptrEV_SZ_classnameidentify15 )
    if ( 
ptd == compare "world"
    
else if ( is_valid_entptd ) ) entity_get_stringptdEV_SZ_classnamecompare15 )

    
//Ensures that the grenade cluster argument is always the 'ptr'
    
if ( ptr == || equalicompare"grenade_cluster" ) ) return PLUGIN_HANDLED

    
//Checks to see if it is a grenade cluster hitting another object. If it is it explodes and deals damage
    
if ( equaliidentify"grenade_cluster" ) ) {
        
entity_get_vectorptrEV_VEC_originorigin )

        
//Deals radius damage to the spot of collision
        
new player[32], playerslocation[3], origin2[3], distanceFloat:multiplierownerFloat:origin3[3]
        
origin2[0] = floatroundorigin[0] )
        
origin2[1] = floatroundorigin[1] )
        
origin2[2] = floatroundorigin[2] )

        
owner entity_get_edictptrEV_ENT_owner )

        
get_playersplayerplayers"a" )
        for ( new 
0playersi++ ) {
            
get_user_originplayer[i], location )
            
entity_get_vectorplayer[i], EV_VEC_originorigin3 )
            
distance get_distanceorigin2location )
            if ( 
distance CLUSTER_DAMAGE_RADIUS && !is_wall_between_points(originorigin31)) {
                
multiplier floatdivfloatCLUSTER_DAMAGE_RADIUS distance ), floatCLUSTER_DAMAGE_RADIUS ) )
                
deal_grenade_damageplayer[i], ownerfloatmulmultiplierfloatMAX_CLUSTER_DAMAGE ) ) )
            }
        }

        
//Paints the explosion
        
message_beginMSG_BROADCASTSVC_TEMPENTITY 
        
write_byteTE_EXPLOSION 
        
write_coordfloatroundorigin[0] ) ) 
        
write_coordfloatroundorigin[1] ) ) 
        
write_coordfloatroundorigin[2] ) ) 
        
write_shortexplosion1 
        
write_byte50 
        
write_byte15 
        
write_byte)
        
message_end() 

        
message_beginMSG_BROADCASTSVC_TEMPENTITY 
        
write_byteTE_EXPLOSION 
        
write_coordfloatroundorigin[0] ) ) 
        
write_coordfloatroundorigin[1] ) ) 
        
write_coordfloatroundorigin[2] ) ) 
        
write_shortexplosion2 
        
write_byte50 
        
write_byte15 
        
write_byte)
        
message_end() 

        
//If the grenade hit the ground or a wall then this draws a land scar
        
if ( ptd == ) {
            
message_beginMSG_BROADCASTSVC_TEMPENTITY )
            
write_byteTE_WORLDDECAL )
            
write_coordfloatroundorigin[0] ) ) 
            
write_coordfloatroundorigin[1] ) ) 
            
write_coordfloatroundorigin[2] ) ) 
            
write_byteSCORCH )
            
message_end()
        }

        
remove_entityptr //Removes the grenade cluster so that it does not enter an infinite loop

        
return PLUGIN_HANDLED
    
}

    return 
PLUGIN_CONTINUE
}

public 
grenade_explosion() {
    if (
get_msg_arg_int) == && get_msg_arg_int ) == 25 && get_msg_arg_int ) == 30 && enabled) {
        new 
pos[3]
        
pos[0] = floatroundget_msg_arg_float) )
        
pos[1] = floatroundget_msg_arg_float) )
        
pos[2] = floatroundget_msg_arg_float) )

        new 
clusterFloat:vAngle[3], Float:angles[3], Float:velocity[3], Rvelocity[3], Float:distanceFloat:actualDistanceFloat:multiplier

        
new Float:origin[3
        
origin[0] = floatpos[0] )
        
origin[1] = floatpos[1] )
        
origin[2] = floatpos[2] )

        new 
Float:minBox[3] = { -1.0, ... }
        new 
Float:maxBox[3] = { 1.0, ... }
        
        
//This will launch the above specified number of clusters
        
for (new 0CLUSTERSi++) {
            
//Create a random direction for the cluster to fly
            
velocity[0] = random_floatfloatMIN_FLY_DISTANCE ), floatMAX_FLY_DISTANCE ) )
            if ( 
random_num0) == velocity[0] = floatmulvelocity[0], -1.0 )
            
velocity[1] = random_floatfloatMIN_FLY_DISTANCE ), floatMAX_FLY_DISTANCE ) )
            if ( 
random_num0) == velocity[1] = floatmulvelocity[1], -1.0 )
            
velocity[2] = floatUPWARD_ARC )

            
Rvelocity[0] = pos[0] + floatroundvelocity[0] )
            
Rvelocity[1] = pos[1] + floatroundvelocity[1] )
            
Rvelocity[2] = pos[2] + floatroundvelocity[2] )

            
//Create the distance the cluster will fly
            
distance random_floatfloatMIN_FLY_DISTANCE ), floatMAX_FLY_DISTANCE ) )
            
actualDistance floatget_distanceposRvelocity ) )
            
multiplier floatdivdistanceactualDistance )
            

            
velocity[0] = floatmulvelocity[0], multiplier )
            
velocity[1] = floatmulvelocity[1], multiplier )
            
velocity[2] = floatmulvelocity[2], multiplier )

            
//Create the angles for the facing of the cluster. PS: I have no idea how to do the angle thing really. This is a blind attempt.
            
vector_to_anglevelocityangles )
            
vector_to_anglevelocityvAngle )

            
//Create the entity of the cluster
            
cluster create_entity"info_target" )

            
//Set the identifying string of the cluster's entity
            
entity_set_stringclusterEV_SZ_classname"grenade_cluster"

            
//Set the model for the cluster's entity
            
entity_set_modelcluster"models/grenade.mdl" )     

            
//Set the bounds for the cluster's entity    
            
entity_set_vectorclusterEV_VEC_minsminBox)
            
entity_set_vectorclusterEV_VEC_maxsmaxBox)

            
//Set the origin for the cluster's entity (NOTE: The clusters will spawn in the same spot, but they will be set to ignore eachother
            
entity_set_originclusterorigin )

            
//Set the angles of the cluster's entity    
            
entity_set_vectorclusterEV_VEC_anglesangles )
            
entity_set_vectorclusterEV_VEC_v_anglevAngle )

            
//Set the behavior specific variables for the cluster's entity
            
entity_set_intclusterEV_INT_movetype//Has gravity and registers collisions
            
entity_set_intclusterEV_INT_solid//Collisions do not block

            //Record who the owner of this nade is
            
entity_set_edictclusterEV_ENT_ownerget_grenade_owner() )

            
//Make the cluster fly!
            
entity_set_vectorclusterEV_VEC_velocityvelocity 
        }
    }

    return 
PLUGIN_CONTINUE
}

public 
enable_cluster_grenadeid ) {
    new 
argument[1], number

    read_argv
1argument)
    
number str_to_numargument )

    if ( 
number == ) {
        
enabled false
    
}
    if ( 
number == ) {
        
enabled =true
    
}

    return 
PLUGIN_HANDLED
}

public 
plugin_init() {
    
register_plugin"Cluster Grenades""1.0beta""doomy" )

    
register_concmd"amx_cluster_grenade_enable""enable_cluster_grenade"ADMIN_KICK"Enable or disable cluster grenades (1 = enable, 0 = false)" )

    
register_message23"grenade_explosion" )
    
register_message77"fire_in_the_hole" )
    
register_message83"death_msg" )
    
register_message99,"grenade_throw" )

    return 
PLUGIN_CONTINUE    
}

public 
plugin_precachce() {
    
precache_sound"sound/weapons/explode3.wav" )
    
explosion1 precache_model"sprites/zerogxplode.spr" )
    
explosion2 precache_model"sprites/explode1.spr" )
}

//MISCELLANEOUS FUNCTIONS

deal_grenade_damageattackedattackerFloat:damage ) {
    
//DeathMsg 85 -1 BYTE : killer index BYTE : victim index STRING : weapon 
    
if ( get_user_healthattacked ) - floatrounddamage ) <= ) {
        
//Stops the default death message from being displayed
        
catchdeath true
        user_kill
attacked )
        
        
//Displays who killed who
        
message_begin283 )
        
write_byteattacker )
        
write_byteattacked )
        
write_byte//No idea what this does
        
write_string"grenade" )
        
message_end()

        
//Adds a frag to the killer
        
set_user_fragsattackerget_user_fragsattacker ) + )
    }
    else
        
set_user_healthattackedget_user_healthattacked ) - floatrounddamage ) )
}

add_grenade_ownerowner ) {
    for ( new 
032i++ ) {
        if ( 
grenade[i] == ) {
            
grenade[i] = owner
            
return
        }
    }
}

stock get_grenade_owner() {
    new 
which grenade[0]
    for ( new 
132i++ ) {
        
grenade[1] = grenade[i]
    }
    
grenade[31] = 0

    
return which
}

stock is_wall_between_points(Float:start[3], Float:end[3], ignore_ent)
{
    static 
ptr
    ptr 
create_tr2()

    
engfunc(EngFunc_TraceLinestartendIGNORE_MONSTERSignore_entptr)
    
    static 
Float:EndPos[3]
    
get_tr2(ptrTR_vecEndPosEndPos)

    
free_tr2(ptr)
    return 
floatround(get_distance_f(endEndPos))

__________________
My plugin:
Celena Luna is offline
Ark_Procession
Senior Member
Join Date: Jun 2020
Location: Argentina
Old 06-07-2022 , 00:47   Re: Cluster Grenade that doesn't go behind walls
Reply With Quote #9

Quote:
Originally Posted by Celena Luna View Post
OK, for the newer code
PHP Code:
#include < amxmodx >
#include < amxmisc >
#include < engine >
#include < fun >
#include < fakemeta >

#define TE_EXPLOSION 3
#define TE_WORLDDECAL 116

#define CLUSTERS 5

#define MAX_CLUSTER_DAMAGE 20
#define CLUSTER_DAMAGE_RADIUS 300

#define MIN_FLY_DISTANCE 200
#define MAX_FLY_DISTANCE 400

#define UPWARD_ARC 200

#define SCORCH 47

new explosion1explosion2grenade[32], last
new bool:enabled true
new bool:catchdeath false

public death_msg() {
    if ( 
catchdeath ) {
        
catchdeath false
        
return PLUGIN_HANDLED
    
}

    return 
PLUGIN_CONTINUE
}

public 
grenade_throw() {

    if ( 
get_msg_args() < ) return PLUGIN_HANDLED_MAIN

    
if ( get_msg_arg_int) == 12 && get_msg_arg_int) == )
        
add_grenade_ownerlast )

    return 
PLUGIN_CONTINUE
}

public 
fire_in_the_holeiddestent ) {
    if ( 
get_msg_args() != ) return PLUGIN_CONTINUE

    
new temp[17]
    
get_msg_arg_string5temp17 )

    if ( 
equalitemp"#Fire_in_the_hole" ) ) {
        new 
name[32]
        
entity_get_stringentEV_SZ_netnamename32 )

        
last find_player"a"name )
    }

    return 
PLUGIN_CONTINUE
}

public 
pfn_touchptrptd ) { 

    
//Gets the indentifying strings of each entity
    
new identify[15], compare[15], Float:origin[3]
    if ( 
ptr == identify "world"
    
else entity_get_stringptrEV_SZ_classnameidentify15 )
    if ( 
ptd == compare "world"
    
else if ( is_valid_entptd ) ) entity_get_stringptdEV_SZ_classnamecompare15 )

    
//Ensures that the grenade cluster argument is always the 'ptr'
    
if ( ptr == || equalicompare"grenade_cluster" ) ) return PLUGIN_HANDLED

    
//Checks to see if it is a grenade cluster hitting another object. If it is it explodes and deals damage
    
if ( equaliidentify"grenade_cluster" ) ) {
        
entity_get_vectorptrEV_VEC_originorigin )

        
//Deals radius damage to the spot of collision
        
new player[32], playerslocation[3], origin2[3], distanceFloat:multiplierownerFloat:origin3[3]
        
origin2[0] = floatroundorigin[0] )
        
origin2[1] = floatroundorigin[1] )
        
origin2[2] = floatroundorigin[2] )

        
owner entity_get_edictptrEV_ENT_owner )

        
get_playersplayerplayers"a" )
        for ( new 
0playersi++ ) {
            
get_user_originplayer[i], location )
            
entity_get_vectorplayer[i], EV_VEC_originorigin3 )
            
distance get_distanceorigin2location )
            if ( 
distance CLUSTER_DAMAGE_RADIUS && !is_wall_between_points(originorigin31)) {
                
multiplier floatdivfloatCLUSTER_DAMAGE_RADIUS distance ), floatCLUSTER_DAMAGE_RADIUS ) )
                
deal_grenade_damageplayer[i], ownerfloatmulmultiplierfloatMAX_CLUSTER_DAMAGE ) ) )
            }
        }

        
//Paints the explosion
        
message_beginMSG_BROADCASTSVC_TEMPENTITY 
        
write_byteTE_EXPLOSION 
        
write_coordfloatroundorigin[0] ) ) 
        
write_coordfloatroundorigin[1] ) ) 
        
write_coordfloatroundorigin[2] ) ) 
        
write_shortexplosion1 
        
write_byte50 
        
write_byte15 
        
write_byte)
        
message_end() 

        
message_beginMSG_BROADCASTSVC_TEMPENTITY 
        
write_byteTE_EXPLOSION 
        
write_coordfloatroundorigin[0] ) ) 
        
write_coordfloatroundorigin[1] ) ) 
        
write_coordfloatroundorigin[2] ) ) 
        
write_shortexplosion2 
        
write_byte50 
        
write_byte15 
        
write_byte)
        
message_end() 

        
//If the grenade hit the ground or a wall then this draws a land scar
        
if ( ptd == ) {
            
message_beginMSG_BROADCASTSVC_TEMPENTITY )
            
write_byteTE_WORLDDECAL )
            
write_coordfloatroundorigin[0] ) ) 
            
write_coordfloatroundorigin[1] ) ) 
            
write_coordfloatroundorigin[2] ) ) 
            
write_byteSCORCH )
            
message_end()
        }

        
remove_entityptr //Removes the grenade cluster so that it does not enter an infinite loop

        
return PLUGIN_HANDLED
    
}

    return 
PLUGIN_CONTINUE
}

public 
grenade_explosion() {
    if (
get_msg_arg_int) == && get_msg_arg_int ) == 25 && get_msg_arg_int ) == 30 && enabled) {
        new 
pos[3]
        
pos[0] = floatroundget_msg_arg_float) )
        
pos[1] = floatroundget_msg_arg_float) )
        
pos[2] = floatroundget_msg_arg_float) )

        new 
clusterFloat:vAngle[3], Float:angles[3], Float:velocity[3], Rvelocity[3], Float:distanceFloat:actualDistanceFloat:multiplier

        
new Float:origin[3
        
origin[0] = floatpos[0] )
        
origin[1] = floatpos[1] )
        
origin[2] = floatpos[2] )

        new 
Float:minBox[3] = { -1.0, ... }
        new 
Float:maxBox[3] = { 1.0, ... }
        
        
//This will launch the above specified number of clusters
        
for (new 0CLUSTERSi++) {
            
//Create a random direction for the cluster to fly
            
velocity[0] = random_floatfloatMIN_FLY_DISTANCE ), floatMAX_FLY_DISTANCE ) )
            if ( 
random_num0) == velocity[0] = floatmulvelocity[0], -1.0 )
            
velocity[1] = random_floatfloatMIN_FLY_DISTANCE ), floatMAX_FLY_DISTANCE ) )
            if ( 
random_num0) == velocity[1] = floatmulvelocity[1], -1.0 )
            
velocity[2] = floatUPWARD_ARC )

            
Rvelocity[0] = pos[0] + floatroundvelocity[0] )
            
Rvelocity[1] = pos[1] + floatroundvelocity[1] )
            
Rvelocity[2] = pos[2] + floatroundvelocity[2] )

            
//Create the distance the cluster will fly
            
distance random_floatfloatMIN_FLY_DISTANCE ), floatMAX_FLY_DISTANCE ) )
            
actualDistance floatget_distanceposRvelocity ) )
            
multiplier floatdivdistanceactualDistance )
            

            
velocity[0] = floatmulvelocity[0], multiplier )
            
velocity[1] = floatmulvelocity[1], multiplier )
            
velocity[2] = floatmulvelocity[2], multiplier )

            
//Create the angles for the facing of the cluster. PS: I have no idea how to do the angle thing really. This is a blind attempt.
            
vector_to_anglevelocityangles )
            
vector_to_anglevelocityvAngle )

            
//Create the entity of the cluster
            
cluster create_entity"info_target" )

            
//Set the identifying string of the cluster's entity
            
entity_set_stringclusterEV_SZ_classname"grenade_cluster"

            
//Set the model for the cluster's entity
            
entity_set_modelcluster"models/grenade.mdl" )     

            
//Set the bounds for the cluster's entity    
            
entity_set_vectorclusterEV_VEC_minsminBox)
            
entity_set_vectorclusterEV_VEC_maxsmaxBox)

            
//Set the origin for the cluster's entity (NOTE: The clusters will spawn in the same spot, but they will be set to ignore eachother
            
entity_set_originclusterorigin )

            
//Set the angles of the cluster's entity    
            
entity_set_vectorclusterEV_VEC_anglesangles )
            
entity_set_vectorclusterEV_VEC_v_anglevAngle )

            
//Set the behavior specific variables for the cluster's entity
            
entity_set_intclusterEV_INT_movetype//Has gravity and registers collisions
            
entity_set_intclusterEV_INT_solid//Collisions do not block

            //Record who the owner of this nade is
            
entity_set_edictclusterEV_ENT_ownerget_grenade_owner() )

            
//Make the cluster fly!
            
entity_set_vectorclusterEV_VEC_velocityvelocity 
        }
    }

    return 
PLUGIN_CONTINUE
}

public 
enable_cluster_grenadeid ) {
    new 
argument[1], number

    read_argv
1argument)
    
number str_to_numargument )

    if ( 
number == ) {
        
enabled false
    
}
    if ( 
number == ) {
        
enabled =true
    
}

    return 
PLUGIN_HANDLED
}

public 
plugin_init() {
    
register_plugin"Cluster Grenades""1.0beta""doomy" )

    
register_concmd"amx_cluster_grenade_enable""enable_cluster_grenade"ADMIN_KICK"Enable or disable cluster grenades (1 = enable, 0 = false)" )

    
register_message23"grenade_explosion" )
    
register_message77"fire_in_the_hole" )
    
register_message83"death_msg" )
    
register_message99,"grenade_throw" )

    return 
PLUGIN_CONTINUE    
}

public 
plugin_precachce() {
    
precache_sound"sound/weapons/explode3.wav" )
    
explosion1 precache_model"sprites/zerogxplode.spr" )
    
explosion2 precache_model"sprites/explode1.spr" )
}

//MISCELLANEOUS FUNCTIONS

deal_grenade_damageattackedattackerFloat:damage ) {
    
//DeathMsg 85 -1 BYTE : killer index BYTE : victim index STRING : weapon 
    
if ( get_user_healthattacked ) - floatrounddamage ) <= ) {
        
//Stops the default death message from being displayed
        
catchdeath true
        user_kill
attacked )
        
        
//Displays who killed who
        
message_begin283 )
        
write_byteattacker )
        
write_byteattacked )
        
write_byte//No idea what this does
        
write_string"grenade" )
        
message_end()

        
//Adds a frag to the killer
        
set_user_fragsattackerget_user_fragsattacker ) + )
    }
    else
        
set_user_healthattackedget_user_healthattacked ) - floatrounddamage ) )
}

add_grenade_ownerowner ) {
    for ( new 
032i++ ) {
        if ( 
grenade[i] == ) {
            
grenade[i] = owner
            
return
        }
    }
}

stock get_grenade_owner() {
    new 
which grenade[0]
    for ( new 
132i++ ) {
        
grenade[1] = grenade[i]
    }
    
grenade[31] = 0

    
return which
}

stock is_wall_between_points(Float:start[3], Float:end[3], ignore_ent)
{
    static 
ptr
    ptr 
create_tr2()

    
engfunc(EngFunc_TraceLinestartendIGNORE_MONSTERSignore_entptr)
    
    static 
Float:EndPos[3]
    
get_tr2(ptrTR_vecEndPosEndPos)

    
free_tr2(ptr)
    return 
floatround(get_distance_f(endEndPos))

wow you are great, such level of patience!

something is wrong with some offset or something? ( look at me trying to talk code)

the decal that renders after grenade and clusters explode is a literal number "5" now. hilarious

Edit: maybe don't waste your energy and time fixing this.
My main plugin is extra damage mod from V3X.

if you found yourself bored, consider checking the code and hint me on what could be the possible cause "hegrenades" sometimes go off without damage.

is actually that reason why i am using cluster grenades since is the only plugin i found that doesn't mess with scoreboard, doesn't fail applying damage, and actually works.

Last edited by Ark_Procession; 06-07-2022 at 00:48.
Ark_Procession 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 04:21.


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