Активный
- Тема Автор
- #1
Руководство по созданию системы наблюдения за игроками для администраторов и модераторов.
Структура данных наблюдателя
Включение режима наблюдения
Остановка наблюдения
Наблюдение за транспортом
Переключение между игроками
Команды для наблюдения
Информация о наблюдаемом игроке
Автоматическое переключение при отключении
Наблюдение за транспортом игрока
Список наблюдающих
Ограничение действий в режиме наблюдения
Система наблюдения - важный инструмент для администраторов. Эти примеры показывают полный функционал наблюдения за игроками и транспортом.
Структура данных наблюдателя
Код:
enum SpectatorInfo
{
sTarget,
sMode,
sInterior,
sVirtualWorld
}
new SpectatorData[MAX_PLAYERS][SpectatorInfo];
new IsSpectating[MAX_PLAYERS];
Включение режима наблюдения
Код:
StartSpectating(playerid, targetid)
{
if(!IsPlayerConnected(targetid))
{
SendClientMessage(playerid, -1, "Игрок не найден");
return 0;
}
if(targetid == playerid)
{
SendClientMessage(playerid, -1, "Вы не можете наблюдать за собой");
return 0;
}
if(IsSpectating[playerid])
{
StopSpectating(playerid);
}
IsSpectating[playerid] = 1;
SpectatorData[playerid][sTarget] = targetid;
SpectatorData[playerid][sMode] = 1;
SpectatorData[playerid][sInterior] = GetPlayerInterior(playerid);
SpectatorData[playerid][sVirtualWorld] = GetPlayerVirtualWorld(playerid);
TogglePlayerSpectating(playerid, 1);
PlayerSpectatePlayer(playerid, targetid);
new string[128], name[MAX_PLAYER_NAME];
GetPlayerName(targetid, name, sizeof(name));
format(string, sizeof(string), "Вы наблюдаете за игроком %s (ID: %d)", name, targetid);
SendClientMessage(playerid, -1, string);
return 1;
}
Остановка наблюдения
Код:
StopSpectating(playerid)
{
if(!IsSpectating[playerid])
{
return 0;
}
TogglePlayerSpectating(playerid, 0);
new Float:x, Float:y, Float:z;
GetPlayerPos(SpectatorData[playerid][sTarget], x, y, z);
SetPlayerPos(playerid, x+2, y, z);
SetPlayerInterior(playerid, SpectatorData[playerid][sInterior]);
SetPlayerVirtualWorld(playerid, SpectatorData[playerid][sVirtualWorld]);
IsSpectating[playerid] = 0;
SpectatorData[playerid][sTarget] = INVALID_PLAYER_ID;
SendClientMessage(playerid, -1, "Режим наблюдения отключен");
return 1;
}
Наблюдение за транспортом
Код:
StartSpectatingVehicle(playerid, vehicleid)
{
if(!IsValidVehicle(vehicleid))
{
SendClientMessage(playerid, -1, "Транспорт не найден");
return 0;
}
if(IsSpectating[playerid])
{
StopSpectating(playerid);
}
IsSpectating[playerid] = 1;
SpectatorData[playerid][sTarget] = vehicleid;
SpectatorData[playerid][sMode] = 2;
SpectatorData[playerid][sInterior] = GetPlayerInterior(playerid);
SpectatorData[playerid][sVirtualWorld] = GetPlayerVirtualWorld(playerid);
TogglePlayerSpectating(playerid, 1);
PlayerSpectateVehicle(playerid, vehicleid);
new string[128];
format(string, sizeof(string), "Вы наблюдаете за транспортом ID: %d", vehicleid);
SendClientMessage(playerid, -1, string);
return 1;
}
Переключение между игроками
Код:
SwitchSpectateTarget(playerid, newtargetid)
{
if(!IsSpectating[playerid])
{
return 0;
}
if(SpectatorData[playerid][sMode] != 1)
{
return 0;
}
if(!IsPlayerConnected(newtargetid))
{
SendClientMessage(playerid, -1, "Игрок не найден");
return 0;
}
SpectatorData[playerid][sTarget] = newtargetid;
PlayerSpectatePlayer(playerid, newtargetid);
new string[128], name[MAX_PLAYER_NAME];
GetPlayerName(newtargetid, name, sizeof(name));
format(string, sizeof(string), "Теперь вы наблюдаете за игроком %s (ID: %d)", name, newtargetid);
SendClientMessage(playerid, -1, string);
return 1;
}
Команды для наблюдения
Код:
CMD:spec(playerid, params[])
{
if(PlayerInfo[playerid][pAdmin] < 1)
{
SendClientMessage(playerid, -1, "У вас нет доступа к этой команде");
return 1;
}
if(IsSpectating[playerid])
{
StopSpectating(playerid);
return 1;
}
new targetid;
if(sscanf(params, "u", targetid))
{
SendClientMessage(playerid, -1, "Использование: /spec [id игрока]");
return 1;
}
StartSpectating(playerid, targetid);
return 1;
}
CMD:specoff(playerid, params[])
{
if(!IsSpectating[playerid])
{
SendClientMessage(playerid, -1, "Вы не находитесь в режиме наблюдения");
return 1;
}
StopSpectating(playerid);
return 1;
}
CMD:specnext(playerid, params[])
{
if(!IsSpectating[playerid] || SpectatorData[playerid][sMode] != 1)
{
SendClientMessage(playerid, -1, "Вы не наблюдаете за игроком");
return 1;
}
new currentTarget = SpectatorData[playerid][sTarget];
new nextTarget = INVALID_PLAYER_ID;
new found = 0;
for(new i = currentTarget + 1; i < MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i) && i != playerid)
{
nextTarget = i;
found = 1;
break;
}
}
if(!found)
{
for(new i = 0; i < currentTarget; i++)
{
if(IsPlayerConnected(i) && i != playerid)
{
nextTarget = i;
found = 1;
break;
}
}
}
if(found)
{
SwitchSpectateTarget(playerid, nextTarget);
}
else
{
SendClientMessage(playerid, -1, "Нет других игроков для наблюдения");
}
return 1;
}
CMD:specprev(playerid, params[])
{
if(!IsSpectating[playerid] || SpectatorData[playerid][sMode] != 1)
{
SendClientMessage(playerid, -1, "Вы не наблюдаете за игроком");
return 1;
}
new currentTarget = SpectatorData[playerid][sTarget];
new prevTarget = INVALID_PLAYER_ID;
new found = 0;
for(new i = currentTarget - 1; i >= 0; i--)
{
if(IsPlayerConnected(i) && i != playerid)
{
prevTarget = i;
found = 1;
break;
}
}
if(!found)
{
for(new i = MAX_PLAYERS - 1; i > currentTarget; i--)
{
if(IsPlayerConnected(i) && i != playerid)
{
prevTarget = i;
found = 1;
break;
}
}
}
if(found)
{
SwitchSpectateTarget(playerid, prevTarget);
}
else
{
SendClientMessage(playerid, -1, "Нет других игроков для наблюдения");
}
return 1;
}
Информация о наблюдаемом игроке
Код:
ShowSpectateInfo(playerid)
{
if(!IsSpectating[playerid] || SpectatorData[playerid][sMode] != 1)
{
return 0;
}
new targetid = SpectatorData[playerid][sTarget];
if(!IsPlayerConnected(targetid))
{
return 0;
}
new string[256], name[MAX_PLAYER_NAME];
GetPlayerName(targetid, name, sizeof(name));
new Float:health, Float:armour;
GetPlayerHealth(targetid, health);
GetPlayerArmour(targetid, armour);
new Float:x, Float:y, Float:z;
GetPlayerPos(targetid, x, y, z);
format(string, sizeof(string),
"~w~Наблюдение: ~y~%s~n~\
~w~ID: ~g~%d~n~\
~w~Здоровье: ~r~%.0f~n~\
~w~Броня: ~b~%.0f~n~\
~w~Деньги: ~g~$%d~n~\
~w~Оружие: ~y~%s",
name,
targetid,
health,
armour,
GetPlayerMoney(targetid),
GetWeaponName(GetPlayerWeapon(targetid))
);
GameTextForPlayer(playerid, string, 2000, 3);
return 1;
}
public OnPlayerUpdate(playerid)
{
if(IsSpectating[playerid] && SpectatorData[playerid][sMode] == 1)
{
static lastUpdate[MAX_PLAYERS];
if(GetTickCount() - lastUpdate[playerid] > 1000)
{
ShowSpectateInfo(playerid);
lastUpdate[playerid] = GetTickCount();
}
}
return 1;
}
Автоматическое переключение при отключении
Код:
public OnPlayerDisconnect(playerid, reason)
{
// Остановка наблюдения за отключившимся игроком
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(IsSpectating[i] && SpectatorData[i][sTarget] == playerid)
{
StopSpectating(i);
SendClientMessage(i, -1, "Игрок, за которым вы наблюдали, отключился");
}
}
// Остановка наблюдения отключившегося игрока
if(IsSpectating[playerid])
{
StopSpectating(playerid);
}
return 1;
}
Наблюдение за транспортом игрока
Код:
CMD:specvehicle(playerid, params[])
{
if(PlayerInfo[playerid][pAdmin] < 1)
{
SendClientMessage(playerid, -1, "У вас нет доступа к этой команде");
return 1;
}
new targetid;
if(sscanf(params, "u", targetid))
{
SendClientMessage(playerid, -1, "Использование: /specvehicle [id игрока]");
return 1;
}
if(!IsPlayerConnected(targetid))
{
SendClientMessage(playerid, -1, "Игрок не найден");
return 1;
}
if(!IsPlayerInAnyVehicle(targetid))
{
SendClientMessage(playerid, -1, "Игрок не находится в транспорте");
return 1;
}
new vehicleid = GetPlayerVehicleID(targetid);
StartSpectatingVehicle(playerid, vehicleid);
return 1;
}
Список наблюдающих
Код:
GetSpectatorsCount(targetid)
{
new count = 0;
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(IsSpectating[i] && SpectatorData[i][sTarget] == targetid)
{
count++;
}
}
return count;
}
CMD:specinfo(playerid, params[])
{
new count = GetSpectatorsCount(playerid);
if(count > 0)
{
new string[128];
format(string, sizeof(string), "За вами наблюдают %d администраторов", count);
SendClientMessage(playerid, -1, string);
}
return 1;
}
Ограничение действий в режиме наблюдения
Код:
public OnPlayerCommandText(playerid, cmdtext[])
{
if(IsSpectating[playerid])
{
new allowedCommands[][] = {
"spec", "specoff", "specnext", "specprev", "specvehicle", "specinfo"
};
new cmd[32];
sscanf(cmdtext, "s[32]", cmd);
new allowed = 0;
for(new i = 0; i < sizeof(allowedCommands); i++)
{
if(strcmp(cmd, allowedCommands[i], true) == 0)
{
allowed = 1;
break;
}
}
if(!allowed)
{
SendClientMessage(playerid, -1, "Вы не можете использовать команды в режиме наблюдения");
return 1;
}
}
return 0;
}
Система наблюдения - важный инструмент для администраторов. Эти примеры показывают полный функционал наблюдения за игроками и транспортом.