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