From 99b0a6aa12af3f00c46ac3566ab32527cec54ff2 Mon Sep 17 00:00:00 2001 From: jenz Date: Fri, 19 Jun 2026 20:57:51 +0200 Subject: [PATCH] AI generated update to add a feature for selecting randomized weapon selection on round spawn. --- .gitignore | 2 + src/zr/weapons/zmarket.inc | 118 ++++++++++++++++++++++++++++++++++++- 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 9aa2ddd..eee183b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ src/zr/hgversion.h.inc +cstrike/ + build/ release/ docs/changes/ diff --git a/src/zr/weapons/zmarket.inc b/src/zr/weapons/zmarket.inc index 7046b4b..cc98b81 100644 --- a/src/zr/weapons/zmarket.inc +++ b/src/zr/weapons/zmarket.inc @@ -30,6 +30,7 @@ */ #define ZMARKET_COOKIE_AUTOREBUY "zr_zmarket_autorebuy" #define ZMARKET_COOKIE_REBUY "zr_zmarket_rebuy" +#define ZMARKET_COOKIE_RANDOMIZE "zr_zmarket_randomize" /** * @endsection */ @@ -39,6 +40,14 @@ */ #define ZMARKET_REBUY_WEAPONS_SLOTS_MAX 1 + +/** + * 2026 randomization of zmarket guns for round start. +*/ +new Handle:g_hZMarketRandomizeCookie = INVALID_HANDLE; +new bool:g_bZMarketRandomize[MAXPLAYERS + 1]; +new String:g_sZMarketRandomHistoryPrimary[MAXPLAYERS + 1][3][WEAPONS_MAX_LENGTH]; + /** * Array to store the client's current weapon type within menu. */ @@ -90,6 +99,12 @@ ZMarketOnCookiesCreate() g_hZMarketLoadoutCookie[x] = RegClientCookie(rebuycookiename, rebuycookiedesc, CookieAccess_Protected); } } + + // Randomize toggle cookie. + if (g_hZMarketRandomizeCookie == INVALID_HANDLE) + { + g_hZMarketRandomizeCookie = RegClientCookie(ZMARKET_COOKIE_RANDOMIZE, "Whether weapon randomization is enabled", CookieAccess_Protected); + } } ZMarketLoad() @@ -207,6 +222,12 @@ ZMarketClientInit(client) // No weapons bought automatically. g_bZMarketWeaponsBought[client] = false; + + // Clear randomize weapon history. + for (new i = 0; i < 3; i++) + { + g_sZMarketRandomHistoryPrimary[client][i][0] = '\0'; + } } /** @@ -216,6 +237,10 @@ ZMarketClientInit(client) */ ZMarketOnCookiesCached(client) { + decl String:value[4]; + GetClientCookie(client, g_hZMarketRandomizeCookie, value, sizeof(value)); + g_bZMarketRandomize[client] = (value[0] == '1'); + // Rebuy wapons (if auto-rebuy is enabled, and not bought already). if (!g_bZMarketWeaponsBought[client]) { @@ -371,6 +396,7 @@ bool:ZMarketMenuMain(client) decl String:editloadout[MENU_LINE_REG_LENGTH]; decl String:rebuy[MENU_LINE_REG_LENGTH]; decl String:weaponslist[MENU_LINE_REG_LENGTH]; + decl String:randomize[MENU_LINE_REG_LENGTH]; // Format menu options. Format(title, sizeof(title), "%t\n ", "Weapons menu zmarket main title"); @@ -378,6 +404,7 @@ bool:ZMarketMenuMain(client) Format(editloadout, sizeof(editloadout), "%t", "Weapons menu zmarket main edit loadout"); Format(rebuy, sizeof(rebuy), "%t", "Weapons menu zmarket main rebuy"); Format(weaponslist, sizeof(weaponslist), "%t", "Weapons menu zmarket main weapons list"); + Format(randomize, sizeof(randomize), "Randomize Weapons: %s", g_bZMarketRandomize[client] ? "ON" : "OFF"); // Add formatted options to menu. SetMenuTitle(menu_zmarket_main, title); @@ -385,6 +412,7 @@ bool:ZMarketMenuMain(client) AddMenuItem(menu_zmarket_main, "Edit Loadout", editloadout, MenuGetItemDraw(zmarketrebuy || zmarketrebuyauto)); AddMenuItem(menu_zmarket_main, "Rebuy", rebuy, MenuGetItemDraw(zmarketrebuy || zmarketrebuyauto)); AddMenuItem(menu_zmarket_main, "Weapons List", weaponslist); + AddMenuItem(menu_zmarket_main, "Randomize", randomize); // Set exit back button. SetMenuExitBackButton(menu_zmarket_main, true); @@ -440,6 +468,18 @@ public ZMarketMenuMainHandle(Handle:menu_zmarket_main, MenuAction:action, client // Send the weapon types list. ZMarketMenuTypes(client); } + case 4: + { + // Toggle randomize. + g_bZMarketRandomize[client] = !g_bZMarketRandomize[client]; + + decl String:value[4]; + Format(value, sizeof(value), "%d", g_bZMarketRandomize[client] ? 1 : 0); + SetClientCookie(client, g_hZMarketRandomizeCookie, value); + PrintToChat(client, "Weapons zmarket randomize toggled: %s", g_bZMarketRandomize[client] ? "ON" : "OFF"); + + ZMarketMenuMain(client); + } } } // Client closed the menu. @@ -1305,6 +1345,75 @@ stock ZMarketSetRebuyCookie(client, WeaponsSlot:slot, const String:value[]) CloseHandle(rebuycookie); } +/** + * Picks a random weapon name from the given slot, avoiding the client's + * last 3 picks for the primiary slot. + * + * @param client The client index. + * @param slot Slot_Primary + * @param buffer Output buffer for the weapon name. + * @param maxlen Size of buffer. + */ +stock ZMarketGetRandomWeaponForSlot(client, WeaponsSlot:slot, String:buffer[], maxlen) +{ + new Handle:candidates = CreateArray(WEAPONS_MAX_LENGTH); + + new size = GetArraySize(arrayWeapons); + decl String:weaponname[WEAPONS_MAX_LENGTH]; + + for (new i = 0; i < size; i++) + { + if (WeaponsGetSlot(i) != slot) + continue; + + WeaponsGetName(i, weaponname, sizeof(weaponname)); + + // Skip if restricted. + if (RestrictIsWeaponRestricted(i)) + continue; + + // Skip if in the client's last-3 history for this slot. + new bool:inHistory = false; + for (new h = 0; h < 3; h++) + { + decl String:histEntry[WEAPONS_MAX_LENGTH]; + if (slot == Slot_Primary) + strcopy(histEntry, sizeof(histEntry), g_sZMarketRandomHistoryPrimary[client][h]); + if (StrEqual(histEntry, weaponname)) + { + inHistory = true; + break; + } + } + + if (inHistory) + continue; + + PushArrayString(candidates, weaponname); + } + + new candidateCount = GetArraySize(candidates); + + if (candidateCount == 0) + { + buffer[0] = '\0'; + CloseHandle(candidates); + return; + } + + new pick = Math_GetRandomInt(0, candidateCount - 1); + GetArrayString(candidates, pick, buffer, maxlen); + CloseHandle(candidates); + + // Push into history (shift, then insert at front). + if (slot == Slot_Primary) + { + strcopy(g_sZMarketRandomHistoryPrimary[client][2], WEAPONS_MAX_LENGTH, g_sZMarketRandomHistoryPrimary[client][1]); + strcopy(g_sZMarketRandomHistoryPrimary[client][1], WEAPONS_MAX_LENGTH, g_sZMarketRandomHistoryPrimary[client][0]); + strcopy(g_sZMarketRandomHistoryPrimary[client][0], WEAPONS_MAX_LENGTH, buffer); + } +} + /** * Force a client to rebuy their weapons. * @@ -1340,9 +1449,14 @@ ZMarketRebuy(client, bool:autorebuy = false) // x = Weapon slot. for (new x = 0; x < ZMARKET_REBUY_WEAPONS_SLOTS_MAX + 1; x++) { - // If slot is empty, then use the default value. - if (!rebuyweapons[x][0]) + // If randomize is enabled, override any saved loadout for primary/secondary. + if (g_bZMarketRandomize[client] && (x == Slot_Primary || x == Slot_Secondary)) { + ZMarketGetRandomWeaponForSlot(client, WeaponsSlot:x, rebuyweapons[x], sizeof(rebuyweapons[])); + } + else if (!rebuyweapons[x][0]) + { + // No saved loadout, fall back to cvar default. switch(x) { case Slot_Primary: