X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fg_damage.qc;h=6ab29006d2226bc8fa897b446aa05a4f8de6c262;hp=76cb7861498c7820ea603c9ad2b118b4f8f48951;hb=a666e3cfb0053892d0b224c1b37475ad10484664;hpb=9334cf53b0bdefd6710e84a4ba2f5e4fb97818c9 diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 76cb786149..6ab29006d2 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -88,11 +88,11 @@ float IsFlying(entity a) vector GetHeadshotMins(entity targ) { - return '0.6 0 0' * targ.mins_x + '0 0.6 0' * targ.mins_y + '0 0 1' * (1.3 * targ.view_ofs_z - 0.3 * targ.maxs_z); + return '-0.5 0 0' * PL_HEAD_x + '0 -0.5 0' * PL_HEAD_y + '0 0 1' * (targ.maxs_z - PL_HEAD_z); } vector GetHeadshotMaxs(entity targ) { - return '0.6 0 0' * targ.maxs_x + '0 0.6 0' * targ.maxs_y + '0 0 1' * targ.maxs_z; + return '0.5 0 0' * PL_HEAD_x + '0 0.5 0' * PL_HEAD_y + '0 0 1' * targ.maxs_z; } void UpdateFrags(entity player, float f) @@ -120,18 +120,20 @@ void GiveFrags (entity attacker, entity targ, float f) { // teamkill PlayerScore_Add(attacker, SP_KILLS, -1); // or maybe add a teamkills field? + PlayerStats_Event(attacker, PLAYERSTATS_KILLS, -1); } } else { // regular frag PlayerScore_Add(attacker, SP_KILLS, 1); + PlayerStats_Event(attacker, PLAYERSTATS_KILLS, 1); } PlayerScore_Add(targ, SP_DEATHS, 1); if(g_arena || g_ca) - if(cvar("g_arena_roundbased")) + if(autocvar_g_arena_roundbased) return; if(targ != attacker) // not for suicides @@ -229,7 +231,7 @@ string AppendItemcodes(string s, entity player) void LogDeath(string mode, float deathtype, entity killer, entity killed) { string s; - if(!cvar("sv_eventlog")) + if(!autocvar_sv_eventlog) return; s = strcat(":kill:", mode); s = strcat(s, ":", ftos(killer.playerid)); @@ -278,7 +280,7 @@ void Send_CSQC_Centerprint(entity e, string s1, string s2, float msg, float type void Obituary (entity attacker, entity inflictor, entity targ, float deathtype) { string s, a, msg; - float p, w, type; + float w, type; if (targ.classname == "player" || targ.classname == "corpse") { @@ -293,7 +295,8 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype) { if (deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE) msg = ColoredTeamName(targ.team); // TODO: check if needed? - Send_CSQC_Centerprint(targ, msg, "", deathtype, MSG_SUICIDE); + if(!g_cts) // no "killed your own dumb self" message in CTS + Send_CSQC_Centerprint(targ, msg, "", deathtype, MSG_SUICIDE); if(deathtype != DEATH_TEAMCHANGE && deathtype != DEATH_QUIET) { @@ -342,7 +345,6 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype) } else { - string blood_message, victim_message; if (!checkrules_firstblood) { checkrules_firstblood = TRUE; @@ -352,7 +354,7 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype) Send_CSQC_Centerprint(targ, "", "", KILL_FIRST_VICTIM, MSG_KILL); } - if((cvar("sv_fragmessage_information_typefrag")) && (targ.BUTTON_CHAT)) { + if((autocvar_sv_fragmessage_information_typefrag) && (targ.BUTTON_CHAT)) { Send_CSQC_Centerprint(attacker, s, GetAdvancedDeathReports(targ), KILL_TYPEFRAG, MSG_KILL); Send_CSQC_Centerprint(targ, a, GetAdvancedDeathReports(attacker), KILL_TYPEFRAGGED, MSG_KILL); } else { @@ -536,32 +538,32 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float damage = 0; force = '0 0 0'; } - else if(attacker.team == targ.team) + else if(teams_matter && attacker.team == targ.team) { - if(teamplay == 1) + if(autocvar_teamplay_mode == 1) damage = 0; else if(attacker != targ) { - if(teamplay == 3) + if(autocvar_teamplay_mode == 3) damage = 0; - else if(teamplay == 4) + else if(autocvar_teamplay_mode == 4) { if(targ.classname == "player" && targ.deadflag == DEAD_NO) { - teamdamage0 = max(attacker.dmg_team, cvar("g_teamdamage_threshold")); + teamdamage0 = max(attacker.dmg_team, autocvar_g_teamdamage_threshold); attacker.dmg_team = attacker.dmg_team + damage; if(attacker.dmg_team > teamdamage0 && !g_ca) - mirrordamage = cvar("g_mirrordamage") * (attacker.dmg_team - teamdamage0); - mirrorforce = cvar("g_mirrordamage") * vlen(force); + mirrordamage = autocvar_g_mirrordamage * (attacker.dmg_team - teamdamage0); + mirrorforce = autocvar_g_mirrordamage * vlen(force); if(g_minstagib) { - if(cvar("g_friendlyfire") == 0) + if(autocvar_g_friendlyfire == 0) damage = 0; } else if(g_ca) damage = 0; else - damage = cvar("g_friendlyfire") * damage; + damage = autocvar_g_friendlyfire * damage; // mirrordamage will be used LATER } else @@ -575,8 +577,8 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float if(attacker.classname == "player") if(attacker != targ) { - targ.lms_traveled_distance = cvar("g_lms_campcheck_distance"); - attacker.lms_traveled_distance = cvar("g_lms_campcheck_distance"); + targ.lms_traveled_distance = autocvar_g_lms_campcheck_distance; + attacker.lms_traveled_distance = autocvar_g_lms_campcheck_distance; } if(targ.classname == "player") @@ -624,32 +626,42 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float force = force * g_weaponforcefactor; mirrorforce *= g_weaponforcefactor; } - + + // should this be changed at all? If so, in what way? + frag_attacker = attacker; + frag_target = targ; + frag_damage = damage; + frag_force = force; + frag_deathtype = deathtype; + MUTATOR_CALLHOOK(PlayerDamage_Calculate); + damage = frag_damage; + force = frag_force; + // apply strength multiplier if ((attacker.items & IT_STRENGTH) && !g_minstagib) { if(targ == attacker) { - damage = damage * cvar("g_balance_powerup_strength_selfdamage"); - force = force * cvar("g_balance_powerup_strength_selfforce"); + damage = damage * autocvar_g_balance_powerup_strength_selfdamage; + force = force * autocvar_g_balance_powerup_strength_selfforce; } else { - damage = damage * cvar("g_balance_powerup_strength_damage"); - force = force * cvar("g_balance_powerup_strength_force"); + 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 * cvar("g_balance_powerup_invincible_takedamage"); + damage = damage * autocvar_g_balance_powerup_invincible_takedamage; if (targ == attacker) { - if(g_ca || (g_cts && !cvar("g_cts_selfdamage"))) + if(g_ca || (g_cts && !autocvar_g_cts_selfdamage)) damage = 0; else - damage = damage * cvar("g_balance_selfdamagepercent"); // Partial damage if the attacker hits himself + damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself } // CTF: reduce damage/force @@ -657,8 +669,8 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float if(targ == attacker) if(targ.flagcarried) { - damage = damage * cvar("g_ctf_flagcarrier_selfdamage"); - force = force * cvar("g_ctf_flagcarrier_selfforce"); + damage = damage * autocvar_g_ctf_flagcarrier_selfdamage; + force = force * autocvar_g_ctf_flagcarrier_selfforce; } if(g_runematch) @@ -668,31 +680,31 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float { if(attacker.runes & CURSE_WEAK) // have both curse & rune { - damage = damage * cvar("g_balance_rune_strength_combo_damage"); - force = force * cvar("g_balance_rune_strength_combo_force"); + damage = damage * autocvar_g_balance_rune_strength_combo_damage; + force = force * autocvar_g_balance_rune_strength_combo_force; } else { - damage = damage * cvar("g_balance_rune_strength_damage"); - force = force * cvar("g_balance_rune_strength_force"); + damage = damage * autocvar_g_balance_rune_strength_damage; + force = force * autocvar_g_balance_rune_strength_force; } } else if (attacker.runes & CURSE_WEAK) { - damage = damage * cvar("g_balance_curse_weak_damage"); - force = force * cvar("g_balance_curse_weak_force"); + 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 * cvar("g_balance_rune_defense_combo_takedamage"); + damage = damage * autocvar_g_balance_rune_defense_combo_takedamage; else - damage = damage * cvar("g_balance_rune_defense_takedamage"); + damage = damage * autocvar_g_balance_rune_defense_takedamage; } else if (targ.runes & CURSE_VULNER) - damage = damage * cvar("g_balance_curse_vulner_takedamage"); + damage = damage * autocvar_g_balance_curse_vulner_takedamage; } // count the damage @@ -728,7 +740,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float { if(damage > 0) { - if(attacker.weapon != WEP_ELECTRO && attacker.weapon != WEP_LASER || ((attacker.weapon == WEP_ELECTRO && cvar("g_balance_electro_lightning") || attacker.weapon == WEP_LASER) && attacker.prevhitsound + cvar("sv_hitsound_antispam_time") < time)) + if(attacker.weapon != WEP_ELECTRO && attacker.weapon != WEP_LASER || ((attacker.weapon == WEP_ELECTRO && autocvar_g_balance_electro_lightning || attacker.weapon == WEP_LASER) && attacker.prevhitsound + autocvar_sv_hitsound_antispam_time < time)) { if(targ.BUTTON_CHAT) attacker.typehitsound += 1; @@ -753,6 +765,8 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float if(deathtype & HITTYPE_HEADSHOT) headshot = 1; } + if(g_ca) + PlayerScore_Add(attacker, SP_SCORE, damage * autocvar_g_ca_damage2score_multiplier); } } else @@ -788,13 +802,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float if(targ.classname == "player" && attacker.classname == "player" && attacker != targ && attacker.health > 2) { - // Savage: vampire mode - if (g_vampire) - if (!g_minstagib) - if (time >= self.spawnshieldtime) - { - attacker.health += damage; - } if(g_runematch) { if (attacker.runes & RUNE_VAMPIRE) @@ -802,28 +809,28 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float // apply vampire rune if (attacker.runes & CURSE_EMPATHY) // have the curse too { - //attacker.health = attacker.health + damage * cvar("g_balance_rune_vampire_combo_absorb"); + //attacker.health = attacker.health + damage * autocvar_g_balance_rune_vampire_combo_absorb; attacker.health = bound( - cvar("g_balance_curse_empathy_minhealth"), // LA: was 3, now 40 - attacker.health + damage * cvar("g_balance_rune_vampire_combo_absorb"), - cvar("g_balance_rune_vampire_maxhealth")); // LA: was 1000, now 500 + 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 * cvar("g_balance_rune_vampire_absorb"); + //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 * cvar("g_balance_rune_vampire_absorb"), - cvar("g_balance_rune_vampire_maxhealth")); // LA: was 1000, now 500 + 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( - cvar("g_balance_curse_empathy_minhealth"), // LA: was 3, now 20 - attacker.health + damage * cvar("g_balance_curse_empathy_takedamage"), + autocvar_g_balance_curse_empathy_minhealth, // LA: was 3, now 20 + attacker.health + damage * autocvar_g_balance_curse_empathy_takedamage, attacker.health); } } @@ -850,19 +857,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float } } -void Damage_RecordDamage(entity attacker, float deathtype, float damage) -{ - float weaponid; - weaponid = DEATH_WEAPONOF(deathtype); - - if not(inWarmupStage) - if (weaponid) - if ((clienttype(attacker) == CLIENTTYPE_REAL) | (clienttype(attacker) == CLIENTTYPE_BOT)) { - attacker.stats_hit[weaponid - 1] += damage; - attacker.stat_hit = weaponid + 64 * floor(attacker.stats_hit[weaponid - 1]); - } -} - float RadiusDamage_running; float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity ignore, float forceintensity, float deathtype, entity directhitentity) // Returns total damage applies to creatures @@ -881,25 +875,17 @@ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float e float tfloorforce; float stat_damagedone; - float stat_maxdamage; if(RadiusDamage_running) { - string save; - print("RadiusDamage called recursively!\n"); - print("Expect stuff to go HORRIBLY wrong.\n"); - print("Causing a stack trace...\n"); - save = cvar_string("prvm_backtraceforwarnings"); - cvar_set("prvm_backtraceforwarnings", "1"); - fclose(-1); // calls VM_Warning - cvar_set("prvm_backtraceforwarnings", save); + backtrace("RadiusDamage called recursively! Expect stuff to go HORRIBLY wrong."); return 0; } RadiusDamage_running = 1; - tfloordmg = cvar("g_throughfloor_damage"); - tfloorforce = cvar("g_throughfloor_force"); + tfloordmg = autocvar_g_throughfloor_damage; + tfloorforce = autocvar_g_throughfloor_force; blastorigin = (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5); total_damage_to_creatures = 0; @@ -919,7 +905,6 @@ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float e } stat_damagedone = 0; - stat_maxdamage = 0; targ = WarpZone_FindRadius (blastorigin, rad, FALSE); while (targ) @@ -992,6 +977,39 @@ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float e finaldmg = finaldmg * a; a = bound(0, tfloorforce + (1-tfloorforce) * hitratio, 1); force = force * a; + + // laser force adjustments :P + if(DEATH_WEAPONOF(deathtype) == WEP_LASER) + { + vector vel; + + float force_zscale; + float force_velocitybiasramp; + float force_velocitybias; + + force_velocitybiasramp = autocvar_sv_maxspeed; + if(deathtype & HITTYPE_SECONDARY) + { + force_zscale = autocvar_g_balance_laser_secondary_force_zscale; + force_velocitybias = autocvar_g_balance_laser_secondary_force_velocitybias; + } + else + { + force_zscale = autocvar_g_balance_laser_primary_force_zscale; + force_velocitybias = autocvar_g_balance_laser_primary_force_velocitybias; + } + + vel = targ.velocity; + vel_z = 0; + vel = normalize(vel) * bound(0, vlen(vel) / force_velocitybiasramp, 1) * force_velocitybias; + force = + vlen(force) + * + normalize(normalize(force) + vel); + + force_z *= force_zscale; + } + //if (targ == attacker) //{ // print("hits ", ftos(hits), " / ", ftos(total)); @@ -1004,14 +1022,8 @@ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float e { total_damage_to_creatures += finaldmg; - if(targ.flags & FL_CLIENT) - if(targ.deadflag == DEAD_NO) - if(targ != attacker) - if(!teamplay || targ.team != attacker.team) - { + if(accuracy_isgooddamage(attacker, targ)) stat_damagedone += finaldmg; - stat_maxdamage += coredamage; - } } if(targ == directhitentity || DEATH_ISSPECIAL(deathtype)) @@ -1027,7 +1039,8 @@ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float e RadiusDamage_running = 0; - Damage_RecordDamage(attacker, deathtype, min(stat_maxdamage, stat_damagedone)); + if(!DEATH_ISSPECIAL(deathtype)) + accuracy_add(attacker, DEATH_WEAPONOFWEAPONDEATH(deathtype), 0, min(coredamage, stat_damagedone)); return total_damage_to_creatures; } @@ -1130,6 +1143,8 @@ float Fire_AddDamage(entity e, entity o, float d, float t, float dt) e.fire_hitsound = FALSE; } } + if(accuracy_isgooddamage(o, e)) + accuracy_add(o, DEATH_WEAPONOFWEAPONDEATH(dt), 0, max(0, totaldamage - mindamage)); return max(0, totaldamage - mindamage); // can never be negative, but to make sure } else @@ -1142,6 +1157,8 @@ float Fire_AddDamage(entity e, entity o, float d, float t, float dt) e.fire_deathtype = dt; e.fire_owner = o; e.fire_hitsound = FALSE; + if(accuracy_isgooddamage(o, e)) + accuracy_add(o, DEATH_WEAPONOFWEAPONDEATH(dt), 0, d); return d; } } @@ -1154,9 +1171,7 @@ void Fire_ApplyDamage(entity e) if not(Fire_IsBurning(e)) return; - o = e.owner; - while(o.owner) - o = o.owner; + for(t = 0, o = e.owner; o.owner && t < 16; o = o.owner, ++t); if(clienttype(o) == CLIENTTYPE_NOTACLIENT) o = e.fire_owner; @@ -1178,8 +1193,6 @@ void Fire_ApplyDamage(entity e) } e.fire_hitsound = TRUE; - Damage_RecordDamage(e.fire_owner, e.fire_deathtype, d); - if not(IS_INDEPENDENT_PLAYER(e)) FOR_EACH_PLAYER(other) if(e != other) { @@ -1188,8 +1201,8 @@ void Fire_ApplyDamage(entity e) if not(IS_INDEPENDENT_PLAYER(other)) if(boxesoverlap(e.absmin, e.absmax, other.absmin, other.absmax)) { - t = cvar("g_balance_firetransfer_time") * (e.fire_endtime - time); - d = cvar("g_balance_firetransfer_damage") * e.fire_damagepersec * t; + t = autocvar_g_balance_firetransfer_time * (e.fire_endtime - time); + d = autocvar_g_balance_firetransfer_damage * e.fire_damagepersec * t; Fire_AddDamage(other, o, d, t, DEATH_FIRE); } }