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