]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/mutators/mutator_nix.qc
Mario scored against another gamemode specific check
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / mutator_nix.qc
1
2 #include "mutator.qh"
3
4 float g_nix_with_blaster;
5 // WEAPONTODO
6 int nix_weapon;
7 float nix_nextchange;
8 float nix_nextweapon;
9 .float nix_lastchange_id;
10 .float nix_lastinfotime;
11 .float nix_nextincr;
12
13 bool NIX_CanChooseWeapon(int wpn);
14
15 REGISTER_MUTATOR(nix, cvar("g_nix") && !cvar("g_instagib") && !cvar("g_overkill"))
16 {
17         MUTATOR_ONADD
18         {
19                 g_nix_with_blaster = autocvar_g_nix_with_blaster;
20
21                 nix_nextchange = 0;
22                 nix_nextweapon = 0;
23
24                 for (int i = WEP_FIRST; i <= WEP_LAST; ++i)
25                         if (NIX_CanChooseWeapon(i)) {
26                                 Weapon w = get_weaponinfo(i);
27                                 w.wr_init(w);
28                         }
29         }
30
31         MUTATOR_ONROLLBACK_OR_REMOVE
32         {
33                 // nothing to roll back
34         }
35
36         MUTATOR_ONREMOVE
37         {
38                 // as the PlayerSpawn hook will no longer run, NIX is turned off by this!
39                 entity e;
40                 FOR_EACH_PLAYER(e) if(e.deadflag == DEAD_NO)
41                 {
42                         e.ammo_cells = start_ammo_cells;
43                         e.ammo_plasma = start_ammo_plasma;
44                         e.ammo_shells = start_ammo_shells;
45                         e.ammo_nails = start_ammo_nails;
46                         e.ammo_rockets = start_ammo_rockets;
47                         e.ammo_fuel = start_ammo_fuel;
48                         e.weapons = start_weapons;
49                         if(!client_hasweapon(e, e.weapon, true, false))
50                                 e.switchweapon = w_getbestweapon(self);
51                 }
52         }
53
54         return 0;
55 }
56
57 bool NIX_CanChooseWeapon(int wpn)
58 {
59         entity e = get_weaponinfo(wpn);
60         if(!e.weapon) // skip dummies
61                 return false;
62         if(g_weaponarena)
63         {
64                 if(!(g_weaponarena_weapons & WepSet_FromWeapon(wpn)))
65                         return false;
66         }
67         else
68         {
69                 if(wpn == WEP_BLASTER.m_id && g_nix_with_blaster)
70                         return false;
71                 if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
72                         return false;
73                 if (!(e.spawnflags & WEP_FLAG_NORMAL))
74                         return false;
75         }
76         return true;
77 }
78 void NIX_ChooseNextWeapon()
79 {
80         float j;
81         RandomSelection_Init();
82         for(j = WEP_FIRST; j <= WEP_LAST; ++j)
83                 if(NIX_CanChooseWeapon(j))
84                         RandomSelection_Add(world, j, string_null, 1, (j != nix_weapon));
85         nix_nextweapon = RandomSelection_chosen_float;
86 }
87
88 void NIX_GiveCurrentWeapon()
89 {SELFPARAM();
90         float dt;
91
92         if(!nix_nextweapon)
93                 NIX_ChooseNextWeapon();
94
95         dt = ceil(nix_nextchange - time);
96
97         if(dt <= 0)
98         {
99                 nix_weapon = nix_nextweapon;
100                 nix_nextweapon = 0;
101                 if (!nix_nextchange) // no round played yet?
102                         nix_nextchange = time; // start the first round now!
103                 else
104                         nix_nextchange = time + autocvar_g_balance_nix_roundtime;
105                 // Weapon w = get_weaponinfo(nix_weapon);
106                 // w.wr_init(w); // forget it, too slow
107         }
108
109         // get weapon info
110         entity e = get_weaponinfo(nix_weapon);
111
112         if(nix_nextchange != self.nix_lastchange_id) // this shall only be called once per round!
113         {
114                 self.ammo_shells = self.ammo_nails = self.ammo_rockets = self.ammo_cells = self.ammo_plasma = self.ammo_fuel = 0;
115
116                 if(self.items & IT_UNLIMITED_WEAPON_AMMO)
117                 {
118                         switch(e.ammo_field)
119                         {
120                                 case ammo_shells:  self.ammo_shells  = autocvar_g_pickup_shells_max;  break;
121                                 case ammo_nails:   self.ammo_nails   = autocvar_g_pickup_nails_max;   break;
122                                 case ammo_rockets: self.ammo_rockets = autocvar_g_pickup_rockets_max; break;
123                                 case ammo_cells:   self.ammo_cells   = autocvar_g_pickup_cells_max;   break;
124                                 case ammo_plasma:  self.ammo_plasma  = autocvar_g_pickup_plasma_max;   break;
125                                 case ammo_fuel:    self.ammo_fuel    = autocvar_g_pickup_fuel_max;    break;
126                         }
127                 }
128                 else
129                 {
130                         switch(e.ammo_field)
131                         {
132                                 case ammo_shells:  self.ammo_shells  = autocvar_g_balance_nix_ammo_shells;  break;
133                                 case ammo_nails:   self.ammo_nails   = autocvar_g_balance_nix_ammo_nails;   break;
134                                 case ammo_rockets: self.ammo_rockets = autocvar_g_balance_nix_ammo_rockets; break;
135                                 case ammo_cells:   self.ammo_cells   = autocvar_g_balance_nix_ammo_cells;   break;
136                                 case ammo_plasma:  self.ammo_plasma  = autocvar_g_balance_nix_ammo_plasma;   break;
137                                 case ammo_fuel:    self.ammo_fuel    = autocvar_g_balance_nix_ammo_fuel;    break;
138                         }
139                 }
140
141                 self.nix_nextincr = time + autocvar_g_balance_nix_incrtime;
142                 if(dt >= 1 && dt <= 5)
143                         self.nix_lastinfotime = -42;
144                 else
145                         Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_NEWWEAPON, nix_weapon);
146
147                 Weapon w = get_weaponinfo(nix_weapon);
148                 w.wr_resetplayer(w);
149
150                 // all weapons must be fully loaded when we spawn
151                 if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
152                         self.(weapon_load[nix_weapon]) = e.reloading_ammo;
153
154                 // vortex too
155                 if(WEP_CVAR(vortex, charge))
156                 {
157                         if(WEP_CVAR_SEC(vortex, chargepool))
158                                 self.vortex_chargepool_ammo = 1;
159                         self.vortex_charge = WEP_CVAR(vortex, charge_start);
160                 }
161
162                 // set last change info
163                 self.nix_lastchange_id = nix_nextchange;
164         }
165         if(self.nix_lastinfotime != dt)
166         {
167                 self.nix_lastinfotime = dt; // initial value 0 should count as "not seen"
168                 if(dt >= 1 && dt <= 5)
169                         Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_COUNTDOWN, nix_nextweapon, dt);
170         }
171
172         if(!(self.items & IT_UNLIMITED_WEAPON_AMMO) && time > self.nix_nextincr)
173         {
174                 switch(e.ammo_field)
175                 {
176                         case ammo_shells:  self.ammo_shells  += autocvar_g_balance_nix_ammoincr_shells;  break;
177                         case ammo_nails:   self.ammo_nails   += autocvar_g_balance_nix_ammoincr_nails;   break;
178                         case ammo_rockets: self.ammo_rockets += autocvar_g_balance_nix_ammoincr_rockets; break;
179                         case ammo_cells:   self.ammo_cells   += autocvar_g_balance_nix_ammoincr_cells;   break;
180                         case ammo_plasma:  self.ammo_plasma  += autocvar_g_balance_nix_ammoincr_plasma;   break;
181                         case ammo_fuel:    self.ammo_fuel    += autocvar_g_balance_nix_ammoincr_fuel;    break;
182                 }
183
184                 self.nix_nextincr = time + autocvar_g_balance_nix_incrtime;
185         }
186
187         self.weapons = '0 0 0';
188         if(g_nix_with_blaster)
189                 self.weapons |= WEPSET(BLASTER);
190         self.weapons |= WepSet_FromWeapon(nix_weapon);
191
192         if(self.switchweapon != nix_weapon)
193                 if(!client_hasweapon(self, self.switchweapon, true, false))
194                         if(client_hasweapon(self, nix_weapon, true, false))
195                                 W_SwitchWeapon(nix_weapon);
196 }
197
198 MUTATOR_HOOKFUNCTION(nix, ForbidThrowCurrentWeapon)
199 {
200         return 1; // no throwing in NIX
201 }
202
203 MUTATOR_HOOKFUNCTION(nix, BuildMutatorsString)
204 {
205         ret_string = strcat(ret_string, ":NIX");
206         return 0;
207 }
208
209 MUTATOR_HOOKFUNCTION(nix, BuildMutatorsPrettyString)
210 {
211         ret_string = strcat(ret_string, ", NIX");
212         return 0;
213 }
214
215 MUTATOR_HOOKFUNCTION(nix, FilterItem)
216 {SELFPARAM();
217         switch (self.items)
218         {
219                 case ITEM_HealthSmall.m_itemid:
220                 case ITEM_HealthMedium.m_itemid:
221                 case ITEM_HealthLarge.m_itemid:
222                 case ITEM_HealthMega.m_itemid:
223                 case ITEM_ArmorSmall.m_itemid:
224                 case ITEM_ArmorMedium.m_itemid:
225                 case ITEM_ArmorLarge.m_itemid:
226                 case ITEM_ArmorMega.m_itemid:
227                         if (autocvar_g_nix_with_healtharmor)
228                                 return 0;
229                         break;
230                 case ITEM_Strength.m_itemid:
231                 case ITEM_Shield.m_itemid:
232                         if (autocvar_g_nix_with_powerups)
233                                 return 0;
234                         break;
235         }
236
237         return 1; // delete all other items
238 }
239
240 MUTATOR_HOOKFUNCTION(nix, OnEntityPreSpawn)
241 {SELFPARAM();
242         if(self.classname == "target_items") // items triggers cannot work in nix (as they change weapons/ammo)
243                 return 1;
244         return 0;
245 }
246
247 MUTATOR_HOOKFUNCTION(nix, PlayerPreThink)
248 {SELFPARAM();
249         if(!intermission_running)
250         if(self.deadflag == DEAD_NO)
251         if(IS_PLAYER(self))
252                 NIX_GiveCurrentWeapon();
253         return 0;
254 }
255
256 MUTATOR_HOOKFUNCTION(nix, PlayerSpawn)
257 {SELFPARAM();
258         self.nix_lastchange_id = -1;
259         NIX_GiveCurrentWeapon(); // overrides the weapons you got when spawning
260         self.items |= IT_UNLIMITED_SUPERWEAPONS;
261         return 0;
262 }
263
264 MUTATOR_HOOKFUNCTION(nix, SetModname, CBC_ORDER_LAST)
265 {
266         modname = "NIX";
267         return 0;
268 }