X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fg_damage.qc;h=593aaf7e378e889889e601a266aa58ab67be4239;hb=5b6514ad570d0210590f6fb10b6abd26df38cbd8;hp=066fdcf1046c81e7b50b58cbc5b42a6bc973e6c7;hpb=7897f63225d8cb32c96e00c682eb6ec78ae2b170;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 066fdcf10..593aaf7e3 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -186,11 +186,7 @@ void GiveFrags (entity attacker, entity targ, float f, float deathtype) else { self = oldself; - if(g_runematch) - { - f = RunematchHandleFrags(attacker, targ, f); - } - else if(g_lms) + if(g_lms) { // remove a life float tl; @@ -216,44 +212,6 @@ void GiveFrags (entity attacker, entity targ, float f, float deathtype) UpdateFrags(attacker, f); } -/*string Obituary_ExtraFragInfo(entity player) // Extra fragmessage information -{ - string health_output = string_null; - string ping_output = string_null; - string handicap_output = string_null; - string output = string_null; - - if(autocvar_sv_fraginfo && ((autocvar_sv_fraginfo == 2) || inWarmupStage)) - { - // health/armor of attacker (person who killed you) - if(autocvar_sv_fraginfo_stats && (player.health >= 1)) - health_output = strcat("^7(Health ^1", ftos(rint(player.health)), "^7 / Armor ^2", ftos(rint(player.armorvalue)), "^7)"); - - // ping display - if(autocvar_sv_fraginfo_ping) - ping_output = ((clienttype(player) == CLIENTTYPE_BOT) ? "^2Bot" : strcat("Ping ", ((player.ping >= 150) ? "^1" : "^2"), ftos(rint(player.ping)), "ms")); - - // handicap display - if(autocvar_sv_fraginfo_handicap) - { - if(autocvar_sv_fraginfo_handicap == 2) - handicap_output = strcat(output, strcat("Handicap ^2", ((player.cvar_cl_handicap <= 1) ? "Off" : ftos(rint(player.cvar_cl_handicap))))); - else if(player.cvar_cl_handicap) // with _handicap 1, only show this if there actually is a handicap enabled. - handicap_output = strcat("Handicap ^2", ftos(rint(player.cvar_cl_handicap))); - } - - // format the string - output = strcat(health_output, (health_output ? ((ping_output || handicap_output) ? " ^7(" : "") : ((ping_output || handicap_output) ? "^7(" : "")), - ping_output, (handicap_output ? "^7 / " : ""), - handicap_output, ((ping_output || handicap_output) ? "^7)" : "")); - - // add new line to the beginning if there is a message - if(output) { output = strcat("\n", output); } - } - - return output; -}*/ - string AppendItemcodes(string s, entity player) { float w; @@ -273,8 +231,6 @@ string AppendItemcodes(string s, entity player) s = strcat(s, "T"); if(player.kh_next) s = strcat(s, "K"); - if(player.runes) - s = strcat(s, "|", ftos(player.runes)); return s; } @@ -297,55 +253,75 @@ void LogDeath(string mode, float deathtype, entity killer, entity killed) GameLogEcho(s); } -#define INFO_NO_MSG 0 - -void Obituary_SpecialDeath(entity notif_target, float murder, float deathtype, string s1, string s2, float f1, float f2, float f3) +void Obituary_SpecialDeath( + entity notif_target, + float murder, + float deathtype, + string s1, string s2, string s3, + float f1, float f2, float f3) { - float handled = 0, hits = 0; if(DEATH_ISSPECIAL(deathtype)) { - #define DEATHTYPE(name,msg_death,msg_death_by,position) \ - { if(deathtype == max(0, name)) \ - { \ - #if msg_death != NO_MSG \ - if not(murder) \ - { \ - Send_Notification_WOVA(NOTIF_ONE, notif_target, MSG_DEATH, msg_death, s1, s2, "", "", f1, f2, f3, 0); \ - Send_Notification_WOVA(NOTIF_ANY_EXCEPT, notif_target, MSG_INFO, INFO_##msg_death, s1, s2, "", "", f1, f2, f3, 0); \ - ++handled; \ - } \ - #endif \ - #if msg_death_by != NO_MSG \ - if(murder) \ - { \ - Send_Notification_WOVA(NOTIF_ONE, notif_target, MSG_DEATH, msg_death_by, s1, s2, "", "", f1, f2, f3, 0); \ - Send_Notification_WOVA(NOTIF_ANY_EXCEPT, notif_target, MSG_INFO, INFO_##msg_death_by, s1, s2, "", "", f1, f2, f3, 0); \ - ++handled; \ - } \ - #endif \ - ++hits; \ - } } - - DEATHTYPES - #undef DEATHTYPE - - if not(hits) + entity deathent = deathtypes[(deathtype - DT_FIRST) - 1]; + if not(deathent) { backtrace("Obituary_SpecialDeath: Could not find deathtype entity!\n"); return; } + + if(murder) { - backtrace("Obituary_SpecialDeath(): Unhandled deathtype- Please notify Samual!\n"); + if(deathent.death_msgmurder) + { + Send_Notification_WOVA( + NOTIF_ONE, + notif_target, + MSG_MULTI, + deathent.death_msgmurder.nent_id, + s1, s2, s3, "", + f1, f2, f3, 0 + ); + Send_Notification_WOVA( + NOTIF_ALL_EXCEPT, + notif_target, + MSG_INFO, + deathent.death_msgmurder.nent_msginfo.nent_id, + s1, s2, s3, "", + f1, f2, f3, 0 + ); + } } - if not(handled) + else { - dprint(sprintf("Obituary_SpecialDeath(): ^1Deathtype ^7(%s-%d)^1 has no notification!\n", Deathtype_Name(deathtype), deathtype)); - return; + if(deathent.death_msgself) + { + Send_Notification_WOVA( + NOTIF_ONE, + notif_target, + MSG_MULTI, + deathent.death_msgself.nent_id, + s1, s2, s3, "", + f1, f2, f3, 0 + ); + Send_Notification_WOVA( + NOTIF_ALL_EXCEPT, + notif_target, + MSG_INFO, + deathent.death_msgself.nent_msginfo.nent_id, + s1, s2, s3, "", + f1, f2, f3, 0 + ); + } } } + else { backtrace("Obituary_SpecialDeath called without a special deathtype?\n"); return; } } float w_deathtype; -float Obituary_WeaponDeath(entity notif_target, float murder, float deathtype, string s1, string s2, float f1, float f2) +float Obituary_WeaponDeath( + entity notif_target, + float murder, + float deathtype, + string s1, string s2, string s3, + float f1, float f2) { float death_weapon = DEATH_WEAPONOF(deathtype); - if(death_weapon) { w_deathtype = deathtype; @@ -354,11 +330,31 @@ float Obituary_WeaponDeath(entity notif_target, float murder, float deathtype, s if(death_message) { - Send_Notification_WOVA(NOTIF_ONE, notif_target, MSG_WEAPON, death_message, s1, s2, "", "", f1, f2, 0, 0); - Send_Notification_WOVA(NOTIF_ANY_EXCEPT, notif_target, MSG_INFO, msg_weapon_notifs[death_message - 1].nent_msginfo.nent_id, s1, s2, "", "", f1, f2, 0, 0); - //print(Get_Field_Value(F_INFVAL, MSG_WEAPON, death_message), "\n"); + Send_Notification_WOVA( + NOTIF_ONE, + notif_target, + MSG_MULTI, + death_message, + s1, s2, s3, "", + f1, f2, 0, 0 + ); + Send_Notification_WOVA( + NOTIF_ALL_EXCEPT, + notif_target, + MSG_INFO, + msg_multi_notifs[death_message - 1].nent_msginfo.nent_id, + s1, s2, s3, "", + f1, f2, 0, 0 + ); + } + else + { + dprint(sprintf( + "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %d!\n", + deathtype, + death_weapon + )); } - else { dprint(sprintf("Obituary_WeaponDeath(): ^1Deathtype ^7(%s-%d)^1 has no notification for weapon %d!\n", Deathtype_Name(deathtype), deathtype, death_weapon)); } return TRUE; } @@ -368,13 +364,30 @@ float Obituary_WeaponDeath(entity notif_target, float murder, float deathtype, s void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) { // Sanity check - if not(targ.classname == STR_PLAYER) { backtrace("Obituary called on non-player?!\n"); return; } + if not(IS_PLAYER(targ)) { backtrace("Obituary called on non-player?!\n"); return; } // Declarations float notif_firstblood = FALSE; + float kill_count_to_attacker, kill_count_to_target; - //dprint(sprintf("Obituary(): Deathtype = %s (%d), Attacker = %s, Inflictor = %s, Target = %s...\n", Deathtype_Name(deathtype), deathtype, attacker.netname, inflictor.netname, targ.netname)); - + // Set final information for the death + targ.death_origin = targ.origin; + if(targ != attacker) { targ.killer_origin = attacker.origin; } + string deathlocation = (autocvar_notification_server_allows_location ? NearestLocation(targ.death_origin) : ""); + + #ifdef NOTIFICATIONS_DEBUG + dprint( + sprintf( + "Obituary(%s, %s, %s, %s = %d);\n", + attacker.netname, + inflictor.netname, + targ.netname, + Deathtype_Name(deathtype), + deathtype + ) + ); + #endif + // ======= // SUICIDE // ======= @@ -384,7 +397,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) { if(deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE) { - Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, "", targ.team, 0, 0); + Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.team, 0, 0); } else { @@ -392,30 +405,31 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) { case DEATH_MIRRORDAMAGE: { - Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, "", targ.killcount, 0, 0); + Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0); break; } default: { - Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, "", targ.killcount, 0, 0); + Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0); break; } } - LogDeath("suicide", deathtype, targ, targ); - GiveFrags(attacker, targ, -1, deathtype); } } - else if not(Obituary_WeaponDeath(targ, FALSE, deathtype, targ.netname, "", targ.killcount, 0)) + else if not(Obituary_WeaponDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0)) { backtrace("SUICIDE: what the hell happened here?\n"); + return; } + LogDeath("suicide", deathtype, targ, targ); + GiveFrags(attacker, targ, -1, deathtype); } // ====== // MURDER // ====== - else if(attacker.classname == "player") + else if(IS_PLAYER(attacker)) { if(!IsDifferentTeam(attacker, targ)) { @@ -426,7 +440,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname); Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker.netname); - Send_Notification(NOTIF_ANY, world, MSG_INFO, APP_TEAM_NUM_4(targ.team, INFO_DEATH_TEAMKILL_), targ.netname, attacker.netname, targ.killcount); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(targ.team, INFO_DEATH_TEAMKILL_), targ.netname, attacker.netname, targ.killcount); // In this case, the death message will ALWAYS be "foo was betrayed by bar" // No need for specific death/weapon messages... @@ -459,12 +473,8 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) notif_firstblood = TRUE; // modify the current messages so that they too show firstblood information PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1); PlayerStats_Event(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1); - } - float kill_count_to_attacker; - float kill_count_to_target; - if(notif_firstblood) - { + // tell spree_inf and spree_cen that this is a first-blood and first-victim event kill_count_to_attacker = -1; kill_count_to_target = -2; } @@ -474,33 +484,34 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) kill_count_to_target = 0; } + float verbose_allowed = (autocvar_notification_server_allows_frag_verbose && ((autocvar_notification_server_allows_frag_verbose == 2) || inWarmupStage)); if(targ.istypefrag) { - if(attacker.FRAG_VERBOSE) + if(attacker.FRAG_VERBOSE && verbose_allowed) Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE, targ.netname, kill_count_to_attacker, (IS_BOT_CLIENT(targ) ? NO_MSG : targ.ping)); else Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG, targ.netname, kill_count_to_attacker); - if(targ.FRAG_VERBOSE) + if(targ.FRAG_VERBOSE && verbose_allowed) Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE, attacker.netname, kill_count_to_target, attacker.health, attacker.armorvalue, (IS_BOT_CLIENT(attacker) ? NO_MSG : attacker.ping)); else Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAGGED, attacker.netname, kill_count_to_target); } else { - if(attacker.FRAG_VERBOSE) + if(attacker.FRAG_VERBOSE && verbose_allowed) Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_FRAG_VERBOSE, targ.netname, kill_count_to_attacker, (IS_BOT_CLIENT(targ) ? NO_MSG : targ.ping)); else Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_FRAG, targ.netname, kill_count_to_attacker); - if(targ.FRAG_VERBOSE) + if(targ.FRAG_VERBOSE && verbose_allowed) Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED_VERBOSE, attacker.netname, kill_count_to_target, attacker.health, attacker.armorvalue, (IS_BOT_CLIENT(attacker) ? NO_MSG : attacker.ping)); else Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED, attacker.netname, kill_count_to_target); } - if not(Obituary_WeaponDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, targ.killcount, kill_count_to_attacker)) - Obituary_SpecialDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, targ.killcount, kill_count_to_attacker, 0); + if not(Obituary_WeaponDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker)) + Obituary_SpecialDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker, 0); } } @@ -527,6 +538,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, ((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage), + deathlocation, targ.killcount, 0, 0); @@ -535,7 +547,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) default: { - Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, "", targ.killcount, 0, 0); + Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0); break; } } @@ -550,9 +562,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) } } - // Set final information for the death - targ.death_origin = targ.origin; - if(targ != attacker) { targ.killer_origin = attacker.origin; } + // reset target kill count if(targ.killcount) { targ.killcount = 0; } } @@ -565,7 +575,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float { float mirrordamage; float mirrorforce; - float teamdamage0; + float complainteamdamage = 0; entity attacker_save; mirrordamage = 0; mirrorforce = 0; @@ -645,17 +655,12 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float { if(targ.classname == "player" && targ.deadflag == DEAD_NO) { - teamdamage0 = max(attacker.dmg_team, autocvar_g_teamdamage_threshold); attacker.dmg_team = attacker.dmg_team + damage; - if(attacker.dmg_team > teamdamage0 && !g_ca) - mirrordamage = autocvar_g_mirrordamage * (attacker.dmg_team - teamdamage0); + complainteamdamage = attacker.dmg_team - autocvar_g_teamdamage_threshold; + if(complainteamdamage > 0 && !g_ca) // FIXME why is g_ca ruled out here? Why not just g_mirrordamage 0 on CA servers? + mirrordamage = autocvar_g_mirrordamage * complainteamdamage; mirrorforce = autocvar_g_mirrordamage * vlen(force); - if(g_minstagib) - { - if(autocvar_g_friendlyfire == 0) - damage = 0; - } - else if(g_ca) + if(g_ca) damage = 0; else damage = autocvar_g_friendlyfire * damage; @@ -697,47 +702,11 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float attacker.lms_traveled_distance = autocvar_g_lms_campcheck_distance; } - if(targ.classname == "player") - if (g_minstagib) - { - if ((deathtype == DEATH_FALL) || - (deathtype == DEATH_DROWN) || - (deathtype == DEATH_SLIME) || - (deathtype == DEATH_LAVA) || - (!DEATH_ISWEAPON(deathtype, WEP_LASER) && damage > 0 && damage < 100)) - { - self = oldself; - return; - } - if(damage > 0) - damage = 10000; - if (targ.armorvalue && (deathtype == WEP_MINSTANEX) && damage) - { - targ.armorvalue -= 1; - centerprint(targ, strcat("^3Remaining extra lives: ",ftos(targ.armorvalue))); - damage = 0; - targ.hitsound += 1; - attacker.hitsound += 1; // TODO change this to a future specific hitsound for armor hit - } - if (DEATH_ISWEAPON(deathtype, WEP_LASER)) - { - damage = 0; - mirrordamage = 0; - if (targ != attacker) - { - if ((targ.health >= 1) && (targ.classname == "player")) - centerprint(attacker, "Secondary fire inflicts no damage!"); - force = '0 0 0'; - // keep mirrorforce - attacker = targ; - } - } - } - if not(DEATH_ISSPECIAL(deathtype)) { damage *= g_weapondamagefactor; mirrordamage *= g_weapondamagefactor; + complainteamdamage *= g_weapondamagefactor; force = force * g_weaponforcefactor; mirrorforce *= g_weaponforcefactor; } @@ -748,28 +717,33 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float frag_damage = damage; frag_force = force; frag_deathtype = deathtype; + frag_mirrordamage = mirrordamage; MUTATOR_CALLHOOK(PlayerDamage_Calculate); damage = frag_damage; + mirrordamage = frag_mirrordamage; force = frag_force; - // apply strength multiplier - if ((attacker.items & IT_STRENGTH) && !g_minstagib) + if not(g_minstagib) { - if(targ == attacker) + // apply strength multiplier + if (attacker.items & IT_STRENGTH) { - damage = damage * autocvar_g_balance_powerup_strength_selfdamage; - force = force * autocvar_g_balance_powerup_strength_selfforce; - } - else - { - damage = damage * autocvar_g_balance_powerup_strength_damage; - force = force * autocvar_g_balance_powerup_strength_force; + if(targ == attacker) + { + damage = damage * autocvar_g_balance_powerup_strength_selfdamage; + force = force * autocvar_g_balance_powerup_strength_selfforce; + } + else + { + damage = damage * autocvar_g_balance_powerup_strength_damage; + force = force * autocvar_g_balance_powerup_strength_force; + } } - } - // apply invincibility multiplier - if (targ.items & IT_INVINCIBLE && !g_minstagib) - damage = damage * autocvar_g_balance_powerup_invincible_takedamage; + // apply invincibility multiplier + if (targ.items & IT_INVINCIBLE) + damage = damage * autocvar_g_balance_powerup_invincible_takedamage; + } if (targ == attacker) { @@ -779,40 +753,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself } - if(g_runematch) - { - // apply strength rune - if (attacker.runes & RUNE_STRENGTH) - { - if(attacker.runes & CURSE_WEAK) // have both curse & rune - { - damage = damage * autocvar_g_balance_rune_strength_combo_damage; - force = force * autocvar_g_balance_rune_strength_combo_force; - } - else - { - damage = damage * autocvar_g_balance_rune_strength_damage; - force = force * autocvar_g_balance_rune_strength_force; - } - } - else if (attacker.runes & CURSE_WEAK) - { - damage = damage * autocvar_g_balance_curse_weak_damage; - force = force * autocvar_g_balance_curse_weak_force; - } - - // apply defense rune - if (targ.runes & RUNE_DEFENSE) - { - if (targ.runes & CURSE_VULNER) // have both curse & rune - damage = damage * autocvar_g_balance_rune_defense_combo_takedamage; - else - damage = damage * autocvar_g_balance_rune_defense_takedamage; - } - else if (targ.runes & CURSE_VULNER) - damage = damage * autocvar_g_balance_curse_vulner_takedamage; - } - // count the damage if(attacker) if(!targ.deadflag) @@ -845,13 +785,8 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float if not(DEATH_ISSPECIAL(deathtype)) { if(targ.classname == "player") // don't do this for vehicles - if(!g_minstagib) if(IsFlying(victim)) yoda = 1; - - if(g_minstagib) - if(victim.items & IT_STRENGTH) - yoda = 1; } } } @@ -861,7 +796,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float { attacker.typehitsound += 1; } - if(mirrordamage > 0) + if(complainteamdamage > 0) if(time > attacker.teamkill_complain) { attacker.teamkill_complain = time + 5; @@ -904,58 +839,10 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float self.event_damage (inflictor, attacker, damage, deathtype, hitloc, force); self = oldself; - if(targ.classname == "player" && attacker.classname == "player" && attacker != targ && attacker.health > 2) - { - if(g_runematch) - { - if (attacker.runes & RUNE_VAMPIRE) - { - // apply vampire rune - if (attacker.runes & CURSE_EMPATHY) // have the curse too - { - //attacker.health = attacker.health + damage * autocvar_g_balance_rune_vampire_combo_absorb; - attacker.health = bound( - autocvar_g_balance_curse_empathy_minhealth, // LA: was 3, now 40 - attacker.health + damage * autocvar_g_balance_rune_vampire_combo_absorb, - autocvar_g_balance_rune_vampire_maxhealth); // LA: was 1000, now 500 - } - else - { - //attacker.health = attacker.health + damage * autocvar_g_balance_rune_vampire_absorb; - attacker.health = bound( - attacker.health, // LA: was 3, but changed so that you can't lose health - // empathy won't let you gain health in the same way... - attacker.health + damage * autocvar_g_balance_rune_vampire_absorb, - autocvar_g_balance_rune_vampire_maxhealth); // LA: was 1000, now 500 - } - } - // apply empathy curse - else if (attacker.runes & CURSE_EMPATHY) - { - attacker.health = bound( - autocvar_g_balance_curse_empathy_minhealth, // LA: was 3, now 20 - attacker.health + damage * autocvar_g_balance_curse_empathy_takedamage, - attacker.health); - } - } - } - // apply mirror damage if any if(mirrordamage > 0 || mirrorforce > 0) { attacker = attacker_save; - if(g_minstagib) - if(mirrordamage > 0) - { - // just lose extra LIVES, don't kill the player for mirror damage - if(attacker.armorvalue > 0) - { - attacker.armorvalue = attacker.armorvalue - 1; - centerprint(attacker, strcat("^3Remaining extra lives: ",ftos(attacker.armorvalue))); - attacker.hitsound += 1; - } - mirrordamage = 0; - } force = normalize(attacker.origin + attacker.view_ofs - hitloc) * mirrorforce; Damage(attacker, inflictor, attacker, mirrordamage, DEATH_MIRRORDAMAGE, attacker.origin, force);