As you know Condition Zero implemented the no damage through walls for Hegrenades
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 )
}
}