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