Найти игроков на нужной дистанции
| |
polo79655
|
Дата: Пятница, 01.05.2020, 11:26:57 | Сообщение # 1 |
![Активный](http://world-source.ru/groupicon/active_icon.jpg) |
Сообщений: 99
Репутация: -1 [ +/- ]
|
|
Всем привет. Мне нужна функция, чтобы найти игроков на определенном расстоянии. Но так, чтобы она не игнорировала стены и пропы, то есть если между игроками есть что-то, то тогда нужно исключить данного игрока из поиска.
Я использовал эту функцию из плагина для турели, которая находит ближайшего игрока:
Код stock FindFirstTargetInRange(client, Float:vAngle[3], Float:vEntPosition[3], Float:entHeight = 60.0) { new Float:vClientPosition[3]; GetEntPropVector(client, Prop_Send, "m_vecOrigin", vEntPosition); vEntPosition[2] += entHeight; new Float:fDistance[MAXPLAYERS + 1]; new iTager[MAXPLAYERS + 1]; new numb = 0; for (new i = 1; i <= MaxClients; i++) { if (IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(client) != GetClientTeam(i)) { GetClientEyePosition(i, vClientPosition); fDistance[numb] = GetVectorDistance(vClientPosition, vEntPosition, false); if(fDistance[numb] <= 9000000 && fDistance[numb] > 50) { iTager[numb] = i; numb++; } } } new zombie = GetZombieMinDistance(iTager, fDistance, numb+1); if(zombie < 1 || !IsClientInGame(zombie) || !IsPlayerAlive(zombie)) { return (-1); } GetClientEyePosition(zombie, vClientPosition); vClientPosition[2] -= 10.0; MakeVectorFromPoints(vEntPosition, vClientPosition, vAngle); vClientPosition[2] += 10.0; //NormalizeVector(vAngle, vAngle); GetVectorAngles(vAngle, vAngle); new Handle:trace = TR_TraceRayFilterEx(vEntPosition, vClientPosition, MASK_SHOT, RayType_EndPoint, TraceASDF, client); if(!TR_DidHit(trace)) { CloseHandle(trace); return (zombie); } CloseHandle(trace); return (-1); }
GetZombieMinDistance(clients[], Float:distance[], max_clients) { if(max_clients < 1) { return -1; } new Float:min_distance = 999999999.0; new zombie = -1; for(new i = 0; i < max_clients; i++) { // 999999999 > 10000000 if(min_distance > distance[i]) { if(distance[i] <= 9000000009 && distance[i] > 50) { min_distance = distance[i]; zombie = clients[i]; } } } return zombie; }
public bool:TraceASDF(entity, mask, any:data) { return (data != entity); }
Но она очень плохо работает, зачастую не видит игрока в упор, даже если между ними ничего нет. Не подскажите, как можно сделать нормальную функцию? Заранее спаибо ![prikol](/smiles/prikol.gif)
|
|
| |
Sedge
|
Дата: Понедельник, 04.05.2020, 08:09:37 | Сообщение # 2 |
![Пользователь](http://world-source.ru/groupicon/user_icon.jpg) |
Сообщений: 16
Репутация: 9 [ +/- ]
|
|
Просто используй на свою энти SDKHook(ent, SDKHook_SetTransmit, Hook_Ragdoll); и в нем уже делай определения радиуса что-то вроде этого:
Код public Action:Hook_Ragdoll(entity, client) { if (entcontrol[entity] > 0) { new Float:pos1[3]; new Float:pos2[3]; GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos1); GetEntPropVector(client, Prop_Send, "m_vecOrigin", pos2); if ((GetVectorDistance(pos1, pos2) < g_spwn[entcontrol[entity]])) { SetEntityMoveType(entity, MOVETYPE_FLY); } } }
|
|
| |
polo79655
|
Дата: Вторник, 12.05.2020, 10:40:59 | Сообщение # 3 |
![Активный](http://world-source.ru/groupicon/active_icon.jpg) |
Сообщений: 99
Репутация: -1 [ +/- ]
|
|
Цитата Sedge ( ![Ссылка на цитируемый текст](/.s/img/fr/ic/2/lastpost.gif) ) Просто используй на свою энти SDKHook(ent, SDKHook_SetTransmit, Hook_Ragdoll); и в нем уже делай определения радиуса что-то вроде этого:
Код public Action:Hook_Ragdoll(entity, client) { if (entcontrol[entity] > 0) { new Float:pos1[3]; new Float:pos2[3]; GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos1); GetEntPropVector(client, Prop_Send, "m_vecOrigin", pos2); if ((GetVectorDistance(pos1, pos2) < g_spwn[entcontrol[entity]])) { SetEntityMoveType(entity, MOVETYPE_FLY); } } }
Спасибо. Я не проверял ещё, потому что смог сделать другую функцию, которая более менее работает. Сразу говорю, это говно код, но как умею)))
Код FindAllTargets(client, players[]) { new Float:vAngle[3],Float:vClientPosition[3],Float:vEntPositionIgroks[3]; for (new i = 1; i <= MaxClients; i++) { players[i] = -1; } new Handle:trace; for (new igroks = 1; igroks <= MaxClients; igroks++) { if (!IsClientConnected(igroks) || !IsClientInGame(igroks) || !IsPlayerAlive(igroks) || players[igroks] == 1) { continue; } for (new j = 0; j<=9; j++) { if (players[igroks] == 1) { break; } GetClientEyePosition(igroks, vEntPositionIgroks); if (j == 0) { GetClientEyePosition(igroks, vEntPositionIgroks); } else if (j == 1) { GetClientEyePosition(igroks, vEntPositionIgroks); vEntPositionIgroks[2] -= 30; } else if (j == 2) { GetClientEyePosition(igroks, vEntPositionIgroks); vEntPositionIgroks[2] -= 45; vEntPositionIgroks[1] -= 30; vEntPositionIgroks[0] += 30; } else if (j == 3) { GetClientEyePosition(igroks, vEntPositionIgroks); vEntPositionIgroks[2] -= 45; vEntPositionIgroks[1] += 30; vEntPositionIgroks[0] -= 30; } else if (j == 4) { GetClientEyePosition(igroks, vEntPositionIgroks); vEntPositionIgroks[2] -= 45; vEntPositionIgroks[1] += 30; vEntPositionIgroks[0] += 30; } else if (j == 5) { GetClientEyePosition(igroks, vEntPositionIgroks); vEntPositionIgroks[2] -= 45; vEntPositionIgroks[1] -= 30; vEntPositionIgroks[0] += 30; } else if (j == 6) { GetClientEyePosition(igroks, vEntPositionIgroks); vEntPositionIgroks[2] -= 25; vEntPositionIgroks[1] -= 30; vEntPositionIgroks[0] -= 30; } else if (j == 7) { GetClientEyePosition(igroks, vEntPositionIgroks); vEntPositionIgroks[2] -= 25; vEntPositionIgroks[1] += 30; vEntPositionIgroks[0] -= 30; } else if (j == 8) { GetClientEyePosition(igroks, vEntPositionIgroks); vEntPositionIgroks[2] -= 25; vEntPositionIgroks[1] += 30; vEntPositionIgroks[0] += 30; } else if (j == 9) { GetClientEyePosition(igroks, vEntPositionIgroks); vEntPositionIgroks[2] -= 25; vEntPositionIgroks[1] -= 30; vEntPositionIgroks[0] += 30; } for (new i = 0; i <= 9; i++) { if (i == 0) { GetClientEyePosition(client, vClientPosition); } else if (i == 1) { GetClientEyePosition(client, vClientPosition); vClientPosition[2] -= 30; } else if (i == 2) { GetClientEyePosition(client, vClientPosition); vClientPosition[2] -= 45; vClientPosition[1] -= 30; vClientPosition[0] += 30; } else if (i == 3) { GetClientEyePosition(client, vClientPosition); vClientPosition[2] -= 45; vClientPosition[1] += 30; vClientPosition[0] -= 30; } else if (i == 4) { GetClientEyePosition(client, vClientPosition); vClientPosition[2] -= 45; vClientPosition[1] += 30; vClientPosition[0] += 30; } else if (i == 5) { GetClientEyePosition(client, vClientPosition); vClientPosition[2] -= 45; vClientPosition[1] -= 30; vClientPosition[0] += 30; } else if (i == 6) { GetClientEyePosition(client, vClientPosition); vClientPosition[2] -= 25; vClientPosition[1] -= 30; vClientPosition[0] -= 30; } else if (i == 7) { GetClientEyePosition(client, vClientPosition); vClientPosition[2] -= 25; vClientPosition[1] += 30; vClientPosition[0] -= 30; } else if (i == 8) { GetClientEyePosition(client, vClientPosition); vClientPosition[2] -= 25; vClientPosition[1] += 30; vClientPosition[0] += 30; } else if (i == 9) { GetClientEyePosition(client, vClientPosition); vClientPosition[2] -= 25; vClientPosition[1] -= 30; vClientPosition[0] += 30; } vClientPosition[2] -= 10.0; MakeVectorFromPoints(vEntPositionIgroks, vClientPosition, vAngle); vClientPosition[2] += 10.0; NormalizeVector(vAngle, vAngle); GetVectorAngles(vAngle, vAngle); trace = TR_TraceRayFilterEx(vEntPositionIgroks, vClientPosition, MASK_SHOT, RayType_EndPoint, TraceASDF, client); if(!TR_DidHit(trace)) { players[igroks] = 1; CloseHandle(trace); break; } CloseHandle(trace); } } } }
|
|
| |
tonline_kms65
|
Дата: Вторник, 09.06.2020, 03:45:09 | Сообщение # 4 |
![Пользователь](http://world-source.ru/groupicon/user_icon.jpg) |
Сообщений: 215
Репутация: 3 [ +/- ]
|
|
Ничего бредовее ещё не встречал. Что у тебя с мыслями? Как, будучи в здравом уме, такое придумать возможно? Или что нужно употребить, что бы такое изобрести, а главное зачем? ============================================== Как-то грубовато получилось. Исправляюсь.
Объясню на словах(код давать не буду) как это делается:
-для начала получим мах. размеры коробки(карты), это делать, естественно, один раз на всю карту. -циклом ищем всех игроков которые в игре и живые(отсеивать можно по командам или по дистанции) -самый интересный момент - нужно сравнить дистанцию от игрока до максимального размера карты(коробки), у какого игрока дистанция меньше тот и есть искомый-ближайший, это будет дистанция на которой есть ближайший игрок(пока без учета препятствий). Эту дистанцию, обязательно!, делаем след. дистанцией заместо размеров коробки(карты), так сказать, каждый тик уменьшаем радиус поиска игроков. -делаем трассировку к ближайшему игроку, что бы определить за препятствием игрок или нет, если за препятствием - цикл дальше, если игрок в зоне видимости - это цель. Нужно сделать еще возможность радиуса обзора, иначе беда(на затылке глаз не бывает) но это уже отдельная и достаточно сложная тема, знания математики приветствуются.
Безупречная работа кода обеспечена.
Сообщение отредактировал tonline_kms65 - Суббота, 18.09.2021, 08:51:24 |
|
| |
|