set g_balance_firetransfer_damage 0.8
set g_throughfloor_damage 1
set g_throughfloor_force 1
+set g_projectiles_damage 1
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines)
+// 0: only damage from contents (lava/slime) or exceptions
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
set g_projectiles_newton_style 2
// possible values:
// 0: absolute velocity projectiles (like Quake)
set g_balance_firetransfer_damage 0.8
set g_throughfloor_damage 0.7
set g_throughfloor_force 0.8
+set g_projectiles_damage 1
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines)
+// 0: only damage from contents (lava/slime) or exceptions
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
set g_projectiles_newton_style 2
// possible values:
// 0: absolute velocity projectiles (like Quake)
set g_balance_firetransfer_damage 0.8
set g_throughfloor_damage 0.4
set g_throughfloor_force 0.7
+set g_projectiles_damage 1
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines)
+// 0: only damage from contents (lava/slime) or exceptions
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
set g_projectiles_newton_style 2
// possible values:
// 0: absolute velocity projectiles (like Quake)
set g_balance_firetransfer_damage 0.8
set g_throughfloor_damage 0.5
set g_throughfloor_force 0.75
+set g_projectiles_damage 1
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines)
+// 0: only damage from contents (lava/slime) or exceptions
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
set g_projectiles_newton_style 2
// possible values:
// 0: absolute velocity projectiles (like Quake)
set g_balance_firetransfer_damage 0.8
set g_throughfloor_damage 0.5
set g_throughfloor_force 0.7
+set g_projectiles_damage 1
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines)
+// 0: only damage from contents (lava/slime) or exceptions
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
set g_projectiles_newton_style 2
// possible values:
// 0: absolute velocity projectiles (like Quake)
float autocvar_g_powerup_shield;
float autocvar_g_powerup_strength;
float autocvar_g_powerup_superhealth;
+float autocvar_g_projectiles_damage;
float autocvar_g_projectiles_newton_style;
float autocvar_g_projectiles_newton_style_2_maxfactor;
float autocvar_g_projectiles_newton_style_2_minfactor;
void GrapplingHook_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
- if(self.health > 0)
- {
- self.health = self.health - damage;
+ if(self.health <= 0)
+ return;
- print(strcat("hook health ", ftos(self.health), " after ", ftos(damage), " damage... (at time: ", ftos(time), ")\n"));
+ if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, 0)) // no exceptions
+ return; // g_balance_projectiledamage says to halt
+
+ self.health = self.health - damage;
- if (self.health <= 0)
+ print(strcat("hook health ", ftos(self.health), " after ", ftos(damage), " damage... (at time: ", ftos(time), ")\n"));
+
+ if (self.health <= 0)
+ {
+ if(attacker != self.realowner)
{
- if(attacker != self.realowner)
- {
- self.realowner.pusher = attacker;
- self.realowner.pushltime = time + autocvar_g_maxpushtime;
- }
- RemoveGrapplingHook(self.realowner);
+ self.realowner.pusher = attacker;
+ self.realowner.pushltime = time + autocvar_g_maxpushtime;
}
+ RemoveGrapplingHook(self.realowner);
}
}
trace_endpos = end;
}
+float W_CheckProjectileDamage(entity inflictor, entity projowner, float deathtype, float exception)
+{
+ float is_from_contents = (deathtype == DEATH_SLIME || deathtype == DEATH_LAVA);
+ float is_from_owner = (inflictor == projowner);
+
+ if(autocvar_g_projectiles_damage <= -2)
+ return FALSE; // no damage to projectiles at all, not even with the exceptions
+
+ else if(autocvar_g_projectiles_damage == -1)
+ if not(exception)
+ return FALSE; // no damage other than exceptions (electro combo, hagar join explode, minelayer mines)
+
+ else if(autocvar_g_projectiles_damage == 0)
+ if not(is_from_contents || exception)
+ return FALSE; // only damage from contents or exceptions is allowed
+
+ else if(autocvar_g_projectiles_damage == 1)
+ if not(is_from_contents || is_from_owner || exception)
+ return FALSE; // only self damage or damage from contents or exceptions is allowed
+
+ // -2 or lower disables all damage including exceptions
+ // 2 or higher automatically allows all damage normally
+
+ return TRUE; // continue with the damage as planned
+}
+
void W_PrepareExplosionByDamage(entity attacker, void() explode)
{
self.takedamage = DAMAGE_NO;
{
if(self.health <= 0)
return;
+
// note: combos are usually triggered by W_Plasma_TriggerCombo, not damage
+ float is_combo = (inflictor.classname == "plasma_chain" || inflictor.classname == "plasma_prim");
+
+ if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, is_combo))
+ return; // g_projectiles_damage says to halt
+
self.health = self.health - damage;
if (self.health <= 0)
{
self.takedamage = DAMAGE_NO;
self.nextthink = time;
- if (inflictor.classname == "plasma_chain" || inflictor.classname == "plasma_prim")
+ if (is_combo)
{
// change owner to whoever caused the combo explosion
self.realowner = inflictor.realowner;
{
if(self.health <= 0)
return;
+
+ if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, 0)) // no exceptions
+ return; // g_projectiles_damage says to halt
+
self.health = self.health - damage;
if (self.health <= 0)
{
{
if (self.health <= 0)
return;
+
+ if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, 0)) // no exceptions
+ return; // g_projectiles_damage says to halt
+
self.health = self.health - damage;
print(strcat("grenade health ", ftos(self.health), " after ", ftos(damage), " damage... (at time: ", ftos(time), ")\n"));
if (self.health <= 0)
return;
- if ((inflictor.realowner == self.realowner) && !autocvar_g_balance_hagar_secondary_load_linkexplode)
- return;
+ float is_linkexplode = ((inflictor.realowner == self.realowner)
+ && ((inflictor.projectiledeathtype & HITTYPE_SECONDARY) && (self.projectiledeathtype & HITTYPE_SECONDARY))
+ && !autocvar_g_balance_hagar_secondary_load_linkexplode);
+
+ if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, is_linkexplode))
+ return; // g_projectiles_damage says to halt
self.health = self.health - damage;
self.angles = vectoangles(self.velocity);
missile.think = adaptor_think2use_hittype_splash;
missile.nextthink = time + autocvar_g_balance_hagar_secondary_lifetime_min + random() * autocvar_g_balance_hagar_secondary_lifetime_rand;
PROJECTILE_MAKETRIGGER(missile);
- missile.projectiledeathtype = WEP_HAGAR;
+ missile.projectiledeathtype = WEP_HAGAR | HITTYPE_SECONDARY;
setorigin (missile, w_shotorg);
setsize(missile, '0 0 0', '0 0 0');
missile.movetype = MOVETYPE_FLY;
{
if (self.health <= 0)
return;
+
+ if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, 0)) // no exceptions
+ return; // g_projectiles_damage says to halt
+
self.health = self.health - damage;
print(strcat("hookbomb health ", ftos(self.health), " after ", ftos(damage), " damage... (at time: ", ftos(time), ")\n"));
{
if (self.health <= 0)
return;
+
+ float is_from_enemy = (inflictor.realowner != self.realowner);
+
+ if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, is_from_enemy))
+ return; // g_projectiles_damage says to halt
+
self.health = self.health - damage;
self.angles = vectoangles(self.velocity);
{
if (self.health <= 0)
return;
+
+ if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, 0)) // no exceptions
+ return; // g_projectiles_damage says to halt
+
self.health = self.health - damage;
self.angles = vectoangles(self.velocity);
{
if (self.health <= 0)
return;
+
+ if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, 0)) // no exceptions
+ return; // g_projectiles_damage says to halt
if (self.realowner == attacker)
self.health = self.health - (damage * 0.25);