#pragma semicolon 1
#include <amxmodx>
#include <amxmisc>
#include <cstrike>
#include <reapi>
#define VERSION "1.0.7"
#define MaskEnt(%0) (1 << (%0 & 31))
new g_bitMigraineux;
#define SetUserReversed(%0) g_bitMigraineux |= MaskEnt(%0)
#define ClearUserReversed(%0) g_bitMigraineux &= ~MaskEnt(%0)
#define HasUserMigraine(%0) g_bitMigraineux & MaskEnt(%0)
enum globalState {None, Terrorists, Cts, All}
new Float:g_fAngle[MAX_PLAYERS + 1];
new g_iGlobalState;
new Float:g_fGlobalAngle = 180.0;
new HookChain:g_hPostThink;
new HookChain:g_hSpawn;
public plugin_init()
{
register_plugin("Migraine", VERSION, "ConnorMcLeod | Gramm");
register_concmd("amx_migraine", "AdminCommand_Migraine", ADMIN_LEVEL_A, "- <name/@CT/@T/@ALL> <0/1> [angle]");
register_concmd("amx_migraine_info", "AdminCommand_MigraineInfo", ADMIN_LEVEL_A, "- показывает список игроков с перевернутым экраном");
}
public client_putinserver(id)
{
ClearUserReversed(id);
g_fAngle[id] = 0.0;
CheckForwards();
}
public client_disconnected(id)
{
ClearUserReversed(id);
g_fAngle[id] = 0.0;
CheckForwards();
}
public OnPlayerSpawn(id)
{
if (!is_user_alive(id))
return;
switch (g_iGlobalState)
{
case Terrorists, Cts:
{
if (g_iGlobalState == _:cs_get_user_team(id))
{
SetUserReversed(id);
g_fAngle[id] = g_fGlobalAngle;
}
else
{
ClearUserReversed(id);
g_fAngle[id] = 0.0;
}
}
case All:
{
SetUserReversed(id);
g_fAngle[id] = g_fGlobalAngle;
}
}
CheckForwards();
if (HasUserMigraine(id))
{
RequestFrame("ApplyAngleAfterSpawn", id);
}
}
public ApplyAngleAfterSpawn(id)
{
if (is_user_alive(id) && HasUserMigraine(id))
{
new Float:vecPunch[3];
vecPunch[2] = g_fAngle[id];
set_entvar(id, var_punchangle, vecPunch);
}
}
public AdminCommand_MigraineInfo(id, level, cid)
{
if (!cmd_access(id, level, cid, 1))
return PLUGIN_HANDLED;
new iCount = 0;
new szName[32];
new szTeam[16];
console_print(id, "^n========================================");
console_print(id, "[Migraine] Список игроков с эффектом:");
console_print(id, "========================================");
// Глобальное состояние
switch (g_iGlobalState)
{
case All: console_print(id, "Режим: ВСЕ игроки (%.0f градусов)", g_fGlobalAngle);
case Terrorists: console_print(id, "Режим: Террористы (%.0f градусов)", g_fGlobalAngle);
case Cts: console_print(id, "Режим: Контр-Террористы (%.0f градусов)", g_fGlobalAngle);
case None: console_print(id, "Режим: Отключен");
}
console_print(id, "----------------------------------------");
for (new i = 1; i <= MaxClients; i++)
{
if (is_user_connected(i) && HasUserMigraine(i))
{
get_user_name(i, szName, charsmax(szName));
switch (cs_get_user_team(i))
{
case CS_TEAM_T: copy(szTeam, charsmax(szTeam), "T");
case CS_TEAM_CT: copy(szTeam, charsmax(szTeam), "CT");
case CS_TEAM_SPECTATOR: copy(szTeam, charsmax(szTeam), "SPEC");
default: copy(szTeam, charsmax(szTeam), "NONE");
}
console_print(id, "%2d. %s [%s] - Угол: %.0f градусов %s",
++iCount,
szName,
szTeam,
g_fAngle,
is_user_alive(i) ? "" : "(мертв)");
}
}
if (iCount == 0)
{
console_print(id, "Нет игроков с активным эффектом.");
}
else
{
console_print(id, "----------------------------------------");
console_print(id, "Всего игроков с эффектом: %d", iCount);
}
console_print(id, "========================================^n");
return PLUGIN_HANDLED;
}
public AdminCommand_Migraine(id, level, cid)
{
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED;
new szTarget[32], szOnOff[2], szAngle[10], iPlayer, iOnOff;
read_argv(1, szTarget, charsmax(szTarget));
read_argv(2, szOnOff, charsmax(szOnOff));
if (read_argc() >= 4)
{
read_argv(3, szAngle, charsmax(szAngle));
g_fGlobalAngle = str_to_float(szAngle);
if (g_fGlobalAngle > 360.0)
g_fGlobalAngle = 360.0;
else if (g_fGlobalAngle < -360.0)
g_fGlobalAngle = -360.0;
}
else
{
g_fGlobalAngle = 180.0;
}
switch (szOnOff[0])
{
case '0': iOnOff = 0;
case '1': iOnOff = 1;
default: return PLUGIN_HANDLED;
}
new szAdminName[32];
get_user_name(id, szAdminName, charsmax(szAdminName));
if (szTarget[0] == '@')
{
if (!iOnOff)
{
g_bitMigraineux = 0;
g_iGlobalState = None;
for (new i = 1; i <= MaxClients; i++)
{
g_fAngle = 0.0;
if(is_user_connected(i))
{
new Float:vecPunch[3];
set_entvar(i, var_punchangle, vecPunch);
}
}
client_print_color(0, print_team_default, "^4[Migraine]^1 Администратор ^4%s^1 отключил эффект для всех.", szAdminName);
CheckForwards();
return PLUGIN_HANDLED;
}
new iPlayers[32], iNum;
get_players(iPlayers, iNum, "a");
new szTeamName[64];
for (new i; i < iNum; i++)
{
iPlayer = iPlayers;
switch (szTarget[1])
{
case 'a', 'A':
{
g_iGlobalState = All;
SetUserReversed(iPlayer);
g_fAngle[iPlayer] = g_fGlobalAngle;
copy(szTeamName, charsmax(szTeamName), "всех игроков");
}
case 't', 'T':
{
g_iGlobalState = Terrorists;
if (cs_get_user_team(iPlayer) == CS_TEAM_T)
{
SetUserReversed(iPlayer);
g_fAngle[iPlayer] = g_fGlobalAngle;
}
else
{
ClearUserReversed(iPlayer);
g_fAngle[iPlayer] = 0.0;
}
copy(szTeamName, charsmax(szTeamName), "Террористов");
}
case 'c', 'C':
{
g_iGlobalState = Cts;
if (cs_get_user_team(iPlayer) == CS_TEAM_CT)
{
SetUserReversed(iPlayer);
g_fAngle[iPlayer] = g_fGlobalAngle;
}
else
{
ClearUserReversed(iPlayer);
g_fAngle[iPlayer] = 0.0;
}
copy(szTeamName, charsmax(szTeamName), "Контр-Террористов");
}
default: return PLUGIN_HANDLED;
}
}
client_print_color(0, print_team_default, "^4[Migraine]^1 Администратор ^4%s^1 перевернул экран для ^3%s^1 на ^4%.0f^1 градусов.", szAdminName, szTeamName, g_fGlobalAngle);
}
else
{
iPlayer = cmd_target(id, szTarget, CMDTARGET_OBEY_IMMUNITY | CMDTARGET_ALLOW_SELF);
if (!iPlayer)
return PLUGIN_HANDLED;
if (iOnOff)
{
SetUserReversed(iPlayer);
g_fAngle[iPlayer] = g_fGlobalAngle;
client_print_color(0, print_team_default, "^4[Migraine]^1 Администратор ^4%s^1 перевернул экран игроку ^3%n^1 на ^4%.0f^1 градусов.", szAdminName, iPlayer, g_fGlobalAngle);
}
else
{
ClearUserReversed(iPlayer);
g_fAngle[iPlayer] = 0.0;
new Float:vecPunch[3];
set_entvar(iPlayer, var_punchangle, vecPunch);
client_print_color(0, print_team_default, "^4[Migraine]^1 Администратор ^4%s^1 вернул нормальный экран игроку ^3%n^1.", szAdminName, iPlayer);
}
}
CheckForwards();
return PLUGIN_HANDLED;
}
public OnPlayerPostThink(id)
{
if (!HasUserMigraine(id) || !is_user_alive(id))
return;
new Float:vecPunch[3];
vecPunch[2] = g_fAngle[id]; // roll angle
set_entvar(id, var_punchangle, vecPunch);
}
CheckForwards()
{
static bool:bForwardStatus = false;
if (!g_bitMigraineux != !bForwardStatus)
{
if (g_bitMigraineux)
{
if (!g_hPostThink)
{
g_hPostThink = RegisterHookChain(RG_CBasePlayer_PostThink, "OnPlayerPostThink", false);
g_hSpawn = RegisterHookChain(RG_CBasePlayer_Spawn, "OnPlayerSpawn", true);
}
else
{
EnableHookChain(g_hPostThink);
EnableHookChain(g_hSpawn);
}
}
else
{
DisableHookChain(g_hPostThink);
DisableHookChain(g_hSpawn);
}
bForwardStatus = !!g_bitMigraineux;
}
}