diff --git a/addons/sourcemod/scripting/weapons.sp b/addons/sourcemod/scripting/weapons.sp index 0697c0ac..556eda0e 100644 --- a/addons/sourcemod/scripting/weapons.sp +++ b/addons/sourcemod/scripting/weapons.sp @@ -92,6 +92,8 @@ public void OnPluginStart() g_Cvar_EnableWeaponOverwrite = CreateConVar("sm_weapons_enable_overwrite", "1", "Enable/Disable players overwriting other players' weapons (picked up from the ground) by using !ws command"); g_Cvar_GracePeriod = CreateConVar("sm_weapons_grace_period", "0", "Grace period in terms of seconds counted after round start for allowing the use of !ws command. 0 means no restrictions"); g_Cvar_InactiveDays = CreateConVar("sm_weapons_inactive_days", "30", "Number of days before a player (SteamID) is marked as inactive and his data is deleted. (0 or any negative value to disable deleting)"); + g_Cvar_EnableC4 = CreateConVar("sm_weapons_enable_c4", "1", "Enable/Disable C4 Skins"); + g_Cvar_EnableAllSkins = CreateConVar("sm_weapons_enable_all_skins", "1", "Enable/Disable showing all skins in menu"); AutoExecConfig(true, "weapons"); @@ -310,7 +312,7 @@ void SetWeaponProps(int client, int entity) static int IDHigh = 16384; SetEntProp(entity, Prop_Send, "m_iItemIDLow", -1); SetEntProp(entity, Prop_Send, "m_iItemIDHigh", IDHigh++); - SetEntProp(entity, Prop_Send, "m_nFallbackPaintKit", g_iSkins[client][index] == -1 ? GetRandomSkin(client, index) : g_iSkins[client][index]); + SetEntProp(entity, Prop_Send, "m_nFallbackPaintKit", g_iSkins[client][index] == -1 ? GetRandomSkin(client, index) : g_iSkins[client][index] == -2 ? GetRandomAllSkin(client, index) : g_iSkins[client][index]); SetEntPropFloat(entity, Prop_Send, "m_flFallbackWear", !g_bEnableFloat || g_fFloatValue[client][index] == 0.0 ? 0.000001 : g_fFloatValue[client][index] == 1.0 ? 0.999999 : g_fFloatValue[client][index]); if (g_bEnableSeed && g_iWeaponSeed[client][index] != -1) { diff --git a/addons/sourcemod/scripting/weapons/config.sp b/addons/sourcemod/scripting/weapons/config.sp index 790fc0a5..788a87e8 100644 --- a/addons/sourcemod/scripting/weapons/config.sp +++ b/addons/sourcemod/scripting/weapons/config.sp @@ -67,6 +67,21 @@ public void ReadConfig() menuWeapons[langCounter][k].AddItem("-1", "Random"); menuWeapons[langCounter][k].ExitBackButton = true; } + + if(g_bAllSkins) { + for (int k = 0; k < sizeof(g_WeaponClasses); k++) + { + if(menuWeaponsAll[langCounter][k] != null) + { + delete menuWeaponsAll[langCounter][k]; + } + menuWeaponsAll[langCounter][k] = new Menu(WeaponsMenuAllHandler, MENU_ACTIONS_DEFAULT|MenuAction_DisplayItem); + menuWeaponsAll[langCounter][k].SetTitle("%T (%T)", g_WeaponClasses[k], LANG_SERVER, "AllSkins", LANG_SERVER); + menuWeaponsAll[langCounter][k].AddItem("0", "Default"); + menuWeaponsAll[langCounter][k].AddItem("-2", "Random"); + menuWeaponsAll[langCounter][k].ExitBackButton = true; + } + } int counter = 0; char weaponTemp[20]; @@ -74,6 +89,7 @@ public void ReadConfig() char name[64]; char index[5]; char classes[1024]; + int weaponIndex; KvGetSectionName(kv, name, sizeof(name)); KvGetString(kv, "classes", classes, sizeof(classes)); @@ -85,6 +101,15 @@ public void ReadConfig() if(StrContains(classes, weaponTemp) > -1) { menuWeapons[langCounter][k].AddItem(index, name); + weaponIndex = k; + } + } + if(g_bAllSkins) { + char nameWeapon[64]; + Format(nameWeapon, sizeof(nameWeapon), "%s (%T)", name, g_WeaponClasses[weaponIndex], LANG_SERVER); + for (int k = 0; k < sizeof(g_WeaponClasses); k++) + { + menuWeaponsAll[langCounter][k].AddItem(index, nameWeapon); } } counter++; diff --git a/addons/sourcemod/scripting/weapons/database.sp b/addons/sourcemod/scripting/weapons/database.sp index 2fdb43ac..3dd253ad 100644 --- a/addons/sourcemod/scripting/weapons/database.sp +++ b/addons/sourcemod/scripting/weapons/database.sp @@ -485,7 +485,14 @@ void CreateMainTable(bool mysql, bool recreate = false) knife_skeleton_trak int(1) NOT NULL DEFAULT '0', \ knife_skeleton_trak_count int(10) NOT NULL DEFAULT '0', \ knife_skeleton_tag varchar(256) NOT NULL DEFAULT '', \ - knife_skeleton_seed int(10) NOT NULL DEFAULT '-1')"); + knife_skeleton_seed int(10) NOT NULL DEFAULT '-1', "); + index += FormatEx(createQuery[index], sizeof(createQuery) - index, " \ + c4 int(4) NOT NULL DEFAULT '0', \ + c4_float decimal(3,2) NOT NULL DEFAULT '0.0', \ + c4_trak int(1) NOT NULL DEFAULT '0', \ + c4_trak_count int(10) NOT NULL DEFAULT '0', \ + c4_tag varchar(256) NOT NULL DEFAULT '', \ + c4_seed int(10) NOT NULL DEFAULT '-1')"); if (mysql) { @@ -552,7 +559,10 @@ public void T_ReCreateMainTableCallback(Database database, DBResultSet results, knife_gypsy_jackknife_trak_count, knife_gypsy_jackknife_tag, knife_stiletto, knife_stiletto_float, knife_stiletto_trak, \ knife_stiletto_trak_count, knife_stiletto_tag, knife_widowmaker, knife_widowmaker_float, knife_widowmaker_trak, \ knife_widowmaker_trak_count, knife_widowmaker_tag, mp5sd, mp5sd_float, mp5sd_trak, mp5sd_trak_count, mp5sd_tag, knife_css, \ - knife_css_float, knife_css_trak, knife_css_trak_count, knife_css_tag, knife_css_seed) \ + knife_css_float, knife_css_trak, knife_css_trak_count, knife_css_tag, knife_css_seed, "); + index += FormatEx(migrateQuery[index], sizeof(migrateQuery) - index, " \ + c4, \ + c4_float, c4_trak, c4_trak_count, c4_tag, c4_seed) \ SELECT * FROM %sweapons_tmp", g_TablePrefix); db.Query(T_MigrateOldDataCallback, migrateQuery, mysql, DBPrio_High); @@ -609,6 +619,7 @@ public void T_CreateMainTableCallback(Database database, DBResultSet results, co { g_iMigrationStep = 0; AddWeaponColumns(mysql, "knife_ursus", false); + AddWeaponColumns(mysql, "c4", true); char createQuery[512]; Format(createQuery, sizeof(createQuery), " \ @@ -695,7 +706,8 @@ public void T_SeedColumnCallback(Database database, DBResultSet results, const c ADD COLUMN knife_gypsy_jackknife_seed int(10) NOT NULL DEFAULT '-1' AFTER knife_gypsy_jackknife_tag, \ ADD COLUMN knife_stiletto_seed int(10) NOT NULL DEFAULT '-1' AFTER knife_stiletto_tag, \ ADD COLUMN knife_widowmaker_seed int(10) NOT NULL DEFAULT '-1' AFTER knife_widowmaker_tag, \ - ADD COLUMN mp5sd_seed int(10) NOT NULL DEFAULT '-1' AFTER mp5sd_tag"); + ADD COLUMN mp5sd_seed int(10) NOT NULL DEFAULT '-1' AFTER mp5sd_tag, \ + ADD COLUMN c4_seed int(10) NOT NULL DEFAULT '-1' AFTER c4_tag"); db.Query(T_SeedConfirmationCallback, seedColumnsQuery, mysql, DBPrio_High); } diff --git a/addons/sourcemod/scripting/weapons/forwards.sp b/addons/sourcemod/scripting/weapons/forwards.sp index e390240e..a6dd3750 100644 --- a/addons/sourcemod/scripting/weapons/forwards.sp +++ b/addons/sourcemod/scripting/weapons/forwards.sp @@ -48,6 +48,8 @@ public void OnConfigsExecuted() g_iFloatIncrementPercentage = RoundFloat(g_fFloatIncrementSize * 100.0); g_bOverwriteEnabled = g_Cvar_EnableWeaponOverwrite.BoolValue; g_iGracePeriod = g_Cvar_GracePeriod.IntValue; + g_bEnableC4 = g_Cvar_EnableC4.BoolValue; + g_bAllSkins = g_Cvar_EnableAllSkins.BoolValue; if(g_iGracePeriod > 0) { HookEvent("round_start", OnRoundStart, EventHookMode_PostNoCopy); diff --git a/addons/sourcemod/scripting/weapons/globals.sp b/addons/sourcemod/scripting/weapons/globals.sp index 684f83d6..0029e984 100644 --- a/addons/sourcemod/scripting/weapons/globals.sp +++ b/addons/sourcemod/scripting/weapons/globals.sp @@ -22,7 +22,7 @@ char g_WeaponClasses[][] = { /*28*/ "weapon_ssg08", /*29*/ "weapon_aug", /*30*/ "weapon_sg556", /*31*/ "weapon_scar20", /*32*/ "weapon_g3sg1", /*33*/ "weapon_knife_karambit", /*34*/ "weapon_knife_m9_bayonet", /*35*/ "weapon_bayonet", /*36*/ "weapon_knife_survival_bowie", /*37*/ "weapon_knife_butterfly", /*38*/ "weapon_knife_flip", /*39*/ "weapon_knife_push", /*40*/ "weapon_knife_tactical", /*41*/ "weapon_knife_falchion", /*42*/ "weapon_knife_gut", /*43*/ "weapon_knife_ursus", /*44*/ "weapon_knife_gypsy_jackknife", /*45*/ "weapon_knife_stiletto", /*46*/ "weapon_knife_widowmaker", /*47*/ "weapon_mp5sd", /*48*/ "weapon_knife_css", /*49*/ "weapon_knife_cord", -/*50*/ "weapon_knife_canis", /*51*/ "weapon_knife_outdoor", /*52*/ "weapon_knife_skeleton" +/*50*/ "weapon_knife_canis", /*51*/ "weapon_knife_outdoor", /*52*/ "weapon_knife_skeleton", /*53*/ "weapon_c4" }; int g_iWeaponDefIndex[] = { @@ -32,7 +32,7 @@ int g_iWeaponDefIndex[] = { /*28*/ 40, /*29*/ 8, /*30*/ 39, /*31*/ 38, /*32*/ 11, /*33*/ 507, /*34*/ 508, /*35*/ 500, /*36*/ 514, /*37*/ 515, /*38*/ 505, /*39*/ 516, /*40*/ 509, /*41*/ 512, /*42*/ 506, /*43*/ 519, /*44*/ 520, /*45*/ 522, /*46*/ 523, /*47*/ 23, /*48*/ 503, /*49*/ 517, -/*50*/ 518, /*51*/ 521, /*52*/ 525 +/*50*/ 518, /*51*/ 521, /*52*/ 525, /*53*/ 49 }; int g_iKnifeIndices[] = { @@ -83,6 +83,12 @@ int g_iGracePeriod; ConVar g_Cvar_InactiveDays; int g_iGraceInactiveDays; +ConVar g_Cvar_EnableC4; +int g_bEnableC4; + +ConVar g_Cvar_EnableAllSkins; +int g_bAllSkins; + int g_iSkins[MAXPLAYERS+1][sizeof(g_WeaponClasses)]; int g_iStatTrak[MAXPLAYERS+1][sizeof(g_WeaponClasses)]; int g_iStatTrakCount[MAXPLAYERS+1][sizeof(g_WeaponClasses)]; @@ -119,6 +125,7 @@ char g_MigrationWeapons[][] = { char g_Language[MAX_LANG][32]; int g_iClientLanguage[MAXPLAYERS+1]; Menu menuWeapons[MAX_LANG][sizeof(g_WeaponClasses)]; +Menu menuWeaponsAll[MAX_LANG][sizeof(g_WeaponClasses)]; StringMap g_smWeaponIndex; StringMap g_smWeaponDefIndex; diff --git a/addons/sourcemod/scripting/weapons/helpers.sp b/addons/sourcemod/scripting/weapons/helpers.sp index ce937ba9..8430d1b3 100644 --- a/addons/sourcemod/scripting/weapons/helpers.sp +++ b/addons/sourcemod/scripting/weapons/helpers.sp @@ -48,6 +48,15 @@ int GetRandomSkin(int client, int index) return StringToInt(idStr); } +int GetRandomAllSkin(int client, int index) +{ + int max = menuWeaponsAll[g_iClientLanguage[client]][index].ItemCount; + int random = GetRandomInt(2, max); + char idStr[6]; + menuWeaponsAll[g_iClientLanguage[client]][index].GetItem(random, idStr, sizeof(idStr)); + return StringToInt(idStr); +} + int GetRandomKnife() { return g_iKnifeIndices[GetRandomInt(0, sizeof(g_iKnifeIndices) - 1)]; diff --git a/addons/sourcemod/scripting/weapons/menus.sp b/addons/sourcemod/scripting/weapons/menus.sp index aff712b0..325d260d 100644 --- a/addons/sourcemod/scripting/weapons/menus.sp +++ b/addons/sourcemod/scripting/weapons/menus.sp @@ -63,6 +63,76 @@ public int WeaponsMenuHandler(Menu menu, MenuAction action, int client, int sele Format(display, sizeof(display), "%T", "RandomSkin", client); return RedrawMenuItem(display); } + else if (StrEqual(info, "-2")) + { + Format(display, sizeof(display), "%T", "RandomAllSkin", client); + return RedrawMenuItem(display); + } + } + } + case MenuAction_Cancel: + { + if (IsClientInGame(client) && selection == MenuCancel_ExitBack) + { + int menuTime; + if((menuTime = GetRemainingGracePeriodSeconds(client)) >= 0) + { + CreateWeaponMenu(client).Display(client, menuTime); + } + } + } + } + return 0; +} + +public int WeaponsMenuAllHandler(Menu menu, MenuAction action, int client, int selection) +{ + switch(action) + { + case MenuAction_Select: + { + if(IsClientInGame(client)) + { + int index = g_iIndex[client]; + + char skinIdStr[32]; + menu.GetItem(selection, skinIdStr, sizeof(skinIdStr)); + int skinId = StringToInt(skinIdStr); + + g_iSkins[client][index] = skinId; + char updateFields[256]; + char weaponName[32]; + RemoveWeaponPrefix(g_WeaponClasses[index], weaponName, sizeof(weaponName)); + Format(updateFields, sizeof(updateFields), "%s = %d", weaponName, skinId); + UpdatePlayerData(client, updateFields); + + RefreshWeapon(client, index); + + DataPack pack; + CreateDataTimer(0.5, WeaponsMenuTimer, pack); + pack.WriteCell(menu); + pack.WriteCell(GetClientUserId(client)); + pack.WriteCell(GetMenuSelectionPosition()); + } + } + case MenuAction_DisplayItem: + { + if(IsClientInGame(client)) + { + char info[32]; + char display[64]; + menu.GetItem(selection, info, sizeof(info)); + + if (StrEqual(info, "0")) + { + Format(display, sizeof(display), "%T", "DefaultSkin", client); + return RedrawMenuItem(display); + } + else if (StrEqual(info, "-2")) + { + Format(display, sizeof(display), "%T", "RandomSkin", client); + return RedrawMenuItem(display); + } } } case MenuAction_Cancel: @@ -115,6 +185,14 @@ public int WeaponMenuHandler(Menu menu, MenuAction action, int client, int selec menuWeapons[g_iClientLanguage[client]][g_iIndex[client]].Display(client, menuTime); } } + if(StrEqual(buffer, "skinall")) + { + int menuTime; + if((menuTime = GetRemainingGracePeriodSeconds(client)) >= 0) + { + menuWeaponsAll[g_iClientLanguage[client]][g_iIndex[client]].Display(client, menuTime); + } + } else if(StrEqual(buffer, "float")) { int menuTime; @@ -624,6 +702,7 @@ Menu CreateAllWeaponsMenu(int client) char name[32]; for (int i = 0; i < sizeof(g_WeaponClasses); i++) { + if (!g_bEnableC4 && StrEqual(g_WeaponClasses[i], "weapon_c4")) continue; Format(name, sizeof(name), "%T", g_WeaponClasses[i], client); menu.AddItem(g_WeaponClasses[i], name); } @@ -682,6 +761,11 @@ Menu CreateWeaponMenu(int client) Format(buffer, sizeof(buffer), "%T", "SetSkin", client); menu.AddItem("skin", buffer); + if(g_bAllSkins) { + Format(buffer, sizeof(buffer), "%T (%T)", "SetSkin", client, "AllSkins", client); + menu.AddItem("skinall", buffer); + } + bool weaponHasSkin = (g_iSkins[client][index] != 0); if (g_bEnableFloat) @@ -789,6 +873,7 @@ Menu CreateMainMenu(int client) int weaponEntity = GetEntPropEnt(client, Prop_Send, "m_hMyWeapons", i); if(weaponEntity != -1 && GetWeaponClass(weaponEntity, weaponClass, sizeof(weaponClass))) { + if (!g_bEnableC4 && StrEqual(weaponClass, "weapon_c4")) continue; Format(weaponName, sizeof(weaponName), "%T", weaponClass, client); menu.AddItem(weaponClass, weaponName, (IsKnifeClass(weaponClass) && g_iKnife[client] == 0) ? ITEMDRAW_DISABLED : ITEMDRAW_DEFAULT); } diff --git a/addons/sourcemod/translations/weapons.phrases.txt b/addons/sourcemod/translations/weapons.phrases.txt index 1595c746..fecf5966 100644 --- a/addons/sourcemod/translations/weapons.phrases.txt +++ b/addons/sourcemod/translations/weapons.phrases.txt @@ -104,6 +104,10 @@ { "en" "Choose Skin" } + "AllSkins" + { + "en" "All Skins" + } "SetFloat" { "en" "Weapon Condition: " @@ -140,6 +144,10 @@ { "en" "M4A1-S" } + "weapon_c4" + { + "en" "C4" + } "weapon_cz75a" { "en" "CZ75-Auto"