]> 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 Mario/overkill
[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 bool nt_IsNewToy(int w)
113 {
114         switch(w)
115         {
116                 case WEP_SEEKER.m_id:
117                 case WEP_MINE_LAYER.m_id:
118                 case WEP_HLAC.m_id:
119                 case WEP_RIFLE.m_id:
120                 case WEP_SHOCKWAVE.m_id:
121                         return true;
122                 default:
123                         return false;
124         }
125 }
126
127 string nt_GetFullReplacement(string w)
128 {
129         switch(w)
130         {
131                 case "hagar": return "seeker";
132                 case "devastator": return "minelayer";
133                 case "machinegun": return "hlac";
134                 case "vortex": return "rifle";
135                 //case "shotgun": return "shockwave";
136                 default: return string_null;
137         }
138 }
139
140 string nt_GetReplacement(string w, float m)
141 {
142         if(m == NT_AUTOREPLACE_NEVER)
143                 return w;
144         string s = nt_GetFullReplacement(w);
145         if (!s)
146                 return w;
147         if(m == NT_AUTOREPLACE_RANDOM)
148                 s = strcat(w, " ", s);
149         return s;
150 }
151
152 MUTATOR_HOOKFUNCTION(nt, SetStartItems)
153 {
154         // rearrange start_weapon_default
155         // apply those bits that are set by start_weapon_defaultmask
156         // same for warmup
157
158         float j, n;
159
160         WepSet newdefault;
161         WepSet warmup_newdefault;
162
163         newdefault = '0 0 0';
164         warmup_newdefault = '0 0 0';
165
166         WepSet seti = '0 0 0';
167
168         FOREACH(Weapons, it != WEP_Null, LAMBDA(
169                 seti = it.m_wepset;
170                 n = tokenize_console(nt_GetReplacement(it.netname, autocvar_g_new_toys_autoreplace));
171
172                 for(j = 0; j < n; ++j)
173                         FOREACH(Weapons, it != WEP_Null, LAMBDA(
174                                 if(it.netname == argv(j))
175                                 {
176                                         WepSet setk = it.m_wepset;
177                                         if(start_weapons & seti) newdefault |= setk;
178                                         if(warmup_start_weapons & seti) warmup_newdefault |= setk;
179                                 }
180                         ));
181         ));
182
183         newdefault &= start_weapons_defaultmask;
184         start_weapons &= ~start_weapons_defaultmask;
185         start_weapons |= newdefault;
186
187         warmup_newdefault &= warmup_start_weapons_defaultmask;
188         warmup_start_weapons &= ~warmup_start_weapons_defaultmask;
189         warmup_start_weapons |= warmup_newdefault;
190 }
191
192 MUTATOR_HOOKFUNCTION(nt, SetWeaponreplace)
193 {
194         entity wep = M_ARGV(0, entity);
195         entity wepinfo = M_ARGV(1, entity);
196         string ret_string = M_ARGV(2, string);
197
198         // otherwise, we do replace
199         if(wep.new_toys)
200         {
201                 // map defined replacement:
202                 ret_string = wep.new_toys;
203         }
204         else
205         {
206                 // auto replacement:
207                 ret_string = nt_GetReplacement(wepinfo.netname, autocvar_g_new_toys_autoreplace);
208         }
209
210         // apply regular weaponreplace
211         ret_string = W_Apply_Weaponreplace(ret_string);
212
213         M_ARGV(2, string) = ret_string;
214 }
215
216 MUTATOR_HOOKFUNCTION(nt, FilterItem)
217 {
218         entity item = M_ARGV(0, entity);
219
220         if(nt_IsNewToy(item.weapon) && autocvar_g_new_toys_use_pickupsound) {
221                 item.item_pickupsound = string_null;
222                 item.item_pickupsound_ent = SND_WEAPONPICKUP_NEW_TOYS;
223         }
224 }