-
Теперь знаю больше, спасибо огромное за помощь :thank_you:
-
Я тут вчера набросал реализацию своей идеи (начал делать заготовку для инклюда) и вот что вышло (может кому пригодится)
Открыть/закрыть
PHP код:
#if !defined DEFAULT_PLAYER_MARKER_RADIUS
#define DEFAULT_PLAYER_MARKER_RADIUS 300.0
#endif
enum e_PLAYER_MARKER_INFO
{
mark_id,
Float:mark_radius,
transparent
}
new pl_mark[MAX_PLAYERS][e_PLAYER_MARKER_INFO];
stock TogglePlayerOnMapForPlayer(playerid, showplayerid, bool:visible)
{
new map_color = GetPlayerColor(showplayerid);
if((map_color & 0xFF) != 0x00) pl_mark[playerid][transparent] = map_color & 0xFF;
SetPlayerMarkerForPlayer(playerid, showplayerid, (map_color | 0xFF) - (visible ? 0x00 : pl_mark[playerid][transparent]));
return 1;
}
stock UpdateRadiusForPlayerMarker(playerid, Float:radius)
{
if(pl_mark[playerid][mark_id] == -1) return 0;
pl_mark[playerid][mark_radius] = radius;
DestroyDynamicArea(pl_mark[playerid][mark_id]);
printf("\n%d", pl_mark[playerid][mark_id] = CreateDynamicSphere(0.0, 0.0, 0.0, pl_mark[playerid][mark_radius], -1, -1, -1));
printf("%d\n", AttachDynamicAreaToPlayer(pl_mark[playerid][mark_id], playerid));
return 1;
}
cmd:radius(playerid, params[])
{
if(isnull(params) || !(params[0] >= '0' && params[0] <= '9')) return SendClientMessage(playerid, -1, "Введите радиус");
new Float: radius = float(strval(params));
new string[30];
foreach(new i: Player)
{
format(string, sizeof(string), "%d", UpdateRadiusForPlayerMarker(playerid, radius));
SendClientMessage(playerid, -1, string);
}
return 1;
}
public OnGameModeInit()
{
ShowPlayerMarkers(PLAYER_MARKERS_MODE_GLOBAL);
LimitPlayerMarkerRadius(10000.0);
for(new i; i < sizeof(pl_mark); i++)
{
pl_mark[i][mark_id] = -1;
pl_mark[i][transparent] = 0xFF;
pl_mark[i][mark_radius] = DEFAULT_PLAYER_MARKER_RADIUS;
}
return 1;
}
public OnPlayerSpawn(playerid)
{
if(pl_mark[playerid][mark_id] == -1)
{
pl_mark[playerid][mark_id] = CreateDynamicSphere(0.0, 0.0, 0.0, pl_mark[playerid][mark_radius], -1, -1, -1);
AttachDynamicAreaToPlayer(pl_mark[playerid][mark_id], playerid);
}
SetPlayerPos(playerid, 1830.3783, 1340.1572, 14.3746);
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
if(pl_mark[playerid][mark_id] != -1)
{
DestroyDynamicArea(pl_mark[playerid][mark_id]);
pl_mark[playerid][mark_id] = -1;
}
pl_mark[playerid][transparent] = 0xFF;
return 1;
}
public OnPlayerEnterDynamicArea(playerid, areaid)
{
new string[30];
foreach(new i: Player)
{
if(i == playerid) continue;
if(areaid != pl_mark[i][mark_id]) continue;
TogglePlayerOnMapForPlayer(i, playerid, true);
format(string, sizeof(string), "%d показан для %d", playerid, i);
SendClientMessageToAll(-1, string);
}
return 1;
}
public OnPlayerLeaveDynamicArea(playerid, areaid)
{
new string[30];
foreach(new i: Player)
{
if(i == playerid) continue;
if(areaid != pl_mark[i][mark_id]) continue;
TogglePlayerOnMapForPlayer(i, playerid, false);
format(string, sizeof(string), "%d скрыт для %d", playerid, i);
SendClientMessageToAll(-1, string);
}
return 1;
}
Код чисто написан для теста (некоторая "ненужная" информация выдаётся в чат и прочее) и я сразу пытался адаптировать его под расширенные возможности (обновлять радиус отображения маркеров для всех/определённого игрока прямо в игре и т.п.). В общем, чисто на посмотреть.
P.S. Тестировал всё на одном компьютере с использованием песочницы и заметил, что то ли функция AttachDynamicAreaToPlayer отказывается крепить зону к игроку, который АФК, то ли OnPlayerEnterDynamicArea/OnPlayerLeaveDynamicArea как-то отказывается срабатывать нормально, но смысл в том, что если попробовать обновить радиус зон (пока реализовано обновление для всех сразу) и кто-то будет стоять АФК, система начнёт глючить (у АФК-шника радиус зоны останется старым).
Вполне возможно, что это косяк моего кода. Вчера просто не было времени проверить. Просто если кто-то решит копаться в моём говнокоде, имейте это ввиду.
И да, я, похоже, стандартные маркеры настроил немного неверно. В общем, работать ещё есть над чем :3
UPD: Бага с AFK никакого нет. Всему виной мои кривые руки и невнимательность. Скоро запилю инклюд
-
LimitPlayerMarkerRadius лучше убрать, чтобы внутренний стриммер не рассчитывал дистанцию.