Raised This Month: $ Target: $400
 0% 

Cluster Grenade that doesn't go behind walls


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
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
 



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 21:18.


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