]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/mutator_new_toys.qc
Merge remote-tracking branch 'origin/master' into samual/notification_rewrite
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / mutator_new_toys.qc
index f702c06f187183aa0ea49c19b5fcb2214f3d2c7c..6ee3e87b3c193e52354dd4e9e40301a8b6a756fc 100644 (file)
@@ -13,7 +13,7 @@ How this mutator works:
  =======================
 
 When a gun tries to spawn, this mutator is called. It will provide alternate
  =======================
 
 When a gun tries to spawn, this mutator is called. It will provide alternate
-default values of weaponreplace lists.
+weaponreplace lists.
 
 Entity:
 
 
 Entity:
 
@@ -41,6 +41,8 @@ There will be two default replacements selectable: "replace all" and "replace ra
 In "replace all" mode, e.g. Nex will have the default replacement "rifle".
 In "replace random" mode, Nex will have the default replacement "nex rifle".
 
 In "replace all" mode, e.g. Nex will have the default replacement "rifle".
 In "replace random" mode, Nex will have the default replacement "nex rifle".
 
+This mutator's replacements run BEFORE regular weaponreplace!
+
 The New Toys guns do NOT get a spawn function, so they can only ever be spawned
 when this mutator is active.
 
 The New Toys guns do NOT get a spawn function, so they can only ever be spawned
 when this mutator is active.
 
@@ -53,7 +55,173 @@ Outside this mutator, they still can be spawned by:
 - weaponreplace
 - weaponarena (but all and most weapons arena again won't include them)
 
 - weaponreplace
 - weaponarena (but all and most weapons arena again won't include them)
 
-Also, this mutator performs the default replacements on the DEFAULTS of the
+This mutator performs the default replacements on the DEFAULTS of the
 start weapon selection.
 
 start weapon selection.
 
+These weapons appear in the menu's priority list, BUT get a suffix
+"(Mutator weapon)".
+
+Picking up a "new toys" weapon will not play standard weapon pickup sound, but
+roflsound "New toys, new toys!" sound.
+
 */
 */
+
+.string new_toys;
+
+float autocvar_g_new_toys_autoreplace;
+#define NT_AUTOREPLACE_NEVER 0
+#define NT_AUTOREPLACE_ALWAYS 1
+#define NT_AUTOREPLACE_RANDOM 2
+
+MUTATOR_HOOKFUNCTION(nt_SetModname)
+{
+       modname = "NewToys";
+       return 0;
+}
+
+float nt_IsNewToy(float w)
+{
+       switch(w)
+       {
+               case WEP_SEEKER:
+               case WEP_MINE_LAYER:
+               case WEP_HLAC:
+               case WEP_RIFLE:
+                       return TRUE;
+               default:
+                       return FALSE;
+       }
+}
+
+string nt_GetFullReplacement(string w)
+{
+       switch(w)
+       {
+               case "hagar": return "seeker";
+               case "rocketlauncher": return "minelayer";
+               case "uzi": return "hlac";
+               case "nex": return "rifle";
+               default: return string_null;
+       }
+}
+
+string nt_GetReplacement(string w, float m)
+{
+       if(m == NT_AUTOREPLACE_NEVER)
+               return w;
+       string s = nt_GetFullReplacement(w);
+       if not(s)
+               return w;
+       if(m == NT_AUTOREPLACE_RANDOM)
+               s = strcat(w, " ", s);
+       return s;
+}
+
+MUTATOR_HOOKFUNCTION(nt_SetStartItems)
+{
+       // rearrange start_weapon_default
+       // apply those bits that are set by start_weapon_defaultmask
+       // same for warmup
+
+       float i, j, k, n;
+
+       WEPSET_DECLARE_A(newdefault);
+       WEPSET_DECLARE_A(warmup_newdefault);
+       
+       WEPSET_CLEAR_A(newdefault);
+       WEPSET_CLEAR_A(warmup_newdefault);
+
+       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+       {
+               entity e = get_weaponinfo(i);
+               if(!e.weapon)
+                       continue;
+
+               n = tokenize_console(nt_GetReplacement(e.netname, autocvar_g_new_toys_autoreplace));
+
+               for(j = 0; j < n; ++j)
+                       for(k = WEP_FIRST; k <= WEP_LAST; ++k)
+                               if(get_weaponinfo(k).netname == argv(j))
+                               {
+                                       if(WEPSET_CONTAINS_AW(start_weapons, i))
+                                               WEPSET_OR_AW(newdefault, k);
+                                       if(WEPSET_CONTAINS_AW(warmup_start_weapons, i))
+                                               WEPSET_OR_AW(warmup_newdefault, k);
+                               }
+       }
+
+       WEPSET_AND_AA(newdefault, start_weapons_defaultmask);
+       WEPSET_ANDNOT_AA(start_weapons, start_weapons_defaultmask);
+       WEPSET_OR_AA(start_weapons, newdefault);
+
+       WEPSET_AND_AA(warmup_newdefault, warmup_start_weapons_defaultmask);
+       WEPSET_ANDNOT_AA(warmup_start_weapons, warmup_start_weapons_defaultmask);
+       WEPSET_OR_AA(warmup_start_weapons, warmup_newdefault);
+
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(nt_SetWeaponreplace)
+{
+       // otherwise, we do replace
+       if(self.new_toys)
+       {
+               // map defined replacement:
+               ret_string = self.new_toys;
+       }
+       else
+       {
+               // auto replacement:
+               ret_string = nt_GetReplacement(other.netname, autocvar_g_new_toys_autoreplace);
+       }
+
+       // apply regular weaponreplace
+       ret_string = W_Apply_Weaponreplace(ret_string);
+
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(nt_FilterItem)
+{
+       if(nt_IsNewToy(self.weapon))
+               self.item_pickupsound = "weapons/weaponpickup_new_toys.ogg";
+       return 0;
+}
+
+MUTATOR_DEFINITION(mutator_new_toys)
+{
+       MUTATOR_HOOK(SetModname, nt_SetModname, CBC_ORDER_ANY);
+       MUTATOR_HOOK(SetStartItems, nt_SetStartItems, CBC_ORDER_ANY);
+       MUTATOR_HOOK(SetWeaponreplace, nt_SetWeaponreplace, CBC_ORDER_LAST);
+       MUTATOR_HOOK(FilterItem, nt_FilterItem, CBC_ORDER_ANY);
+
+       MUTATOR_ONADD
+       {
+               if(time > 1) // game loads at time 1
+                       error("This cannot be added at runtime\n");
+
+               precache_sound("weapons/weaponpickup_new_toys.ogg");
+
+               // mark the guns as ok to use by e.g. impulse 99
+               float i;
+               for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+                       if(nt_IsNewToy(i))
+                               get_weaponinfo(i).spawnflags &~= WEP_FLAG_MUTATORBLOCKED;
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               float i;
+               for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+                       if(nt_IsNewToy(i))
+                               get_weaponinfo(i).spawnflags |= WEP_FLAG_MUTATORBLOCKED;
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               print("This cannot be removed at runtime\n");
+               return -1;
+       }
+
+       return 0;
+}