]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/mutators/mutator_new_toys.qc
new toys: make the mutator compile mostly
[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 string nt_GetFullReplacement(string w)
83 {
84         switch(w)
85         {
86                 case "hagar": return "seeker";
87                 case "rocketlauncher": return "minelayer";
88                 case "uzi": return "hlac";
89                 case "nex": return "rifle";
90                 default: return string_null;
91         }
92 }
93
94 string nt_GetReplacement(string w, float m)
95 {
96         if(m == NT_AUTOREPLACE_NEVER)
97                 return w;
98         string s = nt_GetFullReplacement(w);
99         if not(s)
100                 return w;
101         if(m == NT_AUTOREPLACE_RANDOM)
102                 s = strcat(w, " ", s);
103         return s;
104 }
105
106 MUTATOR_HOOKFUNCTION(nt_SetStartItems)
107 {
108         // rearrange start_weapon_default
109         // apply those bits that are set by start_weapon_defaultmask
110         // same for warmup
111
112         float i, j, k, n;
113
114         WEPSET_DECLARE_A(newdefault);
115         WEPSET_DECLARE_A(warmup_newdefault);
116         
117         WEPSET_CLEAR_A(newdefault);
118         WEPSET_CLEAR_A(warmup_newdefault);
119
120         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
121         {
122                 entity e = get_weaponinfo(i);
123                 if(!e.weapon)
124                         continue;
125
126                 n = tokenize_console(nt_GetReplacement(e.netname, autocvar_g_new_toys_autoreplace));
127
128                 for(j = 0; j < n; ++j)
129                         for(k = WEP_FIRST; k <= WEP_LAST; ++k)
130                                 if(get_weaponinfo(k).netname == argv(j))
131                                 {
132                                         if(WEPSET_CONTAINS_AW(start_weapons, i))
133                                                 WEPSET_OR_AW(newdefault, k);
134                                         if(WEPSET_CONTAINS_AW(warmup_start_weapons, i))
135                                                 WEPSET_OR_AW(warmup_newdefault, k);
136                                 }
137         }
138
139         WEPSET_AND_AA(newdefault, start_weapons_defaultmask);
140         WEPSET_ANDNOT_AA(start_weapons, start_weapons_defaultmask);
141         WEPSET_OR_AA(start_weapons, newdefault);
142
143         WEPSET_AND_AA(warmup_newdefault, warmup_start_weapons_defaultmask);
144         WEPSET_ANDNOT_AA(warmup_start_weapons, warmup_start_weapons_defaultmask);
145         WEPSET_OR_AA(warmup_start_weapons, warmup_newdefault);
146
147         return 0;
148 }
149
150 MUTATOR_HOOKFUNCTION(nt_SetWeaponreplace)
151 {
152         // otherwise, we do replace
153         if(self.new_toys)
154         {
155                 // map defined replacement:
156                 ret_string = self.new_toys;
157         }
158         else
159         {
160                 // auto replacement:
161                 ret_string = nt_GetReplacement(other.netname, autocvar_g_new_toys_autoreplace);
162         }
163
164         // apply regular weaponreplace
165         ret_string = W_Apply_Weaponreplace(ret_string);
166
167         return 0;
168 }
169
170 MUTATOR_DEFINITION(mutator_new_toys)
171 {
172         MUTATOR_HOOK(SetModname, nt_SetModname, CBC_ORDER_ANY);
173         MUTATOR_HOOK(SetStartItems, nt_SetStartItems, CBC_ORDER_ANY);
174         MUTATOR_HOOK(SetWeaponreplace, nt_SetWeaponreplace, CBC_ORDER_LAST);
175
176         MUTATOR_ONADD
177         {
178                 if(time > 1) // game loads at time 1
179                         error("This cannot be added at runtime\n");
180
181                 // mark all guns as ok to use by e.g. impulse 99
182                 float i;
183                 for(i = WEP_FIRST; i <= WEP_LAST; ++i)
184                 {
185                         entity e = get_weaponinfo(i);
186                         if(e.weapon)
187                                 e.spawnflags &~= WEP_FLAG_MUTATORBLOCKED;
188                 }
189         }
190         MUTATOR_ONREMOVE
191         {
192                 error("This cannot be removed at runtime\n");
193         }
194
195         return 0;
196 }