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