Skip to content

Commit

Permalink
Implement temporary item overrides
Browse files Browse the repository at this point in the history
This allows plugins to temporarily equip their own items with
persistence without stomping on the player's own preferences.
  • Loading branch information
nosoop committed Oct 20, 2021
1 parent 6c2fc5d commit d9e23dc
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 12 deletions.
12 changes: 7 additions & 5 deletions scripting/cwx.sp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public void OnClientConnected(int client) {
g_bRetrievedLoadout[client] = false;
for (int c; c < NUM_PLAYER_CLASSES; c++) {
for (int i; i < NUM_ITEMS; i++) {
g_CurrentLoadout[client][c][i].Clear();
g_CurrentLoadout[client][c][i].Clear(.initialize = true);
}
}
}
Expand Down Expand Up @@ -267,9 +267,8 @@ void OnPlayerLoadoutUpdatedPost(UserMsg msg_id, bool sent) {
int currentLoadoutItem = g_CurrentLoadout[client][playerClass][i].entity;
if (g_bForceReequipItems[client] || !IsValidEntity(currentLoadoutItem)
|| GetEntityFlags(currentLoadoutItem) & FL_KILLME) {
// TODO validate that the player can access this item
CustomItemDefinition item;
if (!GetCustomItemDefinition(g_CurrentLoadout[client][playerClass][i].uid, item)) {
if (!g_CurrentLoadout[client][playerClass][i].GetItemDefinition(item)) {
continue;
}

Expand Down Expand Up @@ -408,10 +407,13 @@ bool SetClientCustomLoadoutItem(int client, int playerClass, const char[] itemui

int itemSlot = item.loadoutPosition[playerClass];
if (0 <= itemSlot < NUM_ITEMS) {
g_CurrentLoadout[client][playerClass][itemSlot].SetItemUID(itemuid);

if (flags & LOADOUT_FLAG_UPDATE_BACKEND) {
// item being set as user preference; update backend and set permanent UID slot
g_ItemPersistCookies[playerClass][itemSlot].Set(client, itemuid);
g_CurrentLoadout[client][playerClass][itemSlot].SetItemUID(itemuid);
} else {
// item being set temporarily; set as overload
g_CurrentLoadout[client][playerClass][itemSlot].SetOverloadItemUID(itemuid);
}

g_CurrentLoadout[client][playerClass][itemSlot].entity = INVALID_ENT_REFERENCE;
Expand Down
24 changes: 18 additions & 6 deletions scripting/cwx/loadout_entries.sp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
enum struct LoadoutEntry {
char uid[MAX_ITEM_IDENTIFIER_LENGTH];

// overload UID -- used when plugins want to take priority over user preference
char override_uid[MAX_ITEM_IDENTIFIER_LENGTH];

// loadout entity, for persistence
// note for the future: we do *not* restore this on late load since the schema may have changed
int entity;
Expand All @@ -13,17 +16,26 @@ enum struct LoadoutEntry {
strcopy(this.uid, MAX_ITEM_IDENTIFIER_LENGTH, other_uid);
}

void SetOverloadItemUID(const char[] other_uid) {
strcopy(this.override_uid, MAX_ITEM_IDENTIFIER_LENGTH, other_uid);
}

bool GetItemDefinition(CustomItemDefinition item) {
return GetCustomItemDefinition(this.override_uid, item)
|| GetCustomItemDefinition(this.uid, item);
}

bool IsEmpty() {
return !this.uid[0];
return !(this.override_uid[0] || this.uid[0]);
}

void Clear() {
void Clear(bool initialize = false) {
this.entity = INVALID_ENT_REFERENCE;
this.uid = "";
}

bool GetItemDefinition(CustomItemDefinition item) {
return GetCustomItemDefinition(this.uid, item);
if (initialize) {
this.override_uid = "";
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions scripting/cwx/loadout_radio_menu.sp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ static int OnEquipMenuEvent(Menu menu, MenuAction action, int param1, int param2
int menuSlot = g_iPlayerSlotInMenu[client];

bool equipped = StrEqual(g_CurrentLoadout[client][menuClass][menuSlot].uid, uid);
bool override = StrEqual(g_CurrentLoadout[client][menuClass][menuSlot].override_uid, uid);

SetGlobalTransTarget(client);

Expand All @@ -376,6 +377,9 @@ static int OnEquipMenuEvent(Menu menu, MenuAction action, int param1, int param2
if (equipped) {
Format(itemName, sizeof(itemName), "%s %t", itemName, "QuickSwitchEquipped");
redraw = true;
} else if (uid[0] && override) {
Format(itemName, sizeof(itemName), "%s %t", itemName, "ItemForcedByServer");
redraw = true;
}

SetGlobalTransTarget(LANG_SERVER);
Expand Down
22 changes: 22 additions & 0 deletions scripting/cwx_equip_commands.sp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#pragma newdecls required

#include <cwx>
#include <tf2_stocks>

public Plugin myinfo = {
name = "[TF2] Custom Weapons X - Equip Commands",
Expand All @@ -24,6 +25,7 @@ public Plugin myinfo = {
public void OnPluginStart() {
RegAdminCmd("sm_cwx_equip", EquipItemCmd, ADMFLAG_ROOT);
RegAdminCmd("sm_cwx_equip_target", EquipItemCmdTarget, ADMFLAG_ROOT);
RegAdminCmd("sm_cwx_set_loadout", PersistItemCmd, ADMFLAG_ROOT);
}

/**
Expand Down Expand Up @@ -51,6 +53,26 @@ Action EquipItemCmd(int client, int argc) {
return Plugin_Handled;
}

Action PersistItemCmd(int client, int argc) {
if (!client) {
return Plugin_Continue;
}

char itemuid[MAX_ITEM_IDENTIFIER_LENGTH];
GetCmdArgString(itemuid, sizeof(itemuid));

StripQuotes(itemuid);
TrimString(itemuid);

if (!CWX_IsItemUIDValid(itemuid)) {
ReplyToCommand(client, "Unknown custom item uid %s", itemuid);
} else if (!CWX_SetPlayerLoadoutItem(client, TF2_GetPlayerClass(client), itemuid)) {
ReplyToCommand(client, "Failed to set custom item uid %s", itemuid);
}

return Plugin_Handled;
}

/**
* Testing command to equip the given item uid on the specified target(s).
*/
Expand Down
4 changes: 3 additions & 1 deletion scripting/include/cwx.inc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
***************************************************************************************/

#define LOADOUT_FLAG_UPDATE_BACKEND (1 << 0) // update the item on the backing database, in
// addition to the current session
// addition to the current session -- if this is
// not set, the item will be treated as a temporary
// override
#define LOADOUT_FLAG_ATTEMPT_REGEN (1 << 1) // if the player is in a spawn room, perform
// regeneration to refresh the loadout

Expand Down
4 changes: 4 additions & 0 deletions translations/cwx.phrases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -933,4 +933,8 @@
{
"en" "(Custom items are currently disabled by the server operator.)"
}
"ItemForcedByServer"
{
"en" "(forced by server)"
}
}

0 comments on commit d9e23dc

Please sign in to comment.