]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/gamemodes/gamemode/mayhem/sv_mayhem.qc
ded24baaaf1cb57b3a3e02ae37dc7f7d45c6a5c1
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / gamemodes / gamemode / mayhem / sv_mayhem.qc
1 #include "sv_mayhem.qh"
2
3 bool autocvar_g_mayhem_regenerate;
4 string autocvar_g_mayhem_weaponarena;
5 bool autocvar_g_mayhem_powerups;
6 bool autocvar_g_mayhem_selfdamage;
7 int autocvar_g_mayhem_scoringmethod;
8
9 void mayhem_DelayedInit(entity this)
10 {
11         return;
12 }
13
14 void mayhem_Initialize()
15 {
16         if(autocvar_g_mayhem_point_limit > 0 && autocvar_g_mayhem_fraglimit > 0)
17                 mayhempointmultiplier = autocvar_g_mayhem_point_limit / autocvar_g_mayhem_fraglimit;
18
19         GameRules_limit_score(autocvar_g_mayhem_point_limit);
20
21         InitializeEntity(NULL, mayhem_DelayedInit, INITPRIO_GAMETYPE);
22 }
23
24 MUTATOR_HOOKFUNCTION(mayhem, Scores_CountFragsRemaining)
25 {
26         // announce remaining frags
27         return true;
28 }
29
30 MUTATOR_HOOKFUNCTION(mayhem, SetStartItems)
31 {
32         start_items       &= ~(IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS);
33         start_health       = warmup_start_health       = cvar("g_mayhem_start_health");
34         start_armorvalue   = warmup_start_armorvalue   = cvar("g_mayhem_start_armor");
35         start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_mayhem_start_ammo_shells");
36         start_ammo_nails   = warmup_start_ammo_nails   = cvar("g_mayhem_start_ammo_nails");
37         start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_mayhem_start_ammo_rockets");
38         start_ammo_cells   = warmup_start_ammo_cells   = cvar("g_mayhem_start_ammo_cells");
39         start_ammo_plasma  = warmup_start_ammo_plasma  = cvar("g_mayhem_start_ammo_plasma");
40         start_ammo_fuel    = warmup_start_ammo_fuel    = cvar("g_mayhem_start_ammo_fuel");
41 }
42
43 //this hook also enables rotting, as players spawn with more hp and armor than what default rot limits are set to this is a bad idea as of now
44 MUTATOR_HOOKFUNCTION(mayhem, PlayerRegen)
45 {
46         if(autocvar_g_mayhem_regenerate)
47                 return false;
48         return true;
49 }
50
51 MUTATOR_HOOKFUNCTION(mayhem, ForbidThrowCurrentWeapon)
52 {
53         return true;
54 }
55
56 MUTATOR_HOOKFUNCTION(mayhem, SetWeaponArena)
57 {
58         if (M_ARGV(0, string) == "0" || M_ARGV(0, string) == "")
59                 M_ARGV(0, string) = autocvar_g_mayhem_weaponarena;
60 }
61
62 MUTATOR_HOOKFUNCTION(mayhem, FilterItem)
63 {
64         entity item = M_ARGV(0, entity);
65         if (autocvar_g_powerups == 1){
66                 if (item.flags & FL_POWERUP){
67                         return false;
68                 } 
69         }
70         else if (autocvar_g_powerups == -1){
71                 if (item.flags & FL_POWERUP){
72                         if (autocvar_g_mayhem_powerups){
73                                 return false;
74                         } 
75                 } 
76         }
77         if (autocvar_g_pickup_items <= 0)
78                 return true;
79 }
80
81 MUTATOR_HOOKFUNCTION(mayhem, Damage_Calculate)
82 {
83         entity frag_attacker = M_ARGV(1, entity);
84         entity frag_target = M_ARGV(2, entity);
85         float frag_deathtype = M_ARGV(3, float);
86         float frag_damage = M_ARGV(4, float);
87
88         if ((autocvar_g_mayhem_selfdamage == 0 && frag_target == frag_attacker) || frag_deathtype == DEATH_FALL.m_id)
89                 frag_damage = 0;
90
91         M_ARGV(4, float) = frag_damage;
92 }
93
94 MUTATOR_HOOKFUNCTION(mayhem, PlayerDamage_SplitHealthArmor)
95 {
96         switch(autocvar_g_mayhem_scoringmethod)
97         {
98                 //frags only
99                 case 2:
100                 {
101                         return;
102                 }
103                 
104                 //damage only
105                 case 3:
106                 {
107                         entity frag_attacker = M_ARGV(1, entity);
108                         entity frag_target = M_ARGV(2, entity);
109                         float frag_deathtype = M_ARGV(6, float);
110                         float frag_damage = M_ARGV(7, float);
111                         float damage_take = bound(0, M_ARGV(4, float), GetResource(frag_target, RES_HEALTH));
112                         float damage_save = bound(0, M_ARGV(5, float), GetResource(frag_target, RES_ARMOR));
113
114                         float excess = max(0, frag_damage - damage_take - damage_save);
115
116                         if (frag_target != frag_attacker && IS_PLAYER(frag_attacker))
117                                 GameRules_scoring_add_team(frag_attacker, SCORE, (frag_damage - excess) * (1/(start_health + start_armorvalue)));
118                         
119                         if (frag_target == frag_attacker && IS_PLAYER(frag_attacker))
120                                 GameRules_scoring_add_team(frag_target, SCORE, (-1 * (frag_damage - excess)) * (1/(start_health + start_armorvalue)));
121                 
122                         //handle hazard suiciding, check first if player has a registered attacker who most likely pushed them there
123                         if (!IS_PLAYER(frag_attacker) && (
124                                 frag_deathtype == DEATH_DROWN.m_id ||
125                                 frag_deathtype == DEATH_HURTTRIGGER.m_id ||
126                                 frag_deathtype == DEATH_CAMP.m_id ||
127                                 frag_deathtype == DEATH_LAVA.m_id ||
128                                 frag_deathtype == DEATH_SLIME.m_id))
129                                         GameRules_scoring_add_team(frag_target, SCORE, (-1 * (frag_damage - excess)) * (1/(start_health + start_armorvalue)));
130                                 
131                         //when hp and armor values are checked when suiciding for some reason they are 0.9 hp and 0 armor regardless that player suicided with 200+200
132                         //AFAIK dynamic hp value checking is not possible, hardcoded start hp and armor
133                         //FIXME: ^ , might require fixing hp+a check for suicides as a whole
134                         if (frag_deathtype == DEATH_KILL.m_id)
135                                 GameRules_scoring_add_team(frag_target, SCORE, (-1 * (start_health + start_armorvalue)) * (1/(start_health + start_armorvalue)));
136                         return;
137                 }
138                 
139                 //combined damage and frags
140                 default:
141                 case 1:
142                 {
143                         entity frag_attacker = M_ARGV(1, entity);
144                         entity frag_target = M_ARGV(2, entity);
145                         float frag_deathtype = M_ARGV(6, float);
146                         float frag_damage = M_ARGV(7, float);
147                         float damage_take = bound(0, M_ARGV(4, float), GetResource(frag_target, RES_HEALTH));
148                         float damage_save = bound(0, M_ARGV(5, float), GetResource(frag_target, RES_ARMOR));
149
150                         float excess = max(0, frag_damage - damage_take - damage_save);
151
152                         if (frag_target != frag_attacker && IS_PLAYER(frag_attacker))
153                                 GameRules_scoring_add_team(frag_attacker, SCORE, (frag_damage - excess) * 0.75 * mayhempointmultiplier * (1/(start_health + start_armorvalue)));
154                         
155                         if (frag_target == frag_attacker && IS_PLAYER(frag_attacker))
156                                 GameRules_scoring_add_team(frag_target, SCORE, (-1 * (frag_damage - excess)) * 0.75 * mayhempointmultiplier * (1/(start_health + start_armorvalue)));
157                 
158                         //handle hazard suiciding, check first if player has a registered attacker who most likely pushed them there
159                         if (!IS_PLAYER(frag_attacker) && (
160                                 frag_deathtype == DEATH_DROWN.m_id ||
161                                 frag_deathtype == DEATH_HURTTRIGGER.m_id ||
162                                 frag_deathtype == DEATH_CAMP.m_id ||
163                                 frag_deathtype == DEATH_LAVA.m_id ||
164                                 frag_deathtype == DEATH_SLIME.m_id))
165                                         GameRules_scoring_add_team(frag_target, SCORE, (-1 * (frag_damage - excess)) * 0.75 * mayhempointmultiplier * (1/(start_health + start_armorvalue)));
166                                 
167                         //when hp and armor values are checked when suiciding for some reason they are 0.9 hp and 0 armor regardless that player suicided with 200+200
168                         //AFAIK dynamic hp value checking is not possible, hardcoded start hp and armor
169                         //FIXME: ^ , might require fixing hp+a check for suicides as a whole
170                         if (frag_deathtype == DEATH_KILL.m_id)
171                                 GameRules_scoring_add_team(frag_target, SCORE, (-1 * (start_health + start_armorvalue)) * 0.75 * mayhempointmultiplier * (1/(start_health + start_armorvalue)));
172                         return;
173                 }
174         }
175 }
176
177 MUTATOR_HOOKFUNCTION(mayhem, GiveFragsForKill, CBC_ORDER_FIRST)
178 {
179         switch(autocvar_g_mayhem_scoringmethod)
180         {
181                 //frags only
182                 case 2:
183                 {
184                                                                                                                 //fix 999 score from 30 kills for example
185                         M_ARGV(2, float) = 1 * mayhempointmultiplier * 1.0001;
186                         return true;
187                 }
188                 
189                 //damage only
190                 case 3:
191                 {
192                         M_ARGV(2, float) = 0;
193                         return true;
194                 }
195                 
196                 //combined damage and frags
197                 default:
198                 case 1:
199                 {
200                         M_ARGV(2, float) = 0.25 * mayhempointmultiplier * 1.0001;
201                         return true;
202                 }
203         }
204 }