/**
History:
0.0.1b (23.12.2023) by b0t.
- Release;
0.0.2b (29.12.2023) by b0t.
- Code optimization;
- Added:
* Reset settings;
* Disable;
0.1.2 (10.08.2026) by b0t.
- Code optimization/refactoring;
- Fixed error in disabling light changes;
- Fixed critical error in saving selected parameters;
- Thanks to Czech for optimization ideas;
0.1.3
- All displayed text moved to LightStyle.txt;
- Added EN/RU localization;
0.1.4
- Light settings are now saved per player and per map;
- Each map has its own saved light setting for every player;
*/
new const VERSION[] = "0.1.4";
#include <amxmodx>
#include <nvault>
#pragma semicolon 1
#define SECONDS_IN_DAY 86400
#define INVALID_ACCESS (1<<31)
#define OFF_LIGHT -1
enum _:CvarsStruct
{
ClCmd_OpenMenu[128],
StartLightKey[5],
StorageTime_In_Day
};
new const g_szNvault_DataBase_Name[] = "LightKey";
new
pCvar[CvarsStruct],
g_iNvault_DataBase = INVALID_HANDLE;
new const g_szLightKey[] = "abcdefghijklmnopqrstuvwxyz";
new
g_iStartKey;
new
p_iLightKey[33],
p_szAuthId[33][64],
g_szMapName[32];
public plugin_init()
{
register_plugin("Light Style", VERSION, "b0t.");
register_dictionary("LightStyle.txt");
get_mapname(g_szMapName, charsmax(g_szMapName));
}
public plugin_cfg()
{
CreateCvars();
AutoExecConfig(.autoCreate = true, .name = "LightStyle");
register_clcmd(pCvar[ClCmd_OpenMenu], "Show__LightMenu");
register_clcmd(fmt("say /%s", pCvar[ClCmd_OpenMenu]), "Show__LightMenu");
register_clcmd(fmt("say_team /%s", pCvar[ClCmd_OpenMenu]), "Show__LightMenu");
if (strcmp(pCvar[StartLightKey], "OFF") == 0)
{
g_iStartKey = OFF_LIGHT;
}
else
{
g_iStartKey = -1;
for (new i; i < charsmax(g_szLightKey); i++)
{
if (g_szLightKey[i] == pCvar[StartLightKey][0])
{
g_iStartKey = i;
break;
}
}
if (g_iStartKey == -1)
{
g_iStartKey = 12; // m
}
}
g_iNvault_DataBase = nvault_open(g_szNvault_DataBase_Name);
if (g_iNvault_DataBase == INVALID_HANDLE)
{
set_fail_state(
"Error opening nVault database: %s",
g_szNvault_DataBase_Name
);
}
nvault_prune(
g_iNvault_DataBase,
0,
get_systime() - (SECONDS_IN_DAY * pCvar[StorageTime_In_Day])
);
}
public Show__LightMenu(const id)
{
if (!is_user_connected(id))
return PLUGIN_HANDLED;
new szMenuName[256];
new szItem[128];
switch (p_iLightKey[id])
{
case OFF_LIGHT:
{
formatex(
szMenuName,
charsmax(szMenuName),
"%L",
id,
"LS_MENU_NAME_OFF_LIGHT"
);
}
default:
{
new szKey[2];
szKey[0] = g_szLightKey[p_iLightKey[id]];
szKey[1] = EOS;
formatex(
szMenuName,
charsmax(szMenuName),
"%L",
id,
"LS_MENU_NAME",
szKey
);
}
}
new iMenu = menu_create(
szMenuName,
"LightMenu__Handler"
);
formatex(
szItem,
charsmax(szItem),
"%L",
id,
"LS_LIGHT_DOWN"
);
menu_additem(iMenu, szItem);
formatex(
szItem,
charsmax(szItem),
"%L",
id,
"LS_LIGHT_UP"
);
menu_additem(iMenu, szItem);
formatex(
szItem,
charsmax(szItem),
"%L",
id,
"LS_LIGHT_REMOVE"
);
menu_additem(
iMenu,
szItem,
.paccess = p_iLightKey[id] == g_iStartKey ? INVALID_ACCESS : ADMIN_ALL
);
formatex(
szItem,
charsmax(szItem),
"%L",
id,
"LS_LIGHT_OFF"
);
menu_additem(
iMenu,
szItem,
.paccess = p_iLightKey[id] == OFF_LIGHT ? INVALID_ACCESS : ADMIN_ALL
);
formatex(
szItem,
charsmax(szItem),
"%L",
id,
"LS_MENU_EXIT_NAME"
);
menu_setprop(iMenu, MPROP_EXITNAME, szItem);
formatex(
szItem,
charsmax(szItem),
"%L",
id,
"LS_MENU_NUMBER_COLOR"
);
menu_setprop(iMenu, MPROP_NUMBER_COLOR, szItem);
menu_display(id, iMenu);
return PLUGIN_HANDLED;
}
public LightMenu__Handler(
const id,
const iMenu,
const iItem
)
{
menu_destroy(iMenu);
if (iItem == MENU_EXIT)
return PLUGIN_HANDLED;
switch (iItem)
{
case 0:
{
p_iLightKey[id]--;
if (p_iLightKey[id] < 0)
p_iLightKey[id] = charsmax(g_szLightKey) - 1;
}
case 1:
{
p_iLightKey[id]++;
if (p_iLightKey[id] >= charsmax(g_szLightKey))
p_iLightKey[id] = 0;
}
case 2:
{
p_iLightKey[id] = g_iStartKey;
}
case 3:
{
p_iLightKey[id] = OFF_LIGHT;
}
}
SavePlayerMapLight(id);
UTIL__SetLightStyle(id);
Show__LightMenu(id);
return PLUGIN_HANDLED;
}
public client_putinserver(id)
{
get_user_authid(
id,
p_szAuthId[id],
charsmax(p_szAuthId[])
);
LoadPlayerMapLight(id);
UTIL__SetLightStyle(id);
}
public client_disconnected(id)
{
p_iLightKey[id] = g_iStartKey;
p_szAuthId[id][0] = EOS;
}
public CreateCvars()
{
bind_pcvar_string(
create_cvar(
.name = "lm_cl_cmd_open_menu",
.string = "light",
.description = "LS_CVAR_OPEN_MENU"
),
pCvar[ClCmd_OpenMenu],
charsmax(pCvar[ClCmd_OpenMenu])
);
bind_pcvar_string(
create_cvar(
.name = "lm_start_light_key",
.string = "m",
.description = "LS_CVAR_START_LIGHT_KEY"
),
pCvar[StartLightKey],
charsmax(pCvar[StartLightKey])
);
bind_pcvar_num(
create_cvar(
.name = "lm_storage_time_in_day",
.string = "30",
.description = "LS_CVAR_STORAGE_TIME"
),
pCvar[StorageTime_In_Day]
);
}
public plugin_end()
{
if (g_iNvault_DataBase != INVALID_HANDLE)
{
nvault_close(g_iNvault_DataBase);
}
}
stock LoadPlayerMapLight(const id)
{
if (!p_szAuthId[id][0])
{
p_iLightKey[id] = g_iStartKey;
return;
}
new szVaultKey[128];
new szValue[10];
formatex(
szVaultKey,
charsmax(szVaultKey),
"%s_%s",
p_szAuthId[id],
g_szMapName
);
if (nvault_get(
g_iNvault_DataBase,
szVaultKey,
szValue,
charsmax(szValue)
))
{
p_iLightKey[id] = str_to_num(szValue);
if (
p_iLightKey[id] < OFF_LIGHT ||
p_iLightKey[id] >= charsmax(g_szLightKey)
)
{
p_iLightKey[id] = g_iStartKey;
}
}
else
{
p_iLightKey[id] = g_iStartKey;
}
}
stock SavePlayerMapLight(const id)
{
if (!p_szAuthId[id][0])
return;
new szVaultKey[128];
formatex(
szVaultKey,
charsmax(szVaultKey),
"%s_%s",
p_szAuthId[id],
g_szMapName
);
nvault_set(
g_iNvault_DataBase,
szVaultKey,
fmt("%i", p_iLightKey[id])
);
}
stock UTIL__SetLightStyle(const id)
{
new szKey[2];
if (p_iLightKey[id] != OFF_LIGHT)
{
szKey[0] = g_szLightKey[p_iLightKey[id]];
szKey[1] = EOS;
}
message_begin(
MSG_ONE_UNRELIABLE,
SVC_LIGHTSTYLE,
.player = id
);
write_byte(0);
if (p_iLightKey[id] != OFF_LIGHT)
{
write_string(szKey);
}
else
{
write_string("");
}
message_end();
}