]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/mutators/mutator/stale_move_negation/sv_stale_move_negation.qc
Improve registry API by adding REGISTRY_MAX and REGISTRY_COUNT macros
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / stale_move_negation / sv_stale_move_negation.qc
1 #include "sv_stale_move_negation.qh"
2
3 AUTOCVAR(g_smneg, bool, false, "Stale-move negation: penalize repeated use of the same weapon");
4 AUTOCVAR(g_smneg_bonus, bool, true, "Stale-move negation: allow weapons to become stronger than their baseline");
5 AUTOCVAR(g_smneg_bonus_asymptote, float, 4, "Stale-move negation: damage = infinity at this bonus level");
6 AUTOCVAR(g_smneg_cooldown_factor, float, 1 / 4, "Stale-move negation: penalty cooldown factor");
7 REGISTER_MUTATOR(mutator_smneg, autocvar_g_smneg);
8
9 MUTATOR_HOOKFUNCTION(mutator_smneg, BuildMutatorsString) {
10     M_ARGV(0, string) = strcat(M_ARGV(0, string), ":StaleMoveNegation");
11 }
12
13 MUTATOR_HOOKFUNCTION(mutator_smneg, BuildMutatorsPrettyString) {
14     M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Stale-move negation");
15 }
16
17 .float x_smneg_weight[REGISTRY_MAX(Weapons)];
18
19 float smneg_multiplier(float weight) {
20     float a = autocvar_g_smneg_bonus_asymptote;
21     float x = max(
22         (!autocvar_g_smneg_bonus ? 0 : (-a + .1)),
23         weight / start_health
24     );
25     float z = (M_PI / 5) * a;
26     float f = (x > 0)
27         ? (atan(z / x) / (M_PI / 2))
28         : (tan(-(x / z)) + 1);
29     return f;
30 }
31
32 MUTATOR_HOOKFUNCTION(mutator_smneg, Damage_Calculate) {
33     float deathtype = M_ARGV(3, float);
34     Weapon w = DEATH_WEAPONOF(deathtype);
35     if (w == WEP_Null) return;
36
37     entity frag_attacker = M_ARGV(1, entity);
38     entity c = CS(frag_attacker);
39     float weight = c.x_smneg_weight[w.m_id];
40     float f = smneg_multiplier(weight);
41     float frag_damage = M_ARGV(4, float) = f * M_ARGV(4, float);
42     M_ARGV(6, vector) = f * M_ARGV(6, vector); // force
43
44     c.x_smneg_weight[w.m_id] = weight + frag_damage;
45     float restore = frag_damage * autocvar_g_smneg_cooldown_factor;
46     FOREACH(Weapons, it != WEP_Null && it != w, {
47         c.x_smneg_weight[it.m_id] -= restore;
48     });
49 }