Xonotic
sv_new_toys.qc
Go to the documentation of this file.
1 #include "sv_new_toys.qh"
2 
3 #include "../random_items/sv_random_items.qh"
5 
6 /*
7 
8 CORE laser vortex lg rl cry gl elec hagar fireb hook
9  vaporizer porto
10  tuba
11 
12 NEW rifle hlac minel seeker
13 IDEAS OPEN flak OPEN FUN FUN FUN FUN
14 
15 
16 
17 How this mutator works:
18  =======================
19 
20 When a gun tries to spawn, this mutator is called. It will provide alternate
21 weaponreplace lists.
22 
23 Entity:
24 
25 {
26 "classname" "weapon_vortex"
27 "new_toys" "rifle"
28 }
29 -> This will spawn as Rifle in this mutator ONLY, and as Vortex otherwise.
30 
31 {
32 "classname" "weapon_vortex"
33 "new_toys" "vortex rifle"
34 }
35 -> This will spawn as either Vortex or Rifle in this mutator ONLY, and as Vortex otherwise.
36 
37 {
38 "classname" "weapon_vortex"
39 "new_toys" "vortex"
40 }
41 -> This is always a Vortex.
42 
43 If the map specifies no "new_toys" argument
44 
45 There will be two default replacements selectable: "replace all" and "replace random".
46 In "replace all" mode, e.g. Vortex will have the default replacement "rifle".
47 In "replace random" mode, Vortex will have the default replacement "vortex rifle".
48 
49 This mutator's replacements run BEFORE regular weaponreplace!
50 
51 The New Toys guns do NOT get a spawn function, so they can only ever be spawned
52 when this mutator is active.
53 
54 Likewise, warmup, give all, give ALL and impulse 99 will not give them unless
55 this mutator is active.
56 
57 Outside this mutator, they still can be spawned by:
58 - setting their start weapon cvar to 1
59 - give weaponname
60 - weaponreplace
61 - weaponarena (but all and most weapons arena again won't include them)
62 
63 This mutator performs the default replacements on the DEFAULTS of the
64 start weapon selection.
65 
66 These weapons appear in the menu's priority list, BUT get a suffix
67 "(Mutator weapon)".
68 
69 Picking up a "new toys" weapon will not play standard weapon pickup sound, but
70 roflsound "New toys, new toys!" sound.
71 
72 */
73 
74 //string autocvar_g_new_toys;
75 
76 bool nt_IsNewToy(int w);
77 
78 REGISTER_MUTATOR(nt, expr_evaluate(cvar_string("g_new_toys")) && !MUTATOR_IS_ENABLED(mutator_instagib) && !MUTATOR_IS_ENABLED(ok))
79 {
81  {
82  if(time > 1) // game loads at time 1
83  error("This cannot be added at runtime\n");
84 
85  // mark the guns as ok to use by e.g. impulse 99
86  FOREACH(Weapons, it != WEP_Null, {
87  if(nt_IsNewToy(it.m_id))
88  it.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
89  });
90  }
91 
93  {
94  FOREACH(Weapons, it != WEP_Null, {
95  if(nt_IsNewToy(it.m_id))
96  it.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
97  });
98  }
99 
101  {
102  LOG_INFO("This cannot be removed at runtime");
103  return -1;
104  }
105 
106  return 0;
107 }
108 
109 .string new_toys;
110 
113 const float NT_AUTOREPLACE_NEVER = 0;
114 const float NT_AUTOREPLACE_ALWAYS = 1;
115 const float NT_AUTOREPLACE_RANDOM = 2;
116 
117 bool nt_IsNewToy(int w)
118 {
119  switch(w)
120  {
121  case WEP_SEEKER.m_id:
122  case WEP_MINE_LAYER.m_id:
123  case WEP_HLAC.m_id:
124  case WEP_RIFLE.m_id:
125  case WEP_SHOCKWAVE.m_id:
126  return true;
127  default:
128  return false;
129  }
130 }
131 
132 string nt_GetFullReplacement(string w)
133 {
134  switch(w)
135  {
136  case "hagar": return "seeker";
137  case "devastator": return "minelayer";
138  case "machinegun": return "hlac";
139  case "vortex": return "rifle";
140  //case "shotgun": return "shockwave";
141  default: return string_null;
142  }
143 }
144 
145 string nt_GetReplacement(string w, float m)
146 {
147  if(m == NT_AUTOREPLACE_NEVER)
148  return w;
149  string s = nt_GetFullReplacement(w);
150  if (!s)
151  return w;
152  if(m == NT_AUTOREPLACE_RANDOM)
153  s = strcat(w, " ", s);
154  return s;
155 }
156 
157 MUTATOR_HOOKFUNCTION(nt, SetStartItems)
158 {
159  // rearrange start_weapon_default
160  // apply those bits that are set by start_weapon_defaultmask
161  // same for warmup
162 
163  float j, n;
164 
165  WepSet newdefault;
166  WepSet warmup_newdefault;
167 
168  newdefault = '0 0 0';
169  warmup_newdefault = '0 0 0';
170 
171  WepSet seti = '0 0 0';
172 
173  FOREACH(Weapons, it != WEP_Null, {
174  seti = it.m_wepset;
175  n = tokenize_console(nt_GetReplacement(it.netname, autocvar_g_new_toys_autoreplace));
176 
177  for(j = 0; j < n; ++j)
178  FOREACH(Weapons, it != WEP_Null, {
179  if(it.netname == argv(j))
180  {
181  WepSet setk = it.m_wepset;
182  if(start_weapons & seti) newdefault |= setk;
183  if(warmup_start_weapons & seti) warmup_newdefault |= setk;
184  }
185  });
186  });
187 
188  newdefault &= start_weapons_defaultmask;
190  start_weapons |= newdefault;
191 
192  warmup_newdefault &= warmup_start_weapons_defaultmask;
194  warmup_start_weapons |= warmup_newdefault;
195 }
196 
197 MUTATOR_HOOKFUNCTION(nt, SetWeaponreplace)
198 {
199  if (MUTATOR_IS_ENABLED(random_items))
200  {
201  // Do not replace weapons when random items are enabled.
202  return;
203  }
204  entity wep = M_ARGV(0, entity);
205  entity wepinfo = M_ARGV(1, entity);
206  string ret_string = M_ARGV(2, string);
207 
208  // otherwise, we do replace
209  if(wep.new_toys)
210  {
211  // map defined replacement:
212  ret_string = wep.new_toys;
213  }
214  else
215  {
216  // auto replacement:
217  ret_string = nt_GetReplacement(wepinfo.netname, autocvar_g_new_toys_autoreplace);
218  }
219 
220  // apply regular weaponreplace
221  ret_string = W_Apply_Weaponreplace(ret_string);
222 
223  M_ARGV(2, string) = ret_string;
224 }
225 
226 MUTATOR_HOOKFUNCTION(nt, FilterItem)
227 {
228  entity item = M_ARGV(0, entity);
229 
230  if(nt_IsNewToy(item.weapon) && autocvar_g_new_toys_use_pickupsound) {
231  item.item_pickupsound = string_null;
232  item.item_pickupsound_ent = SND_WEAPONPICKUP_NEW_TOYS;
233  }
234 }
string nt_GetReplacement(string w, float m)
Definition: sv_new_toys.qc:145
vector WepSet
Definition: weapon.qh:11
bool autocvar_g_new_toys_use_pickupsound
Definition: sv_new_toys.qc:112
string string_null
Definition: nil.qh:9
WepSet warmup_start_weapons
Definition: world.qh:100
string W_Apply_Weaponreplace(string in)
Definition: spawning.qc:13
WepSet start_weapons
Definition: world.qh:81
string new_toys
Definition: sv_new_toys.qc:109
const float NT_AUTOREPLACE_NEVER
Definition: sv_new_toys.qc:113
WepSet warmup_start_weapons_defaultmask
Definition: world.qh:102
entity() spawn
MUTATOR_HOOKFUNCTION(nt, SetStartItems)
Definition: sv_new_toys.qc:157
#define MUTATOR_ONROLLBACK_OR_REMOVE
Definition: base.qh:286
#define MUTATOR_IS_ENABLED(this)
Definition: base.qh:176
float autocvar_g_new_toys_autoreplace
Definition: sv_new_toys.qc:111
const float NT_AUTOREPLACE_ALWAYS
Definition: sv_new_toys.qc:114
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
string nt_GetFullReplacement(string w)
Definition: sv_new_toys.qc:132
bool nt_IsNewToy(int w)
Definition: sv_new_toys.qc:117
#define LOG_INFO(...)
Definition: log.qh:70
#define M_ARGV(x, type)
Definition: events.qh:17
#define tokenize_console
Definition: dpextensions.qh:24
#define MUTATOR_ONREMOVE
Definition: base.qh:285
REGISTER_MUTATOR(nt, expr_evaluate(cvar_string("g_new_toys")) &&!MUTATOR_IS_ENABLED(mutator_instagib) &&!MUTATOR_IS_ENABLED(ok))
Definition: sv_new_toys.qc:78
const int WEP_FLAG_MUTATORBLOCKED
Definition: weapon.qh:203
#define MUTATOR_ONADD
Definition: base.qh:284
float time
Definition: csprogsdefs.qc:16
WepSet start_weapons_defaultmask
Definition: world.qh:83
#define FOREACH(list, cond, body)
Definition: iter.qh:19
const float NT_AUTOREPLACE_RANDOM
Definition: sv_new_toys.qc:115
ERASEABLE bool expr_evaluate(string s)
Evaluate an expression of the form: [+ | -]? [var[op]val | [op]var | val | var] ...
Definition: cvar.qh:48