]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/mutators/mutator/new_toys/sv_new_toys.qc
Merge branch 'master' into Lyberta/TeamplayOverhaul
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / new_toys / sv_new_toys.qc
1 #include "sv_new_toys.qh"
2
3 #include "../random_items/sv_random_items.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 autocvar_g_new_toys;
74
75 bool nt_IsNewToy(int w);
76
77 REGISTER_MUTATOR(nt, expr_evaluate(cvar_string("g_new_toys")) && !MUTATOR_IS_ENABLED(mutator_instagib) && !MUTATOR_IS_ENABLED(ok))
78 {
79         MUTATOR_ONADD
80         {
81                 if(time > 1) // game loads at time 1
82                         error("This cannot be added at runtime\n");
83
84                 // mark the guns as ok to use by e.g. impulse 99
85                 FOREACH(Weapons, it != WEP_Null, {
86                         if(nt_IsNewToy(it.m_id))
87                                 it.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
88                 });
89         }
90
91         MUTATOR_ONROLLBACK_OR_REMOVE
92         {
93                 FOREACH(Weapons, it != WEP_Null, {
94                         if(nt_IsNewToy(it.m_id))
95                                 it.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
96                 });
97         }
98
99         MUTATOR_ONREMOVE
100         {
101                 LOG_INFO("This cannot be removed at runtime");
102                 return -1;
103         }
104
105         return 0;
106 }
107
108 .string new_toys;
109
110 float autocvar_g_new_toys_autoreplace;
111 bool autocvar_g_new_toys_use_pickupsound = false;
112 const float NT_AUTOREPLACE_NEVER = 0;
113 const float NT_AUTOREPLACE_ALWAYS = 1;
114 const float NT_AUTOREPLACE_RANDOM = 2;
115
116 bool nt_IsNewToy(int w)
117 {
118         switch(w)
119         {
120                 case WEP_SEEKER.m_id:
121                 case WEP_MINE_LAYER.m_id:
122                 case WEP_HLAC.m_id:
123                 case WEP_RIFLE.m_id:
124                 case WEP_SHOCKWAVE.m_id:
125                         return true;
126                 default:
127                         return false;
128         }
129 }
130
131 string nt_GetFullReplacement(string w)
132 {
133         switch(w)
134         {
135                 case "hagar": return "seeker";
136                 case "devastator": return "minelayer";
137                 case "machinegun": return "hlac";
138                 case "vortex": return "rifle";
139                 //case "shotgun": return "shockwave";
140                 default: return string_null;
141         }
142 }
143
144 string nt_GetReplacement(string w, float m)
145 {
146         if(m == NT_AUTOREPLACE_NEVER)
147                 return w;
148         string s = nt_GetFullReplacement(w);
149         if (!s)
150                 return w;
151         if(m == NT_AUTOREPLACE_RANDOM)
152                 s = strcat(w, " ", s);
153         return s;
154 }
155
156 MUTATOR_HOOKFUNCTION(nt, SetStartItems)
157 {
158         // rearrange start_weapon_default
159         // apply those bits that are set by start_weapon_defaultmask
160         // same for warmup
161
162         float j, n;
163
164         WepSet newdefault;
165         WepSet warmup_newdefault;
166
167         newdefault = '0 0 0';
168         warmup_newdefault = '0 0 0';
169
170         WepSet seti = '0 0 0';
171
172         FOREACH(Weapons, it != WEP_Null, {
173                 seti = it.m_wepset;
174                 n = tokenize_console(nt_GetReplacement(it.netname, autocvar_g_new_toys_autoreplace));
175
176                 for(j = 0; j < n; ++j)
177                         FOREACH(Weapons, it != WEP_Null, {
178                                 if(it.netname == argv(j))
179                                 {
180                                         WepSet setk = it.m_wepset;
181                                         if(start_weapons & seti) newdefault |= setk;
182                                         if(warmup_start_weapons & seti) warmup_newdefault |= setk;
183                                 }
184                         });
185         });
186
187         newdefault &= start_weapons_defaultmask;
188         start_weapons &= ~start_weapons_defaultmask;
189         start_weapons |= newdefault;
190
191         warmup_newdefault &= warmup_start_weapons_defaultmask;
192         warmup_start_weapons &= ~warmup_start_weapons_defaultmask;
193         warmup_start_weapons |= warmup_newdefault;
194 }
195
196 MUTATOR_HOOKFUNCTION(nt, SetWeaponreplace)
197 {
198         if (MUTATOR_IS_ENABLED(random_items))
199         {
200                 // Do not replace weapons when random items are enabled.
201                 return;
202         }
203         entity wep = M_ARGV(0, entity);
204         entity wepinfo = M_ARGV(1, entity);
205         string ret_string = M_ARGV(2, string);
206
207         // otherwise, we do replace
208         if(wep.new_toys)
209         {
210                 // map defined replacement:
211                 ret_string = wep.new_toys;
212         }
213         else
214         {
215                 // auto replacement:
216                 ret_string = nt_GetReplacement(wepinfo.netname, autocvar_g_new_toys_autoreplace);
217         }
218
219         // apply regular weaponreplace
220         ret_string = W_Apply_Weaponreplace(ret_string);
221
222         M_ARGV(2, string) = ret_string;
223 }
224
225 MUTATOR_HOOKFUNCTION(nt, FilterItem)
226 {
227         entity item = M_ARGV(0, entity);
228
229         if(nt_IsNewToy(item.weapon) && autocvar_g_new_toys_use_pickupsound) {
230                 item.item_pickupsound = string_null;
231                 item.item_pickupsound_ent = SND_WEAPONPICKUP_NEW_TOYS;
232         }
233 }