diff --git a/plugins/tf2item_cosmetics.smx b/plugins/tf2item_cosmetics.smx index 8ce627f..ae8d217 100644 Binary files a/plugins/tf2item_cosmetics.smx and b/plugins/tf2item_cosmetics.smx differ diff --git a/plugins/tf2item_weapons.smx b/plugins/tf2item_weapons.smx index ce67375..ffc7bc5 100644 Binary files a/plugins/tf2item_weapons.smx and b/plugins/tf2item_weapons.smx differ diff --git a/scripting/tf2item_cosmetics.sp b/scripting/tf2item_cosmetics.sp index e679a9e..15238b4 100644 --- a/scripting/tf2item_cosmetics.sp +++ b/scripting/tf2item_cosmetics.sp @@ -3,7 +3,7 @@ #pragma semicolon 1 #pragma newdecls required -#define PLUGIN_VERSION "3.0.0" +#define PLUGIN_VERSION "3.0.1" public Plugin myinfo = { @@ -70,6 +70,12 @@ public void OnPluginStart() // Translations! } +// Hook spawns if the ConVar is on +public void OnMapStart() { + if (CV_OnlySpawn.BoolValue) + HookRespawns(); +} + public void OnClientPostAdminCheck(int client) { for (int i = 0; i < 3; i++) pCosmetics[client].ResetFor(i); @@ -88,7 +94,10 @@ public Action CMD_My(int client, int args) { public Action CMD_Cosmetics(int client, int args) { - GenerateHatsMenu(client); + if (CV_OnlySpawn.BoolValue && !bPlayerInSpawn[client]) + CReplyToCommand(client, "%s This server does not allow you to utilize this command outside of spawn.", PGTAG); + else + GenerateHatsMenu(client); return Plugin_Handled; } @@ -447,7 +456,7 @@ void IntermediaryMenu(int client, int iItemDefinitionIndex, int slot) { intMenu.AddItem(slotStr, "", ITEMDRAW_IGNORE); int anyMatch = 0; - if (IsHatUnusual(iItemDefinitionIndex)) { + if (IsHatUnusual(iItemDefinitionIndex && CV_Cosmetics_Unusuals.BoolValue)) { int effect = pCosmetics[client].uEffects[slot]; if (effect < 1 || pCosmetics[client].iItemIndex[slot] != iItemDefinitionIndex) @@ -463,7 +472,7 @@ void IntermediaryMenu(int client, int iItemDefinitionIndex, int slot) { intMenu.AddItem("unu", fName); anyMatch |= (1 << 0); - } if (IsHatPaintable(iItemDefinitionIndex)) { + } if (IsHatPaintable(iItemDefinitionIndex) && CV_Cosmetics_Paint.BoolValue) { int paint = pCosmetics[client].cPaint[slot]; char info[64]; @@ -481,7 +490,8 @@ void IntermediaryMenu(int client, int iItemDefinitionIndex, int slot) { static const char other[] = "Halloween Spells"; - intMenu.AddItem("other", other); + if (CV_Cosmetics_Spells.BoolValue) + intMenu.AddItem("other", other); anyMatch |= (1 << 1); } @@ -552,6 +562,11 @@ void OthersMenu(int client, const char[] name, int iItemDefinitionIndex, int slo // ForceChange() - Forces an SDKCall on the player to get the Unusual effects to be applied instantly. void ForceChange(int client, int slot) { + if (CV_OnlySpawn.BoolValue && !bPlayerInSpawn[client]) { + CPrintToChat(client, "%s You are not allowed to make changes outside of spawn!", PGTAG); + return; + } + int ent = -1; while ((ent = FindEntityByClassname(ent, "tf_wearable")) != INVALID_ENT_REFERENCE) { if (client == GetEntPropEnt(ent, Prop_Send, "m_hOwnerEntity")) { diff --git a/scripting/tf2item_weapons.sp b/scripting/tf2item_weapons.sp index bdf26df..eb2187b 100644 --- a/scripting/tf2item_weapons.sp +++ b/scripting/tf2item_weapons.sp @@ -3,7 +3,7 @@ #pragma semicolon 1 #pragma newdecls required -#define PLUGIN_VERSION "3.0.0" +#define PLUGIN_VERSION "3.0.1" public Plugin myinfo = { @@ -69,6 +69,11 @@ public void OnPluginStart() { LoadTranslations("weapons.phrases.txt"); // Translations! + // Hook onto player spawning / loadout reload (for special weapons to be given correctly) + HookEvent("player_spawn", OnPlayerSpawn); + HookEvent("post_inventory_application", OnPlayerSpawn); + + // Late loading reset if (bLateLoad) { for (int i = 1; i < MaxClients; i++) { if (IsClientInGame(i) && !IsClientSourceTV(i) && !IsFakeClient(i)) @@ -93,10 +98,18 @@ public void OnPluginStart() { }*/ public Action CMD_Weapons(int client, int args) { - mMainMenu(client); + if (CV_OnlySpawn.BoolValue && !bPlayerInSpawn[client]) + CReplyToCommand(client, "%s This server does not allow you to utilize this command outside of spawn.", PGTAG); + else + mMainMenu(client); return Plugin_Handled; } +public void OnMapStart() { + if (CV_OnlySpawn.BoolValue) + HookRespawns(); +} + // // Normal Menus Handlers //////////////////////// @@ -106,7 +119,30 @@ public int mainHdlr(Menu menu, MenuAction action, int client, int p2) { char sel[32]; GetMenuItem(menu, p2, sel, sizeof(sel)); - wMainMenu(client, StringToInt(sel), p2); + if (sel[0] == 's') { + // Special Weapon item was selected + // Create the ArrayList + ArrayList specials = new ArrayList(); + specials.Push(-1); + specials.Push(1071); + specials.Push(423); + specials.Push(169); + + // Push one index + int index = specials.FindValue(pWeapons[client].Special) + 1; + // If (for some reason) the value wasn't found, just set it to the 0 index override. + if (index == -1) index = 0; + + // Set the special weapon iItemDefinitionIndex + pWeapons[client].Special = index >= specials.Length ? specials.Get(0) : specials.Get(index); + + // Clear memory + delete specials; + + // Re-open menu to keep selections + mMainMenu(client); + } else + wMainMenu(client, StringToInt(sel), p2); } case MenuAction_End: delete menu; } @@ -465,11 +501,25 @@ public Action TF2Items_OnGiveNamedItem(int client, char[] classname, int iItemDe // Override detected for this item ID? if (overItemIndex == iItemDefinitionIndex) { // Declare item flags - int flags = OVERRIDE_ALL | PRESERVE_ATTRIBUTES | FORCE_GENERATION; + int flags = OVERRIDE_ALL | PRESERVE_ATTRIBUTES; // For some reason, if it's an allclass melee it requires the FORCE_GENERATION flag - if (StrContains(classname, "saxxy", false) != -1) + if (StrContains(classname, "saxxy", false) != -1) { flags |= FORCE_GENERATION; + + // Rewrite the weapon classname accordingly (to spawn the weapon properly) + switch (TF2_GetPlayerClass(client)) { + case TFClass_Scout: strcopy(classname, 64, "tf_weapon_bat"); + case TFClass_Pyro: strcopy(classname, 64, "tf_weapon_fireaxe"); + case TFClass_DemoMan: strcopy(classname, 64, "tf_weapon_bottle"); + case TFClass_Heavy: strcopy(classname, 64, "tf_weapon_fists"); + case TFClass_Engineer: strcopy(classname, 64, "tf_weapon_wrench"); + case TFClass_Medic: strcopy(classname, 64, "tf_weapon_bonesaw"); + case TFClass_Sniper: strcopy(classname, 64, "tf_weapon_club"); + case TFClass_Spy: strcopy(classname, 64, "tf_weapon_knife"); + default: strcopy(classname, 64, "tf_weapon_shovel"); + } + } // Is this a class based weapon? This is only for Shotgun weapons. // Shotgun variants: @@ -520,6 +570,46 @@ public void TF2Items_OnGiveNamedItem_Post(int client, char[] classname, int iIte SetEntProp(entityIndex, Prop_Send, "m_bValidatedAttachedEntity", 1); } +// Handle player spawns for Special Weapons +public void OnPlayerSpawn(Event event, const char[] name, bool dontBroadcast) { + // Get client that fired the event + int client = GetClientOfUserId(event.GetInt("userid")); + + // Do the necessary checks and if they pass, give the player their Special Weapon override. + GiveSpecialWeapon(client); +} + +// Give a Special Weapon to a player, transferring their attributes to it as well. +void GiveSpecialWeapon(int client) { + // Does this player have a special weapon selected? + if (pWeapons[client].Special > -1) { + // Detect if the melee weapon is being given + TFClassType class = TF2_GetPlayerClass(client); + + // Do not give the Golden Wrench if they're not an Engineer + if (pWeapons[client].Special == 169 && class != TFClass_Engineer) return; + + // Classname to send for the weapon spawn. + char classname[64]; + + // Re-write classname for the saxxy weapon + switch (class) { + case TFClass_Scout: strcopy(classname, 64, "tf_weapon_bat"); + case TFClass_Soldier: strcopy(classname, 64, "tf_weapon_shovel"); + case TFClass_Pyro: strcopy(classname, 64, "tf_weapon_fireaxe"); + case TFClass_DemoMan: strcopy(classname, 64, "tf_weapon_bottle"); + case TFClass_Heavy: strcopy(classname, 64, "tf_weapon_fists"); + case TFClass_Engineer: strcopy(classname, 64, "tf_weapon_wrench"); + case TFClass_Medic: strcopy(classname, 64, "tf_weapon_bonesaw"); + case TFClass_Sniper: strcopy(classname, 64, "tf_weapon_club"); + case TFClass_Spy: strcopy(classname, 64, "tf_weapon_knife"); + } + + // Time it to give the new weapon, we're done! + GiveStrangeWeapon(client, pWeapons[client].Special, classname, 2, OVERRIDE_ALL | PRESERVE_ATTRIBUTES | FORCE_GENERATION, true); + } +} + // Handle the Strange Variant to give. public Action HandleStrange(Handle timer, DataPack pack) { // Null the timer (prevent Handle leaks) @@ -536,6 +626,9 @@ public Action HandleStrange(Handle timer, DataPack pack) { int slot = pack.ReadCell(), flags = pack.ReadCell(); + // Delete the DataPack, we do not need it anymore + delete pack; + // Set-up the new weapon (strange variant of the stock) GiveStrangeWeapon(client, iItemDefinitionIndex, classname, slot, flags); @@ -544,7 +637,7 @@ public Action HandleStrange(Handle timer, DataPack pack) { } // Applies all attributes from overrides on the hItem handle and returns the proper response accordingly. -Action ApplyChanges(Handle& hItem, int client, int iItemDefinitionIndex, char[] classname, int slot, int flags, bool isNew = false) { +Action ApplyChanges(Handle& hItem, int client, int iItemDefinitionIndex, char[] classname, int slot, int flags, bool isNew = false, bool isSpecial = false) { hItem = TF2Items_CreateItem(flags); // Set the same ID (if it was stock it will now be the strange variant) @@ -599,7 +692,7 @@ Action ApplyChanges(Handle& hItem, int client, int iItemDefinitionIndex, char[] // 1007 - SPELL: Halloween pumpkin explosions (Squash Rockets, Sentry Quad-Pumpkings & Gourd Grenades) // // Total Possible Attributes: 13 (holy shit) - TF2Items_SetNumAttributes(hItem, 13); + TF2Items_SetNumAttributes(hItem, isSpecial ? 14 : 13); // Has Unusual override? int unusual = hasUnusual ? pWeapons[client].uEffects[slot] : orgWeapons[client][slot].uEffects; @@ -614,7 +707,7 @@ Action ApplyChanges(Handle& hItem, int client, int iItemDefinitionIndex, char[] TF2Items_SetAttribute(hItem, 1, 2027, hasAussie ? float(hasAussie) : float(orgAussie)); TF2Items_SetAttribute(hItem, 2, 2022, hasAussie ? float(hasAussie) : float(orgAussie)); - TF2Items_SetAttribute(hItem, 3, 542, hasAussie ? float(hasAussie) : float(orgAussie)); + TF2Items_SetAttribute(hItem, 3, 542, isSpecial ? 0.0 : (hasAussie ? float(hasAussie) : float(orgAussie))); // Has Festive Override? bool hasFestive = pWeapons[client].Festive[slot], orgFestive = orgWeapons[client][slot].Festive; @@ -648,6 +741,9 @@ Action ApplyChanges(Handle& hItem, int client, int iItemDefinitionIndex, char[] TF2Items_SetAttribute(hItem, 11, 1008, hasFlames ? float(hasFlames) : float(view_as(oSpells & WeaponSpell_SpectralFlames))); TF2Items_SetAttribute(hItem, 12, 1007, hasExplosion ? float(hasExplosion) : float(view_as(oSpells & WeaponSpell_Explosions))); + if (isSpecial) + TF2Items_SetAttribute(hItem, 13, 150, 1.0); + TF2Items_SetFlags(hItem, flags); // If this is a new weapon (stock -> strange) fire another method. @@ -658,12 +754,12 @@ Action ApplyChanges(Handle& hItem, int client, int iItemDefinitionIndex, char[] } // GiveStrangeWeapon - Issues a new TF2ItemType Handle and gives the player a completely new Strange variant weapon for TF2Items_OnGiveNamedItem to apply changes on. -void GiveStrangeWeapon(int client, int iItemDefinitionIndex, char[] classname, int slot, int flags) { +void GiveStrangeWeapon(int client, int iItemDefinitionIndex, char[] classname, int slot, int flags, bool isSpecial = false) { // Create new Item Handle for the Strange Variant Handle hItem = INVALID_HANDLE; // Apply all attribute changes on it - ApplyChanges(hItem, client, iItemDefinitionIndex, classname, slot, flags, true); + ApplyChanges(hItem, client, iItemDefinitionIndex, classname, slot, flags, true, isSpecial); // Delete the handle, no memory leaks! delete hItem; @@ -772,6 +868,11 @@ void GetOriginalAttributes(int client, int slot) { // ForceChange() - Forces an SDKCall on the player to get effects applied instantly. void ForceChange(int client, int slot) { + if (CV_OnlySpawn.BoolValue && !bPlayerInSpawn[client]) { + CPrintToChat(client, "%s You are not allowed to make changes outside of spawn!", PGTAG); + return; + } + // Get all SOC attribs he had so we check for No Override settings GetOriginalAttributes(client, slot); @@ -841,6 +942,9 @@ public Action ForceTimer(Handle timer, DataPack data) } } + // Give Special Weapon to the player (if they have one) + GiveSpecialWeapon(client); + // Set active weapon as the changed one SetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", GetPlayerWeaponSlot(client, slot)); @@ -848,6 +952,55 @@ public Action ForceTimer(Handle timer, DataPack data) return Plugin_Stop; } +// mMainMenu - Main menu for all users. Allows them to select one of their weapons to begin modifying them. +void mMainMenu(int client) { + Menu menu = new Menu(mainHdlr); + + menu.SetTitle("Welcome! Select a Weapon"); + + for (int i = 0; i < MAX_WEAPONS; i++) { + int weapon = GetPlayerWeaponSlot(client, i); + + if (weapon != INVALID_WEAPON_ENTITY) { + char name[64], idStr[12]; + + int iItemDefinitionIndex = GetEntProp(weapon, Prop_Send, "m_iItemDefinitionIndex"); + + // will turn the stock weapon ID to a strange variant (if it fails it doesn't matter, value remains unchanged) + StockToStrange(iItemDefinitionIndex); + + // If the user has a special weapon override, utilize the original weapon ID that was on the melee slot. If no overrides where set, then whatever I guess. + if (pWeapons[client].Special == iItemDefinitionIndex) + iItemDefinitionIndex = pWeapons[client].iItemIndex[i] != -1 ? pWeapons[client].iItemIndex[i] : iItemDefinitionIndex; + + Format(idStr, sizeof(idStr), "%d", iItemDefinitionIndex); + TF2Econ_GetItemName(iItemDefinitionIndex, name, sizeof(name)); + + menu.AddItem(idStr, name); + } else // To maintain slot consistency, an invisible item is added. + menu.AddItem("", "", ITEMDRAW_IGNORE); + } + + // Special Weapon Preferences + char name[64], display[64]; + if (pWeapons[client].Special < 1) + strcopy(name, sizeof(name), "No Override"); + else + TF2Econ_GetItemName(pWeapons[client].Special, name, sizeof(name)); + + Format(display, sizeof(display), "Special Weapon: %s", name); + + menu.AddItem("-", "Special Weapons override your melee to the one specified here, you require a respawn to obtain them.", ITEMDRAW_DISABLED); + menu.AddItem("-", "Overrides you set on your melee slot will be sent over to the special weapon.", ITEMDRAW_DISABLED); + + menu.AddItem("s", display); + + menu.AddItem("-", "Usage: Select your desired weapon and start fiddling!", ITEMDRAW_DISABLED); + + menu.ExitButton = true; + menu.Display(client, MENU_TIME_FOREVER); +} + // wMainMenu - Main menu for selected weapons; shows a resume of what can be modified on it and what can't (according to compatibility). void wMainMenu(int client, int iItemDefinitionIndex, int slot) { Menu menu = new Menu(wepHdlr); diff --git a/scripting/tf2items/cosmetics.sp b/scripting/tf2items/cosmetics.sp index 3854606..815ac1d 100644 --- a/scripting/tf2items/cosmetics.sp +++ b/scripting/tf2items/cosmetics.sp @@ -357,11 +357,15 @@ void AddUnusuals(Menu menu, int client) char system[64]; TF2Econ_GetParticleAttributeSystemName(id, system, sizeof(system)); - //if (CV_Cosmetics_UParticles.BoolValue) - LogError("[TF2Cosmetics] Failure when adding particle %d (%s), might be new or undocumented; missing translation '%s'. This particle will be skipped!", id, system, name); + if (CV_LogMissingTranslations.BoolValue) + LogError("[TF2Cosmetics] Failure when adding particle %d (%s), might be new or undocumented; missing translation '%s'. This particle will be skipped!", id, system, name); continue; } + // ConVar that appends Unusual IDs + if (CV_Cosmetics_ShowIDs.BoolValue) + Format(name, sizeof(name), "%s (#%d)", name, id); + menu.AddItem(idStr, name); } } diff --git a/scripting/tf2items/tf2item_base.inc b/scripting/tf2items/tf2item_base.inc index 1ca7a39..fabd11f 100644 --- a/scripting/tf2items/tf2item_base.inc +++ b/scripting/tf2items/tf2item_base.inc @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -8,28 +9,92 @@ #include #include +/* + * Change-Log + * + * 3.0.1 - 13/10/21 + * + * General + * - Implemented ConVar functionality + * tf2item_weapons + * - Implemented a manual classname re-write for saxxy weapons (Issue #5). + * - TF2Items does not automatically set the proper classname for multi-class weapons. + * - Adapted functionality to utilize "Special Weapons" + * - Players can give themselves special weapons such as: The Golden Frying Pan, The Saxxy and The Golden Wrench + * + * 3.0.0 - 12/10/21 + * + * - Initial release (Full changes: https://github.com/punteroo/TF2-Item-Plugins/releases/tag/v3.0.0) + * + * Legacy Versions (Those before v3.0.0): https://github.com/punteroo/TF2-Item-Plugins/releases + */ + // Global Static Defines //////////////////////// -#define PGTAG "{mythical}[TF2Items]{white}" +#define PGTAG "{mythical}[TF2Items]{white}" + +// Is the player currently in a spawn region? +bool bPlayerInSpawn[MAXPLAYERS + 1] = false; + +// I am now officially a student of dark arts. Don't thank me, thank my master: Scag :) +stock ConVar CV_OnlySpawn, CV_LogMissingTranslations, + +CV_Cosmetics_Unusuals, CV_Cosmetics_Paint, CV_Cosmetics_Spells, CV_Cosmetics_ShowIDs, CV_Cosmetics_UParticles; // ConVars and more customization for user experiences. // TODO: Implement convar usage -// Global -/* -ConVar CV_OnlySpawn = CreateConVar("tf2items_general_onlyspawn", "1", "Controls wether players can only modify their items inside spawn boundaries. Default is 1.", _, true, 0.0, true, 1.0), - CV_OnlyAdmin = CreateConVar("tf2items_general_onlyadmin", "0", "Should only administrators (flag 'b'+) be able to utilize these plugins? Default is 0.", _, true, 0.0, true, 1.0), - -// Cosmetics Manager -CV_Cosmetics_Unusuals = CreateConVar("tf2items_cosmetics_unusuals", "1", "Are unusual overrides enabled? Default is 1.", _, true, 0.0, true, 1.0), -CV_Cosmetics_Paint = CreateConVar("tf2items_cosmetics_paints", "1", "Are paint overrides enabled? Default is 1.", _, true, 0.0, true, 1.0), -CV_Cosmetics_Spells = CreateConVar("tf2items_cosmetics_spells", "1", "Are halloween spells overrides enabled? Default is 1.", _, true, 0.0, true, 1.0), -CV_Cosmetics_ShowIDs = CreateConVar("tf2items_cosmetics_append_ids", "0", "Should Item Definition Indexes and Unusual Effect Indexes be appended onto their names? " ... - "Example: 'Burning Flames (#13)'", _, true, 0.0, true, 1.0), -CV_Cosmetics_UParticles = CreateConVar("tf2items_cosmetics_show_missing_particles", "0", "Logs to the server whenever a parsed Unusual Particle ID does not have an" ... - " existing translation for their name. I recommend leaving this off, as it causes" ... - " too much console spam and should only be used to debug. Default is 0.", _, true, 0.0, true, 1.0); - -*/ +public void OnConfigsExecuted() { + // Global + CV_OnlySpawn = CreateConVar("tf2items_general_onlyspawn", "0", "Controls wether players can only modify their items inside spawn boundaries. Default is 1.", _, true, 0.0, true, 1.0); + CV_LogMissingTranslations = CreateConVar("tf2items_cosmetics_show_missing_particles", "0", "Logs to the server whenever a parsed Unusual Particle/War Paint ID does not have an" ... + " existing translation for their name. I recommend leaving this off, as it causes" ... + " too much console spam and should only be used to debug. Default is 0.", _, true, 0.0, true, 1.0); + + // Cosmetics Manager + CV_Cosmetics_Unusuals = CreateConVar("tf2items_cosmetics_unusuals", "1", "Are unusual overrides enabled? Default is 1.", _, true, 0.0, true, 1.0); + CV_Cosmetics_Paint = CreateConVar("tf2items_cosmetics_paints", "1", "Are paint overrides enabled? Default is 1.", _, true, 0.0, true, 1.0); + CV_Cosmetics_Spells = CreateConVar("tf2items_cosmetics_spells", "1", "Are halloween spells overrides enabled? Default is 1.", _, true, 0.0, true, 1.0); + CV_Cosmetics_ShowIDs = CreateConVar("tf2items_cosmetics_append_ids", "0", "Should Item Definition Indexes and Unusual Effect Indexes be appended onto their names? " ... + "Example: 'Burning Flames (#13)'", _, true, 0.0, true, 1.0); + +} + +// Weapons Manager + + // General Functions -//////////////////// \ No newline at end of file +//////////////////// + +// Hooks func_respawnroom entities in the map to detect players that get in it. +void HookRespawns(bool unhook = false) { + // If the value is off, this hooking should not be done. + if (!CV_OnlySpawn.BoolValue) return; + + int ent = -1; + while ( (ent = FindEntityByClassname(ent, "func_respawnroom")) != -1) { + unhook ? SDKUnhook(ent, SDKHook_Touch, OnTouchSpawn) : SDKHook(ent, SDKHook_Touch, OnTouchSpawn); + unhook ? SDKUnhook(ent, SDKHook_EndTouch, OnStopTouchingSpawn) : SDKHook(ent, SDKHook_EndTouch, OnStopTouchingSpawn); + } + + if (unhook) { + for (int i = 1; i < MaxClients; i++) + bPlayerInSpawn[i] = false; + } +} + +public void OnTouchSpawn(int entity, int client) { + // Ignore invalid entities. + if (!IsClientInGame(client) || IsFakeClient(client) || IsClientSourceTV(client) || client > MaxClients || !CV_OnlySpawn.BoolValue) return; + + if (GetClientTeam(client) == GetEntProp(entity, Prop_Send, "m_iTeamNum")) + bPlayerInSpawn[client] = true; +} + +public void OnStopTouchingSpawn(int entity, int client) { + // Ignore invalid entities. + if (!IsClientInGame(client) || IsFakeClient(client) || IsClientSourceTV(client) || client > MaxClients || !CV_OnlySpawn.BoolValue) return; + + if (GetClientTeam(client) == GetEntProp(entity, Prop_Send, "m_iTeamNum")) + bPlayerInSpawn[client] = false; +} \ No newline at end of file diff --git a/scripting/tf2items/weapons.sp b/scripting/tf2items/weapons.sp index f5382a1..3f5b431 100644 --- a/scripting/tf2items/weapons.sp +++ b/scripting/tf2items/weapons.sp @@ -121,6 +121,10 @@ enum struct WeaponsInfo { // Spells [Bitfield] int sSpells[3]; + // Special Weapon Selection + // Players can set a preference for Special Weapons (functionality previously seen in vip-australium) + int Special; + /* * void ResetAll() * Called to reset everything on the weapon. All is set to -1. @@ -130,7 +134,7 @@ enum struct WeaponsInfo { this.ResetFor(i); } - void ResetFor(int slot) { + void ResetFor(int slot, bool resetAll = false) { this.iItemIndex[slot] = -1; this.uEffects[slot] = -1; @@ -146,6 +150,10 @@ enum struct WeaponsInfo { this.kStreaker[slot] = -1; this.sSpells[slot] = 0; + + // Do not reset the override if not needed. + if (resetAll) + this.Special = -1; } } @@ -153,36 +161,6 @@ enum struct WeaponsInfo { // Menu Creators //////////////// -// mMainMenu - Main menu for all users. Allows them to select one of their weapons to begin modifying them. -void mMainMenu(int client) { - Menu menu = new Menu(mainHdlr); - - menu.SetTitle("Welcome! Select a Weapon"); - - for (int i = 0; i < MAX_WEAPONS; i++) { - int weapon = GetPlayerWeaponSlot(client, i); - - if (weapon != INVALID_WEAPON_ENTITY) { - char name[64], idStr[12]; - - int iItemDefinitionIndex = GetEntProp(weapon, Prop_Send, "m_iItemDefinitionIndex"); - - // will turn the stock weapon ID to a strange variant (if it fails it doesn't matter, value remains unchanged) - StockToStrange(iItemDefinitionIndex); - - Format(idStr, sizeof(idStr), "%d", iItemDefinitionIndex); - TF2Econ_GetItemName(iItemDefinitionIndex, name, sizeof(name)); - - menu.AddItem(idStr, name); - } - } - - menu.AddItem("-", "Usage: Select your desired weapon and start fiddling!", ITEMDRAW_DISABLED); - - menu.ExitButton = true; - menu.Display(client, MENU_TIME_FOREVER); -} - // wWarPaintProtodef - Allows the user to select a specific War Paint Protodef ID to set on their weapon. void wWarPaintProtodef(int client, int iItemDefinitionIndex, int slot) { Menu menu = new Menu(wPaintProtoHdlr); @@ -211,7 +189,7 @@ void wWarPaintProtodef(int client, int iItemDefinitionIndex, int slot) { Format(pName, sizeof(pName), "%T", pStr, client); menu.AddItem(pStr, pName); - } else + } else if (CV_LogMissingTranslations.BoolValue) LogError("[TF2Weapons] Error while adding Paint Kit %s. Translation is missing. Paint Kit will not be added to the menu.", pStr); }