From c529a1ed619faa1c171cc7aa666a2faa866c0c8f Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Tue, 14 Jan 2025 22:21:12 +1000 Subject: [PATCH] Implement weapon availability warnings for custom weapon groups Fixes "AOL CD Thrower is not available" (see previous commit and #2380) when using a cl_weaponpriorityN custom weapon group and none of its weapons are on the map. Refactors and somewhat documents the `have_other` checking for compatibility, performance and clarity. --- qcsrc/server/weapons/selection.qc | 36 +++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/qcsrc/server/weapons/selection.qc b/qcsrc/server/weapons/selection.qc index bbddb70c7..efef6aaa3 100644 --- a/qcsrc/server/weapons/selection.qc +++ b/qcsrc/server/weapons/selection.qc @@ -139,6 +139,7 @@ float W_GetCycleWeapon(entity this, string weaponorder, float dir, float imp, bo first_valid = prev_valid = 0; float weaponcur; entity wep; + string rest; if(skipmissing || this.(weaponentity).selectweapon == 0) weaponcur = this.(weaponentity).m_switchweapon.m_id; @@ -152,8 +153,33 @@ float W_GetCycleWeapon(entity this, string weaponorder, float dir, float imp, bo int c = 0; entity wepcomplain = NULL; int wepcomplainindex = 0; + bool have_other = false; - string rest = weaponorder; + // see if we have or can locate (not hidden), some other weapon in the group + WepSet customgroup = '0 0 0'; + if(imp < 0) // custom cl_weaponpriorityN group + { + // These groups are client-specific, and (imp == -1) here, + // so generate a weapon set bitmask to represent the group. + rest = weaponorder; + while(rest != "") + { + weaponwant = stof(car(rest)); rest = cdr(rest); + customgroup |= REGISTRY_GET(Weapons, weaponwant).m_wepset; + } + } + else {} // standard weapon_group, defined by impulse sharing + FOREACH(Weapons, (imp >= 0 && it.impulse == imp) || (imp < 0 && (it.m_wepset & customgroup)), + { + if ((it.m_wepset & STAT(WEAPONS, this)) + || (it.m_wepset & weaponsInMap)) + { + have_other = true; + break; + } + }); + + rest = weaponorder; while(rest != "") { weaponwant = stof(car(rest)); rest = cdr(rest); @@ -163,14 +189,6 @@ float W_GetCycleWeapon(entity this, string weaponorder, float dir, float imp, bo if(wep.impulse != imp) continue; - bool have_other = false; - FOREACH(Weapons, it != WEP_Null, { - if(i != weaponwant) - if(it.impulse == imp || imp < 0) - if((STAT(WEAPONS, this) | weaponsInMap) & it.m_wepset) - have_other = true; - }); - // skip weapons we don't own that aren't normal and aren't in the map if(!(STAT(WEAPONS, this) & wepset)) if(!(weaponsInMap & wepset)) -- 2.39.5