]> 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 Mirio/balance
[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 bool nt_IsNewToy(int w);
72
73 REGISTER_MUTATOR(nt, cvar("g_new_toys") && !cvar("g_instagib") && !cvar("g_overkill"))
74 {
75         MUTATOR_ONADD
76         {
77                 if(time > 1) // game loads at time 1
78                         error("This cannot be added at runtime\n");
79
80                 // mark the guns as ok to use by e.g. impulse 99
81                 FOREACH(Weapons, it != WEP_Null, LAMBDA(
82                         if(nt_IsNewToy(it.m_id))
83                                 it.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
84                 ));
85         }
86
87         MUTATOR_ONROLLBACK_OR_REMOVE
88         {
89                 FOREACH(Weapons, it != WEP_Null, LAMBDA(
90                         if(nt_IsNewToy(it.m_id))
91                                 it.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
92                 ));
93         }
94
95         MUTATOR_ONREMOVE
96         {
97                 LOG_INFO("This cannot be removed at runtime\n");
98                 return -1;
99         }
100
101         return 0;
102 }
103
104 .string new_toys;
105
106 float autocvar_g_new_toys_autoreplace;
107 bool autocvar_g_new_toys_use_pickupsound = true;
108 const float NT_AUTOREPLACE_NEVER = 0;
109 const float NT_AUTOREPLACE_ALWAYS = 1;
110 const float NT_AUTOREPLACE_RANDOM = 2;
111
112 MUTATOR_HOOKFUNCTION(nt, SetModname)
113 {
114         M_ARGV(0, string) = "NewToys";
115 }
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, LAMBDA(
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, LAMBDA(
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;
189         start_weapons &= ~start_weapons_defaultmask;
190         start_weapons |= newdefault;
191
192         warmup_newdefault &= warmup_start_weapons_defaultmask;
193         warmup_start_weapons &= ~warmup_start_weapons_defaultmask;
194         warmup_start_weapons |= warmup_newdefault;
195 }
196
197 MUTATOR_HOOKFUNCTION(nt, SetWeaponreplace)
198 {
199         entity wep = M_ARGV(0, entity);
200         entity wepinfo = M_ARGV(1, entity);
201         string ret_string = M_ARGV(2, string);
202
203         // otherwise, we do replace
204         if(wep.new_toys)
205         {
206                 // map defined replacement:
207                 ret_string = wep.new_toys;
208         }
209         else
210         {
211                 // auto replacement:
212                 ret_string = nt_GetReplacement(wepinfo.netname, autocvar_g_new_toys_autoreplace);
213         }
214
215         // apply regular weaponreplace
216         ret_string = W_Apply_Weaponreplace(ret_string);
217
218         M_ARGV(2, string) = ret_string;
219 }
220
221 MUTATOR_HOOKFUNCTION(nt, FilterItem)
222 {
223         entity item = M_ARGV(0, entity);
224
225         if(nt_IsNewToy(item.weapon) && autocvar_g_new_toys_use_pickupsound) {
226                 item.item_pickupsound = string_null;
227                 item.item_pickupsound_ent = SND_WEAPONPICKUP_NEW_TOYS;
228         }
229 }