From 95f11d6f6db015fe421b64f1c769aa0badc41fe5 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Mon, 5 Mar 2012 12:07:19 +0100 Subject: [PATCH] more new toys related stuff --- qcsrc/common/items.qh | 19 ++-- qcsrc/server/cl_weapons.qc | 17 +++ qcsrc/server/defs.qh | 1 + qcsrc/server/miscfunctions.qc | 10 +- qcsrc/server/mutators/base.qh | 7 ++ qcsrc/server/mutators/mutator_new_toys.qc | 128 +++++++++++++++++----- qcsrc/server/t_items.qc | 13 ++- 7 files changed, 154 insertions(+), 41 deletions(-) diff --git a/qcsrc/common/items.qh b/qcsrc/common/items.qh index c022d2672..81f49a476 100644 --- a/qcsrc/common/items.qh +++ b/qcsrc/common/items.qh @@ -2,15 +2,16 @@ float BOT_PICKUP_RATING_LOW = 2500; float BOT_PICKUP_RATING_MID = 5000; float BOT_PICKUP_RATING_HIGH = 10000; -float WEP_TYPE_OTHER = 0x00; // e.g: Hook, Port-o-launch, etc -float WEP_TYPE_SPLASH = 0x01; -float WEP_TYPE_HITSCAN = 0x02; -float WEP_TYPEMASK = 0x0F; -float WEP_FLAG_CANCLIMB = 0x10; -float WEP_FLAG_NORMAL = 0x20; -float WEP_FLAG_HIDDEN = 0x40; -float WEP_FLAG_RELOADABLE = 0x80; -float WEP_FLAG_SUPERWEAPON = 0x100; +float WEP_TYPE_OTHER = 0x00; // not for damaging people +float WEP_TYPE_SPLASH = 0x01; // splash damage +float WEP_TYPE_HITSCAN = 0x02; // hitscan +float WEP_TYPEMASK = 0x0F; +float WEP_FLAG_CANCLIMB = 0x10; // can be used for movement +float WEP_FLAG_NORMAL = 0x20; // in "most weapons" set +float WEP_FLAG_HIDDEN = 0x40; // hides from menu +float WEP_FLAG_RELOADABLE = 0x80; // can has reload +float WEP_FLAG_SUPERWEAPON = 0x100; // powerup timer +float WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag) float IT_UNLIMITED_WEAPON_AMMO = 1; // when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup. diff --git a/qcsrc/server/cl_weapons.qc b/qcsrc/server/cl_weapons.qc index 60ad8eee1..078455a12 100644 --- a/qcsrc/server/cl_weapons.qc +++ b/qcsrc/server/cl_weapons.qc @@ -513,3 +513,20 @@ void W_WeaponFrame() self.currentammo = 1; #endif } + +string W_Apply_Weaponreplace(string in) +{ + string newlist; + float n = tokenize_console(in); + string out = ""; + for(i = 0; i < n; ++i) + { + string s = argv(i); + string r = cvar_string(strcat("g_weaponreplace_", s)); + if(r == "") + out = strcat(out, " ", s); + else if(r != "0") + out = strcat(out, " ", r); + } + return substring(out, 1); +} diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index 7581a7d71..47a72d904 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -350,6 +350,7 @@ floatfield Item_CounterField(float it); float W_AmmoItemCode(float wpn); string W_Name(float weaponid); +string W_Apply_Weaponreplace(string in); void FixIntermissionClient(entity e); void FixClientCvars(entity e); diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 9da8a97df..2abf89188 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -796,6 +796,8 @@ float want_weapon(string cvarprefix, entity weaponinfo, float allguns) d = (i == WEP_LASER || i == WEP_SHOTGUN); if(g_grappling_hook) // if possible, redirect off-hand hook to on-hand hook d |= (i == WEP_HOOK); + if(weaponinfo.spawnflags & WEP_FLAG_MUTATORBLOCKED) // never default mutator blocked guns + d = 0; var float t = cvar(strcat(cvarprefix, weaponinfo.netname)); @@ -852,7 +854,8 @@ void readplayerstartcvars() g_weaponarena = 1; g_weaponarena_list = "All Weapons"; for (j = WEP_FIRST; j <= WEP_LAST; ++j) - WEPSET_OR_AW(g_weaponarena_weapons, j); + if not(e.spawnflags & WEP_FLAG_MUTATORBLOCKED) + WEPSET_OR_AW(g_weaponarena_weapons, j); } else if (s == "most") { @@ -861,8 +864,9 @@ void readplayerstartcvars() for (j = WEP_FIRST; j <= WEP_LAST; ++j) { e = get_weaponinfo(j); - if (e.spawnflags & WEP_FLAG_NORMAL) - WEPSET_OR_AW(g_weaponarena_weapons, j); + if not(e.spawnflags & WEP_FLAG_MUTATORBLOCKED) + if (e.spawnflags & WEP_FLAG_NORMAL) + WEPSET_OR_AW(g_weaponarena_weapons, j); } } else if (s == "none") diff --git a/qcsrc/server/mutators/base.qh b/qcsrc/server/mutators/base.qh index 137eebadb..09e270389 100644 --- a/qcsrc/server/mutators/base.qh +++ b/qcsrc/server/mutators/base.qh @@ -205,3 +205,10 @@ MUTATOR_HOOKABLE(SV_StartFrame); MUTATOR_HOOKABLE(SetModname); // OUT string modname; // name of the mutator/mod if it warrants showing as such in the server browser + +MUTATOR_HOOKABLE(SetDefaultWeaponreplace); + // IN + entity self; // map entity + entity other; // weapon info + // IN+OUT + string ret_string; diff --git a/qcsrc/server/mutators/mutator_new_toys.qc b/qcsrc/server/mutators/mutator_new_toys.qc index df78d2765..461272e7e 100644 --- a/qcsrc/server/mutators/mutator_new_toys.qc +++ b/qcsrc/server/mutators/mutator_new_toys.qc @@ -13,7 +13,7 @@ How this mutator works: ======================= When a gun tries to spawn, this mutator is called. It will provide alternate -default values of weaponreplace lists. +weaponreplace lists. Entity: @@ -43,8 +43,8 @@ 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. Likewise, warmup, give all, give ALL and impulse 99 will not give them unless this mutator is active. @@ -55,38 +55,47 @@ Outside this mutator, they still can be spawned by: - 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. -Also: these weapons appear in the menu's priority list, BUT get a suffix -"(Mutator weapon)". + 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. + Picking up a "new toys" weapon will not play standard weapon pickup sound, but + roflsound "New toys, new toys!" sound. */ -string i_herd_yo_liek_weaponreplace(string replacement) +float autocvar_g_new_toys_autoreplace = 2; // 0 = never, 1 = always, 2 = random + +MUTATOR_HOOKFUNCTION(nt_SetModname) +{ + modname = "NewToys"; + return 0; +} + +string nt_GetFullReplacement(string w) { - string newlist; - float n = tokenize_console(replacement); - string out = ""; - for(i = 0; i < n; ++i) + switch(w) { - string s = argv(i); - string r = cvar_string(strcat("g_weaponreplace_", s)); - if(r == "") - out = strcat(out, " ", s); - else if(r != "0") - out = strcat(out, " ", r); + case "hagar": return "seeker"; + case "rocketlauncher": return "minelayer"; + case "uzi": return "hlac"; + case "nex": return "rifle"; + default: return string_null; } - return substring(out, 1); } -MUTATOR_HOOKFUNCTION(nt_SetModname) +string nt_GetReplacement(string w, float m) { - modname = "NewToys"; - return 0; + if(m == 0) + return w; + string s = nt_GetFullReplacement(w); + if not(s) + return w; + if(m == 2) + s = strcat(w, " ", s); + return s; } MUTATOR_HOOKFUNCTION(nt_SetStartItems) @@ -94,19 +103,88 @@ MUTATOR_HOOKFUNCTION(nt_SetStartItems) // rearrange start_weapon_default // apply those bits that are set by start_weapon_defaultmask // same for warmup - // TODO + + 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 if(autocvar_g_new_toys_autoreplace) + { + // auto replacement: + ret_string = nt_GetReplacement(other.netname, autocvar_g_new_toys_autoreplace); + } + else + { + ret_string = other.netname; + } + + // apply regular weaponreplace + ret_string = W_Apply_Weaponreplace(ret_string); + return 0; } MUTATOR_DEFINITION(mutator_new_toys) { MUTATOR_HOOK(SetModname, nt_SetModname, CBC_ORDER_ANY); - MUTATOR_HOOK(SetStartItems, nix_SetStartItems, CBC_ORDER_ANY); + MUTATOR_HOOK(SetStartItems, nt_SetStartItems, CBC_ORDER_ANY); + MUTATOR_HOOK(SetWeaponreplace, nt_SetWeaponreplace, CBC_ORDER_LAST); MUTATOR_ONADD { if(time > 1) // game loads at time 1 error("This cannot be added at runtime\n"); + + // mark all guns as ok to use by e.g. impulse 99 + float i; + for(i = WEP_FIRST; i <= WEP_LAST; ++i) + { + entity e = get_weaponinfo(i); + if(e.weapon) + e.spawnflags &~= WEP_FLAG_MUTATORBLOCKED; + } } MUTATOR_ONREMOVE { diff --git a/qcsrc/server/t_items.qc b/qcsrc/server/t_items.qc index 47c945ee5..d72cfef87 100644 --- a/qcsrc/server/t_items.qc +++ b/qcsrc/server/t_items.qc @@ -988,8 +988,12 @@ void weapon_defaultspawnfunc(float wpn) if(self.classname != "droppedweapon" && self.classname != "replacedweapon") { e = get_weaponinfo(wpn); - s = cvar_string(strcat("g_weaponreplace_", e.netname)); - if(s == "0") + s = W_Apply_Weaponreplace(e.netname); + ret_string = s; + other = e; + MUTATOR_CALLHOOK(SetDefaultWeaponreplace); + s = ret_string; + if(s == "") { remove(self); startitem_failed = TRUE; @@ -1022,7 +1026,7 @@ void weapon_defaultspawnfunc(float wpn) } self = oldself; } - if(t >= 1) + if(t >= 1) // always the case! { s = argv(0); wpn = 0; @@ -1710,7 +1714,8 @@ float GiveItems(entity e, float beginarg, float endarg) { wi = get_weaponinfo(j); if(wi.weapon) - got += GiveWeapon(e, j, op, val); + if not(wi.spawnflags & WEP_FLAG_MUTATORBLOCKED) + got += GiveWeapon(e, j, op, val); } case "allammo": got += GiveValue(e, ammo_cells, op, val); -- 2.39.2