Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
mutatortab.qc
Go to the documentation of this file.
1#include "mutatortab.qh"
2
3#include "checkbox.qh"
5#include "mixedslider.qh"
6#include "radiobutton.qh"
7#include "slider.qh"
8#include "textlabel.qh"
13#include <common/weapons/all.qh>
14
15#ifdef MENU_INCLUDE_OVERKILL
18#endif
19
24
26{
27 entity e;
28 me.TR(me);
29 me.TDempty(me, 1.75);
30 me.TD(me, 1, 2.25, e = makeXonoticCheckBox(0, me.message, _("Enable")));
32 return e;
33}
34
35// functions to add toggleableItems
37{
39 me.disabled = !me.parent.canEnable(me.parent, false);
40}
42{
44 me.(toggleableItems[me.toggleableItemsCount++]) = e;
45}
47{
49 me.disabled = !me.parent.canEnable(me.parent, false);
50}
52{
54 me.(toggleableItems[me.toggleableItemsCount++]) = e;
55}
57{
58 me.disabled = !me.parent.canEnable(me.parent, false);
59}
61{
63 me.(toggleableItems[me.toggleableItemsCount++]) = e;
64}
65
66
67// Weapon arena "mutator"
69{
70 switch (val)
71 {
72 case "off": case "": case "0":
73 case "standard": case "standard_available":
74 case "most": case "most_available":
75 case "extended": case "extended_available":
76 case "all": case "all_available": case "1":
77 case "devall": case "devall_available":
78 case "none":
79 return true;
80 default:
81 return false;
82 }
83}
84
85entity makeXonoticWeaponarenaCheckBox(string theWeapon, string theText)
86{
88 me.configureXonoticWeaponarenaCheckBox(me, theWeapon, theText);
89 return me;
90}
91
93{
94 me.message = theWeapon;
95 me.checked = false;
96 me.loadCvars(me);
97 me.configureCheckBox(me, theText, me.fontSize, me.image);
98}
99
101{
102 int n = tokenize_console(cvar_string("menu_weaponarena"));
103 for (int i = 0; i < n; ++i)
104 if (argv(i) == me.message)
105 {
106 me.checked = true;
107 break;
108 }
109}
111{
112 string mwa = cvar_string("menu_weaponarena");
113 if (me.checked) // addtolist
114 {
115 if (mwa == "off")
116 mwa = me.message;
117 else
118 mwa = cons(mwa, me.message);
119 }
120 else // removefromlist
121 {
122 string s;
123 int n = tokenize_console(mwa);
124 mwa = "";
125 for (int i = 0; i < n; ++i)
126 {
127 s = argv(i);
128 if (s != me.message)
129 mwa = cons(mwa, s);
130 }
131 if (mwa == "")
132 mwa = "off";
133 }
134 cvar_set("menu_weaponarena", mwa);
135 if (Weaponarena_nonCustomValue(cvar_string("g_weaponarena")))
136 return;
137 else
138 cvar_set("g_weaponarena", mwa);
139
140 entity e;
141 for (int i = 0; i < me.parent.toggleableItemsCount; ++i) // reload cvars for the RadioButtons
142 {
143 e = me.parent.(toggleableItems[i]);
144 e.loadCvars(e);
145 }
146}
147
149{
150 me.checked = (cvar_string("menu_weaponstartoverride") == "-1"
151 && (cvar_string("g_weaponarena") == "0" || cvar_string("g_weaponarena") == "off" || cvar_string("g_weaponarena") == "")
152 && !cvar("g_instagib") && !cvar("g_nix") && !cvar("g_melee_only") && !cvar("g_overkill"));
153}
154
156{
157 for (entity e = me.parent.firstChild; e; e = e.nextSibling)
158 if (e.classname == "XonoticWeaponarenaCheckBox")
159 e.disabled = !me.checked;
160}
161
168{
170 if (cvar_string("g_weaponarena") == "")
171 cvar_set("g_weaponarena", cvar_string("menu_weaponarena"));
173}
174
176{
178 me.configureDialog(me);
179 return me;
180}
181
183{
184 entity e;
185
186 /* These RadioButtons have fairly complicated requirements to work properly:
187 * XonoticWeaponarenaCheckBox_saveCvars:
188 * Clicking the CheckBox needs to update menu_weaponarena, but also g_weaponarena if "Custom weapons" has been selected.
189 * We don't update g_weaponarena directly to allow saving selections.
190 * Clicking a CheckBox also needs to reload cvars for the RadioButtons, since the CheckBox might've set g_weaponarena 0.
191 * MutatorWeaponArenaDisable_RadioButton_loadCvars:
192 * "Disable" is true if g_weaponarena 0, but shouldn't be selected if any of the other options are chosen (e.g. g_instagib 1),
193 * and consequently the CheckBoxes for these cvars in their own mutator tabs need to also adjust g_weaponarena.
194 * MutatorWeaponArenaCustom_RadioButton_loadCvars:
195 * "Custom weapons" being selected has more complicated requirements than just if g_weaponarena is set to "".
196 * MutatorWeaponArenaCustom_RadioButton_saveCvars:
197 * "Custom weapons" needs to set g_weaponarena to menu_weaponarena when selected.
198 * Need to reset g_weaponarena "" to g_weaponarena "0" where possible.
199 * Also, NIX and g_weaponarena can be technically be enabled together, but we just ignore that.
200 */
201 me.TR(me);
202 me.TD(me, 1, 4, e = makeXonoticRadioButton(1, me.message, "0", _("Disable")));
205 me.TR(me);
206 me.TD(me, 1, 4, e = makeXonoticRadioButton(1, me.message, "all", _("All weapons")));
207 e.cvarOffValue = "0";
209 me.TR(me);
210 me.TD(me, 1, 4, e = makeXonoticRadioButton(1, me.message, "standard", _("Standard weapons")));
211 e.cvarOffValue = "0";
213 me.TR(me);
214 me.TD(me, 1, 4, e = makeXonoticRadioButton(1, me.message, "extended", _("Extended weapons (includes New Toys)")));
215 e.cvarOffValue = "0";
217 me.TR(me);
218 me.TD(me, 1, 4, e = makeXonoticRadioButton(1, me.message, "", _("Custom weapons")));
219 e.cvarOffValue = "0";
223 int cols = 3;
224 int c = 0;
225 FOREACH(Weapons, it != WEP_Null && !(it.spawnflags & WEP_FLAG_HIDDEN) && it != WEP_NEXBALL,
226 {
227 if (c % cols == 0)
228 {
229 me.TR(me);
230 me.TDempty(me, 0.2);
231 }
232 ++c;
233 me.TD(me, 1, (4 - 0.2) / cols, e = makeXonoticWeaponarenaCheckBox(strzone(it.netname), strzone(it.m_name)));
236 });
237
238 me.TR(me);
239 me.TD(me, 1, 4, makeXonoticTextLabel(0, _("Special arenas:")));
240 me.TR(me);
241 string multi = "";
242 FOREACH(Weapons, it != WEP_Null && !(it.spawnflags & WEP_FLAG_HIDDEN) && it != WEP_NEXBALL,
243 multi = cons(multi, strcat("g_balance_", it.netname, "_weaponstartoverride")));
244 me.TDempty(me, 0.2);
245 me.TD(me, 1, 4 - 0.2, e = makeXonoticRadioButton_T(1, "menu_weaponstartoverride", "0", _("No start weapons"), "-"));
246 e.cvarOffValue = "-1";
247 makeMulti(e, strzone(multi));
249 me.TR(me);
250 me.TDempty(me, 0.2);
251#ifdef MENU_INCLUDE_OVERKILL
252 me.TD(me, 1, (4 - 0.2) / 2, e = makeXonoticRadioButton_T(1, "g_overkill", "1", MENU_OVERKILL_NAME, sprintf(MENU_OVERKILL_DESCRIPTION, UNCOLORED_NAME(WEP_BLASTER), UNCOLORED_NAME(MUTATOR_dodging), UNCOLORED_NAME(MUTATOR_nades))));
253 e.cvarOffValue = "0";
254 me.TD(me, 1, (4 - 0.2) / 2, // ...
255#else
256 me.TD(me, 1, 4 - 0.2, // ...
257#endif
258 e = makeXonoticRadioButton_T(1, "g_melee_only", "1", _("Melee only arena"),
259 sprintf(_("Players spawn with no ammo and no weapons except the %s, so can only slap other players."), UNCOLORED_NAME(WEP_SHOTGUN))));
260 e.cvarOffValue = "0";
261 me.TR(me);
262 me.TDempty(me, 0.2);
263 me.TD(me, 1, (4 - 0.2) / 2, e = makeXonoticRadioButton_T(1, "g_instagib", "1", MENU_INSTAGIB_NAME, sprintf(MENU_INSTAGIB_DESCRIPTION, UNCOLORED_NAME(WEP_VAPORIZER))));
264 e.cvarOffValue = "0";
265 me.TD(me, 1, (4 - 0.2) / 2, e = makeXonoticRadioButton_T(1, "g_nix", "1", MENU_NIX_NAME, MENU_NIX_DESCRIPTION));
266 e.cvarOffValue = "0";
267}
268
270{
271 return _("Players will be given a set of weapons on spawn along with unlimited ammo, without weapon pickups on the map.");
272}
274{
275 bool can_enable = true;
276 // weaponarena can't be enabled with g_overkill 1, g_instagib 1, or g_melee_only 1,
277 // ... but we ignore them here since they're lumped in the same RadioButton group
278 if (is_already_enabled) // include g_melee_only, since it isn't elsewhere in the menu mutator list
279 return can_enable && (!cvar("menu_weaponstartoverride") || cvar("g_melee_only")
280 || (cvar_string(me.message) != "0" && cvar_string(me.message) != "off" && cvar_string(me.message) != ""));
281 return can_enable;
282}
283
284
285// Weapon stay "mutator"
287{
289 me.configureDialog(me);
290 return me;
291}
292
294{
295 entity e;
296
297 me.TR(me);
298 me.TD(me, 1, 4 * 0.225, e = makeXonoticRadioButton(1, me.message, "0", _("Disable")));
300 me.TD(me, 1, 4 * 0.55, e = makeXonoticRadioButton(1, me.message, "1", _("Enabled but pickups give no ammo")));
302 me.TD(me, 1, 4 * 0.225, e = makeXonoticRadioButton(1, me.message, "2", _("Enable")));
304}
305
307{
308 return _("Weapons stay on the map after they are picked up.");
309}
311{
312 // Weapon stay requires weapons to actually spawn on the map
313 bool can_enable = (!cvar("g_instagib") && !cvar("g_nix") && !cvar("g_melee_only") && !cvar("g_overkill")
314 && (cvar_string("g_weaponarena") == "0" || cvar_string("g_weaponarena") == "off" || cvar_string("g_weaponarena") == ""));
315 if (is_already_enabled)
316 return can_enable && cvar(me.message);
317 return can_enable;
318}
319
320
321// Offhand weapons "mutator"
323{
325 me.configureDialog(me);
326 return me;
327}
328
330{
331 entity e;
332
333 me.TR(me);
334 me.TR(me);
335 me.TD(me, 1, 4 - 0.2, e = makeXonoticCheckBox(0, "g_offhand_blaster", _("Offhand Blaster")));
336
337 me.TR(me);
338 me.TR(me);
339 me.TD(me, 1, 4 - 0.2, e = makeXonoticCheckBox(0, "g_grappling_hook", _("Offhand Hook")));
340 setDependent(e, "g_offhand_blaster", 0, 0);
341 me.TR(me);
342 me.TDempty(me, 0.2);
343 me.TD(me, 1, 4 - 0.2, e = makeXonoticCheckBox(0, "g_grappling_hook_useammo", _("Consume ammo")));
344}
345
347{
348 return sprintf(_("Players spawn with an Offhand Blaster or Grappling Hook. Press %s to use it."), strcat("^3", _("hook"), "^7"));
349}
351{
352 bool can_enable = true;
353 if (is_already_enabled)
354 return can_enable && (cvar("g_offhand_blaster") || cvar("g_grappling_hook"));
355 return can_enable;
356}
357
358
359// Jetpack "mutator"
361{
363 me.configureDialog(me);
364 return me;
365}
366
371
373{
374 return sprintf(_("Players spawn with the %s. Double-tap %s or press %s to use it."), COLORED_NAME(ITEM_Jetpack), strcat("^3", _("jump"), "^7"), strcat("^3", _("jetpack"), "^7"));
375}
377{
378 bool can_enable = true;
379 if (is_already_enabled)
380 return can_enable && cvar(me.message);
381 return can_enable;
382}
383
384
385// Custom physics "mutator"
387{
389 me.configureDialog(me);
390 return me;
391}
392
394{
395 entity e, s;
396
397 me.TR(me);
398 me.TR(me);
399 me.TD(me, 1, 4, e = makeXonoticCheckBox_T(0, "g_dodging", _("Dodging"),
400 _("Enable dodging (quick acceleration in a given direction). Double-tap a directional key to dodge")));
401
402 me.TR(me);
403 me.TR(me);
404 me.TD(me, 1, 2, e = makeXonoticTextLabel(0, _("Midair jumps:")));
405 me.TD(me, 1, 2, e = makeXonoticMixedSlider_T("g_multijump",
406 _("How many times players can jump while midair")));
407 e.addText(e, _("Infinite"), -1);
408 e.addRange(e, 0, 10, 1);
409 e.configureXonoticMixedSliderValues(e);
410 me.TR(me);
411 me.TDempty(me, 0.2);
412 me.TD(me, 1, 4 - 0.2, e = makeXonoticCheckBox_T(0, "g_multijump_add", _("Additive velocity"),
413 _("Add on, rather than set, their vertical velocity each time the player jumps")));
414
415 me.TR(me);
416 me.TR(me);
417 me.TD(me, 1, 4, e = makeXonoticCheckBox_T(0, "g_walljump", _("Wall jumping"),
418 _("Jump away from walls when running alongside them")));
419 me.TR(me);
420 me.TDempty(me, 0.2);
421 me.TD(me, 1, 1.8, makeXonoticTextLabel(0, _("Delay between walljumps:")));
422 me.TD(me, 1, 2, e = makeXonoticSlider(0.5, 1.5, 0.1, "g_walljump_delay"));
423 e.formatString = "S";
424 e.setValueSpace(e, e.valueSpace * 1.25);
425
426 me.TR(me);
427 me.TR(me);
428 me.TD(me, 1, 4, e = makeXonoticCheckBox_T(0, "sv_doublejump", _("Double jumps"),
429 _("Gain extra height when jumping again shortly after the first jump")));
430
431 const float def_grav = stof(cvar_defstring("sv_gravity"));
432 me.TR(me);
433 me.TR(me);
434 s = makeXonoticSlider_T(def_grav * 0.1, def_grav * 0.75, def_grav * 0.025, "sv_gravity",
435 _("Make things fall to the ground slower (percentage of normal gravity)"));
436 s.valueDigits = 3;
437 s.valueDisplayMultiplier = 1 / def_grav; // show gravity as a percent of normal
438 s.formatString = "%";
439 me.TD(me, 1, 2, e = makeXonoticSliderCheckBox(def_grav, 1, s, _("Low gravity")));
440 e.savedValue = def_grav * 0.25; // good on silvercity
441 me.TD(me, 1, 2, s);
442
443 me.TR(me);
444 me.TR(me);
445 me.TD(me, 1, 4, e = makeXonoticCheckBox_T(0, "g_globalforces", _("Global forces"),
446 _("Knockback experienced by any player affects all players")));
447}
448
450{
451 return _("Various fun changes to physics and movement.");
452}
454{
455 bool can_enable = true;
456 if (is_already_enabled)
457 return can_enable && (cvar("g_dodging") || cvar("g_multijump") || cvar("g_walljump") || cvar("sv_doublejump")
458 || cvar("sv_gravity") < stof(cvar_defstring("sv_gravity")) || cvar("g_globalforces"));
459 return can_enable;
460}
entity makeXonoticSliderCheckBox(float theOffValue, float isInverted, entity theControlledSlider, string theText)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
virtual void canEnable()
#define COLORED_NAME(this)
Definition color.qh:189
#define UNCOLORED_NAME(this)
Definition color.qh:190
#define tokenize_console
Weapons
Definition guide.qh:113
#define FOREACH(list, cond, body)
Definition iter.qh:19
void loadAllCvars(entity root)
Definition util.qc:53
void makeMulti(entity e, string otherCvars)
Definition util.qc:92
void setDependent(entity e, string theCvarName, float theCvarMin, float theCvarMax)
Definition util.qc:180
void cvar_set(string name, string value)
float stof(string val,...)
float cvar(string name)
const string cvar_string(string name)
const string cvar_defstring(string name)
string strzone(string s)
string argv(float n)
void Mutators_add_SliderCheckBox(entity me, entity e)
Definition mutatortab.qc:60
void XonoticMutatorOffhandWeaponsTab_fill(entity me)
entity Mutators_main_checkbox(entity me)
Definition mutatortab.qc:25
entity makeXonoticMutatorCustomPhysicsTab()
entity makeXonoticMutatorOffhandWeaponsTab()
void Mutators_add_CheckBox(entity me, entity e)
Definition mutatortab.qc:51
void XonoticMutatorJetpackTab_fill(entity me)
bool Weaponarena_nonCustomValue(string val)
Definition mutatortab.qc:68
void XonoticMutatorWeaponStayTab_fill(entity me)
void Mutators_add_RadioButton(entity me, entity e)
Definition mutatortab.qc:41
void MutatorWeaponArenaDisable_RadioButton_loadCvars(entity me)
void MutatorWeaponArenaCustom_RadioButton_saveCvars(entity me)
void XonoticMutatorTab_showNotify(entity me)
Definition mutatortab.qc:20
void XonoticMutatorWeaponArenaTab_fill(entity me)
void XonoticWeaponarenaCheckBox_configureXonoticWeaponarenaCheckBox(entity me, string theWeapon, string theText)
Definition mutatortab.qc:92
entity makeXonoticMutatorWeaponArenaTab()
void MutatorWeaponArenaCustom_RadioButton_updateCheckBoxes(entity me)
entity makeXonoticMutatorWeaponStayTab()
void XonoticMutatorCustomPhysicsTab_fill(entity me)
void XonoticWeaponarenaCheckBox_loadCvars(entity me)
entity makeXonoticWeaponarenaCheckBox(string theWeapon, string theText)
Definition mutatortab.qc:85
void Mutators_toggleable_SliderCheckBox_loadCvars(entity me)
Definition mutatortab.qc:56
entity makeXonoticMutatorJetpackTab()
void Mutators_toggleable_CheckBox_loadCvars(entity me)
Definition mutatortab.qc:46
void XonoticWeaponarenaCheckBox_saveCvars(entity me)
void Mutators_toggleable_RadioButton_loadCvars(entity me)
Definition mutatortab.qc:36
void MutatorWeaponArenaCustom_RadioButton_loadCvars(entity me)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
#define NEW(cname,...)
Definition oo.qh:120
#define METHOD(cname, name, prototype)
Definition oo.qh:274
ERASEABLE string cons(string a, string b)
Definition string.qh:277
entity makeXonoticTextLabel(float theAlign, string theText)
Definition textlabel.qc:3
const string MENU_INSTAGIB_DESCRIPTION
Definition ui_instagib.qh:4
const string MENU_INSTAGIB_NAME
Definition ui_instagib.qh:3
const string MENU_NIX_NAME
Definition ui_nix.qh:3
const string MENU_NIX_DESCRIPTION
Definition ui_nix.qh:4
const int WEP_FLAG_HIDDEN
hides from menu
Definition weapon.qh:253
entity makeXonoticCheckBox_T(float isInverted, string theCvar, string theText, string theTooltip)
Definition checkbox.qc:3
entity makeXonoticCheckBox(float isInverted, string theCvar, string theText)
Definition checkbox.qc:28
void XonoticCheckBox_loadCvars(entity me)
Definition checkbox.qc:64
entity makeXonoticMixedSlider_T(string theCvar, string theTooltip)
Definition mixedslider.qc:3
void XonoticRadioButton_saveCvars(entity me)
void XonoticRadioButton_loadCvars(entity me)
entity makeXonoticRadioButton(float theGroup, string theCvar, string theValue, string theText)
Definition radiobutton.qc:9
entity makeXonoticRadioButton_T(float theGroup, string theCvar, string theValue, string theText, string theTooltip)
Definition radiobutton.qc:3
entity makeXonoticSlider_T(float theValueMin, float theValueMax, float theValueStep, string theCvar, string theTooltip)
Definition slider.qc:3
entity makeXonoticSlider(float theValueMin, float theValueMax, float theValueStep, string theCvar)
Definition slider.qc:9