ID по известным координатам
| |
tonline_kms65
|
Дата: Вторник, 20.02.2018, 06:55:30 | Сообщение # 1 |
|
Сообщений: 215
Репутация: 3 [ +/- ]
|
|
И снова всем здравствуйте. Появился у меня такой вопрос, как можно получить характеристики сущности(ID, name), имея точные координаты нахождения этой самой сущности? Или проще, я создал точку навигации на карте, записал её координаты в файл. На месте этих координат создаю ENT c именем класса. Сам вопрос, а как теперь узнать какая именно ENT находится в этой самой точке? Не могу сообразить. Или создавать ENT нужно как то по другому. Нужна сама мысль, как это можно сделать.
|
|
| |
_wS_
|
Дата: Вторник, 20.02.2018, 07:26:05 | Сообщение # 2 |
|
Если я правильно понял, то циклом идти по всем ent и проверять расстояние до этой точки (GetVectorDistance).
Код new entity = GetMaxEntities(); while (entity > MaxClients) { if (IsValidEntity(entity)) { // .. }
--entity; }
Еще trigger можно создать и ловить касание ent к нему.
|
|
| |
tonline_kms65
|
Дата: Вторник, 20.02.2018, 10:24:05 | Сообщение # 3 |
|
Сообщений: 215
Репутация: 3 [ +/- ]
|
|
Код #define MAX_POINTS 300 // ограничение вейпоинтов
int count; //кол-во созданных вейпоинтов float point[count][3]; сам вейпоинт, его положение(массив)
Пытаюсь пройти циклом по кол-ву созданных(они увеличиваются при создании и уменьшаются при удалении):
Код for(new i = 1; i < count++i){ point[i]........ ....... .... Не хочет зараза и все тут. не перебирает. Где-то я косячу. Если пройти по всем ENT то работает, но это же нужно перебрать сколько ENT, это лишняя нагрузка. MAX_ENT если будет например 2000
Код for(new i = 1; i < MAX_ENT; ++i){ только заметил - здесь можно по моему начинать не с 1(1-32 это ведь игроки) взять MaxClients, правда не пробовал, попробую. if(IsValidEntity(i)){ GetEdictClassname(i, classname, sizeof(classname)); if(StrEqual(classname, "class_waypoint", true)){ GetEntPropVector(i, Prop_Send, "m_vecOrigin", point_pos); ..... ..
У меня, кстати, этот вопрос остался нерешенным в Дроне. Я там так и перебираю все ENT. Абсурд - создал к примеру 3 Дрона, а перебираю все ENT, для того что бы найти эти 3 Дрона.
Сообщение отредактировал tonline_kms65 - Вторник, 20.02.2018, 10:41:40 |
|
| |
_wS_
|
Дата: Вторник, 20.02.2018, 18:21:39 | Сообщение # 4 |
|
Не понимаю почему ты просто не хранишь индексы созданных ent?
Код new Handle:g_hAr;
public OnPluginStart() { g_hAr = CreateArray(1); HookEvent("round_start", round_start, EventHookMode_PostNoCopy); }
public round_start(Handle:event, const String:name[], bool:silent) { ClearArray(g_hAr); }
создание_ent() { new ent = CreateEntityByName(...);
// PushArrayCell(g_hAr, EntIndexToEntRef(ent)); //
... }
цикл_по_созданным_ent() { new index = GetArraySize(g_hAr); decl ent;
while (--index != -1) { if ((ent = EntRefToEntIndex(GetArrayCell(g_hAr, index))) > MaxClients) { ... } } }
|
|
| |
_wS_
|
Дата: Вторник, 20.02.2018, 18:24:08 | Сообщение # 5 |
|
Цитата tonline_kms65 ( ) #define MAX_POINTS 300 // ограничение вейпоинтов
int count; //кол-во созданных вейпоинтов float point[count][3]; сам вейпоинт, его положение(массив)
for (new i = 1; i < count; ++i) { point[i]........ Тут должно быть for (new i = 0;
|
|
| |
_wS_
|
Дата: Вторник, 20.02.2018, 20:50:24 | Сообщение # 6 |
|
Цитата tonline_kms65 ( ) уменьшаются при удалении Еще мне кажется тут у тебя ошибка, покажи как уменьшаешь и как добавляешь (int count)
|
|
| |
tonline_kms65
|
Дата: Понедельник, 26.02.2018, 16:59:24 | Сообщение # 7 |
|
Сообщений: 215
Репутация: 3 [ +/- ]
|
|
Прошу прощения за долгий ответ. Решил отказаться от ENT в качестве вейпоинтов. Все-таки удачнее использовать в качестве навигации просто точки. Код из любого плагина с созданием точек спавна.
Основная проблема - как, по какому критерию искать эти самые точки? Ближайшие точки(координаты). Если я нахожусь на точке, то конечно её видно. Но мне нужны позиции ближайших точек. С ENT я могу просто, по имени класса, в указанном радиусе пройти. А как найти ближайшую точку не пойму. У неё ведь нет имени класса, у неё вообще ничего нет, просто координаты на карте и всё. Это не ENT, свойства точке не задашь. У меня не хватает воображения, как это можно сделать. С координатами все намного проще, но в то-же время и не просто. Или я просто так на ENT зациклился, что не вижу того что рядом.Добавлено (26.02.2018, 16:47:02) --------------------------------------------- Видео https://youtu.be/bD7Xm52zkKo Добавлено (26.02.2018, 16:59:24) ---------------------------------------------
Цитата _wS_ ( ) Еще мне кажется тут у тебя ошибка, покажи как уменьшаешь и как добавляешь (int count) Я просто перезаписывал(удалял всё и писал по новой) текстовый файл с данными. Это не то. Меня не устраивает. Хорошо то, что не нужно использовать таймер для постоянного обновления, и хорошо то что к ENT можно добавить целую кучу свойств(какой вейпоинт, бомплейс, кемперский, просто движение, привязку этого вейпоинта к другому, его флаги, и т.д.) Плохо то, что как раз таки нет постоянного обновления.
А вот с простыми координатами(точками) я не знаю пока как быть. Но нравится мне это больше. Может быть, при создании точек, в сам массив писать и их свойства? Нужно попробовать.
Гости не могут скачивать файлы
|
Сообщение отредактировал tonline_kms65 - Понедельник, 26.02.2018, 12:05:55 |
|
| |
_wS_
|
Дата: Понедельник, 26.02.2018, 19:42:38 | Сообщение # 8 |
|
Цитата tonline_kms65 ( ) А как найти ближайшую точку не пойму. У неё ведь нет имени класса, у неё вообще ничего нет, просто координаты на карте и всё. Я уже вроде ответил на это =\ Точки это координаты, эти точки хранятся в массиве, цикл по массиву с точками и проверяем расстояние.
Код new Handle:g_hTo4ka; // список точек (координаты) new Handle:g_hTo4kaName; // имя точки (для примера, как хранить дополнительную инфу)
public OnPluginStart() { g_hTo4ka = CreateArray(3); g_hTo4kaName = CreateArray(50);
HookEvent("round_start", round_start, EventHookMode_PostNoCopy); }
// Возможно нужен не round_start, а OnMapStart. public round_start(Handle:event, const String:name[], bool:silent) { ClearArray(g_hTo4ka); ClearArray(g_hTo4kaName); }
создание_ent() { new ent = CreateEntityByName(...);
// new Float:to4ka[3] = Float:{1.0, 2.0, 3.0}; new String:to4ka_name[] = "test";
PushArrayArray(g_hTo4ka, to4ka, 3); PushArrayString(g_hTo4kaName, to4ka_name); // // И когда у нас есть индекс танка (TankEnt) и надо найти ближайшую точку: decl Float:result_pos[3], String:to4ka_name[50]; if (ПолучитьКоординатыБлижайшейТочки(TankEnt, result_pos, to4ka_name)) { PrintToChatAll("Ближайшая точка '%s' (%.1f %.1f %.1f)", to4ka_name, result_pos[0], result_pos[1], result_pos[2]); }
... }
stock bool:ПолучитьКоординатыБлижайшейТочки(TankEnt, Float:result_pos[3], String:to4ka_name[50]) { decl Float:TankEnt_pos[3]; GetEntPropVector(TankEnt, Prop_Data, "m_vecAbsOrigin", TankEnt_pos);
new index = GetArraySize(g_hTo4ka); new Float:fDistMin = 0.0; decl Float:x_pos[3], Float:fDist;
while (--index != -1) { GetArrayArray(g_hTo4ka, index, x_pos, 3); if ((fDist = GetVectorDistance(x_pos, TankEnt_pos)) < fDistMin || fDistMin == 0.0) { fDistMin = fDist; result_pos[0] = x_pos[0]; result_pos[1] = x_pos[1]; result_pos[2] = x_pos[2]; GetArrayString(g_hTo4kaName, index, to4ka_name, 50); } } return fDistMin != 0.0; } Только когда танк доехал до точки, нужно её сохранить и потом игнорировать при поиске новой ближайшей точки.
|
|
| |
tonline_kms65
|
Дата: Вторник, 27.02.2018, 04:15:31 | Сообщение # 9 |
|
Сообщений: 215
Репутация: 3 [ +/- ]
|
|
_wS_, Мы с тобой как в поговорке про Фому и Ерему. Вроде об одном и том же, но по разному как-то. Или я тебя не правильно понимаю, или ты меня. От создания ENT я отказался, я уже писал. Причина там была именно в создании самой ENT. Нет той мобильности и оперативности как с просто координатами (точкой). Ситуация в общем выглядит так: 1. создаю какой-то набор точек(координат) на карте. Весь этот набор записываю в текстовый файл(для каждой карты свой) 2. считываю координаты точек, и создаю ENT. 3. работаю с созданными ENT Так вот слабое место здесь, это создание ENT. По идее зачем их создавать? Да с ними удобнее, понятнее. Но это лишние расчеты, лишняя нагрузка, создание кучи ENT с их ID и т.д. Во вторых неудобства начинаются при корректировке маршрута (добавление, удаление ENT). Так просто переписал точку и все, а в случае с созданием ENT это постоянное изменение их ID, обновление что-бы сделать - кучка проблем, всё это дополнительные сложности. Не знаю, понятно или нет объяснил, точка она и есть точка, например точка №1, точка №2, и т.д. Вот я и хочу просто дописать к этой точке не только её номер, координаты и углы, но и например глобальное имя, имя класса, флаги и т.д. Флаг нужен для, к примеру, активирована точка - становится неактивной, пока не активирована - активна. Вот это мне интересно. Прочитается ли потом поиск по этому, например, по имени или имени класса(номер же не для всех точек один не задашь)
Добавлено (27.02.2018, 04:15:31) --------------------------------------------- типа такой записи в текстовом файле - координаты, углы, имя класса.
Код 1.691101 -783.103393 135.643127 0.000000 1.813337 0.000000 "classname" "class_waypoint" -277.506530 -770.624694 75.003135 0.000000 1.813337 0.000000 "classname" "class_waypoint"
Сообщение отредактировал tonline_kms65 - Вторник, 27.02.2018, 04:20:08 |
|
| |
_wS_
|
Дата: Вторник, 27.02.2018, 04:56:41 | Сообщение # 10 |
|
Запутано всё. У тебя есть танк (одна ent) и куча точек (координат origin). Твой вопрос был как получить координаты ближайшей точки, я на него ответил: stock bool:ПолучитьКоординатыБлижайшейТочки(TankEnt, Float:result_pos[3], String:to4ka_name[50])
Как хранить вместе с координатами и другую инфу, тоже показал (g_hTo4kaName). Если я неправильно отвечаю, тогда задавай вопрос корректнее. Нужно найти ближайшую точку, а что нам известно? Есть массив с координатами, с этим разобрались, ну и есть же сам танк разве нет? Ну вот и получаем координаты танка и находим эту ближайшую точку, не знаю как по-другому можно ответить или понять твой вопрос.
|
|
| |
tonline_kms65
|
Дата: Четверг, 01.03.2018, 18:56:48 | Сообщение # 11 |
|
Сообщений: 215
Репутация: 3 [ +/- ]
|
|
Ну вроде всё, я разобрался. Остановился на варианте с точками, без создания ENT.
Принцип следующий: 1. Создаю точки на карте. Сделал несколько видов наземных вейпоинтов (простой, бомбплейс 3 видов, кемперский). Примерно по такому же типу и создание вейпоинтов для воздуха. 2. Созданные точки, при сохранении, записываю в текстовый файл такого вида:
Код 278.137084 2390.010253 -126.306930 0.000000 85.303268 0.000000 class_gr_wpbombplb //бомбплэйс В 385.627166 2397.619384 -125.687614 0.000000 85.303268 0.000000 class_gr_wpbombplc //бомбплэйс С 288.481933 2272.243652 -126.499694 0.000000 85.303268 0.000000 class_gr_wpkemp // кемперский 156.917434 2405.375000 -126.775321 0.000000 95.269386 0.000000 class_gr_wpnrm // нормальный 450.335510 2451.042724 -115.058654 0.000000 95.269386 0.000000 class_gr_wpnrm // нормальный
3. При загрузке карты считываю все координаты в массив точек. 4. Можно использовать по назначению. Работает на ура.
Есть у меня одна проблема, в свое время я вплотную занимался работой именно с текстовыми файлами, на бейсике. Но это было так давно, что уже все забылось. Вот и возникла проблема в неправильном считывании из текстового файла класса вейпоинта (например class_gr_wpbombplc) Т.е. при расстановке вейпоинтов и при их записи в файл, все работает безупречно. Проблема именно при считывании. Значения float читает без ошибок, а вот string не считывает, вернее считывает, но или не в том формате или еще что то. Объявил массив так Код new String:spawnClassName[MAX_POINTS][26]; // это для class_gr_wpbombplc (строкой) /* ЧТЕНИЕ ИЗ ФАЙЛА */
Код char buffer[256]; new String:parts[7][26]; // можно конечно по новому char, но пока так сделал. while (!IsEndOfFile(file) && ReadFileLine(file, buffer, sizeof(buffer))){ ExplodeString(buffer, " ", parts, 7, 26); spawnPositions[iSpawnWaipointCount][0] = StringToFloat(parts[0]); spawnPositions[iSpawnWaipointCount][1] = StringToFloat(parts[1]); spawnPositions[iSpawnWaipointCount][2] = StringToFloat(parts[2]); spawnAngles[iSpawnWaipointCount][0] = StringToFloat(parts[3]); spawnAngles[iSpawnWaipointCount][1] = StringToFloat(parts[4]); spawnAngles[iSpawnWaipointCount][2] = StringToFloat(parts[5]); // здесь из строки конвертирую в float spawnClassName[iSpawnWaipointCount] = parts[6]; // косяк, по моему, здесь. Возможно я не правильно понял принцип работы ExplodeString. iSpawnWaipointCount++; }
Добавление имени класса при создании вейпоинтаКод spawnClassName[iSpawnWaipointCount] = "class_gr_wpnrm"; Вот здесь подсказку бы. Чувствую сам не разберусь. Может быть как то нужно строку в строку конвертировать, хотя не понимаю как так, но кто его знает.
Добавлено (01.03.2018, 16:16:55) --------------------------------------------- Да, чуть не забыл, сам процес визуальной подсветки вейпоинтов, код:
Код for (int i = 0; i < iSpawnWaipointCount; i++){ float spawnPosition[3]; AddVectors(spawnPositions[i], spawnPointOffset, spawnPosition); //размер свечения, в высоту.
if (StrEqual(spawnClassName[i], "class_gr_wpnrm", false)){ // И вот здесь не сравниваются 2 строки, они непохожи. Не пойму что за ..... TE_SetupGlowSprite(spawnPosition, glowSpriteNormal, 1.0, 0.5, 255); TE_SendToAll(); } ...... .... ...
Добавлено (01.03.2018, 16:32:33) ---------------------------------------------
Цитата _wS_ ( ) создание_ent() { new ent = CreateEntityByName(...); ..........
Вот от этого то я и отказался. Да оно удобно, да оно проще. Но давай представим, при создании карты, типа новой Дуст2 (csgo) в хаммере было использовано, например, 1900 ENT, игроков 32 - +32ENT, +ENT от плагинов, и здесь я добавляю ENT штук 300 в виде вейпоинтов. А у каждой ENT свой ID номер, свои свойства, и т.д. При перезагрузке карты, при редактировании вейпоинтов, их ID будет меняться. Но не нравится не это, не нравится вот эта масса ID. У точек нет ID. Точка и точка. Да и номер (подобие ID) ей присваивается уже постоянный, по крайней мере до её редактирования. Возможно я и где-то ошибаюсь.
Добавлено (01.03.2018, 18:56:48) --------------------------------------------- Решил проблему, пошел другим путем. Перевел все строки в цифру, все работает распрекрасно. Пока пусть строка для меня останется проблемой. Можно считать проблема решена "не мытьём так катаньем".
Гости не могут скачивать файлы
|
Сообщение отредактировал tonline_kms65 - Четверг, 01.03.2018, 20:17:59 |
|
| |
_wS_
|
Дата: Пятница, 02.03.2018, 02:57:40 | Сообщение # 12 |
|
Цитата tonline_kms65 ( ) if (StrEqual(spawnClassName[i], "class_gr_wpnrm", false)){ // И вот здесь не сравниваются 2 строки, они непохожи. Не пойму что за ..... Вывел бы значение в чат ('%s') или еще куда-то и стало бы понятно. После ExplodeString нужно чистить пробелы
Код TrimString(parts[6]); strcopy(spawnClassName[iSpawnWaipointCount], sizeof(spawnClassName[]), parts[6]);
Цитата tonline_kms65 ( ) создание_ent() { new ent = CreateEntityByName(...); ..........
Вот от этого то я и отказался. Эта часть кода вообще роли не играет и оно не нужно. По коду же видно что этот ent нигде и не используется, нужен лишь индекс танка и массив со всеми "x y z" точками и находится ближайшая.
|
|
| |
tonline_kms65
|
Дата: Суббота, 03.03.2018, 19:57:49 | Сообщение # 13 |
|
Сообщений: 215
Репутация: 3 [ +/- ]
|
|
Цитата _wS_ ( ) После ExplodeString нужно чистить пробелы Вот была же такая мысль, даже на скринах видно, до перезагрузки карты информация о точке, в чате, в одну строку влезает, после перезагрузки карты переносит 2 последних символа на след. строку. Как нибудь на досуге, время выберу, займусь. Проверю эту теорию. Спасибо за подсказку.
Цитата _wS_ ( ) создание_ent(){ new ent = CreateEntityByName(...); Вот оно что. Я тебя неправильно понял. Эта ENT, ты про танк имел в виду. Сейчас понятно, а я думаю, что ты так на ней зациклился. Редактор вейпоинтов у меня отдельным плагином идет. Только редактор. Все остальные плагины так же отдельно, все Дроны. Этот танк, кстати, тоже дрон .
Добавлено (03.03.2018, 07:54:22) ---------------------------------------------
Цитата _wS_ ( ) TrimString(parts[6]); strcopy(spawnClassName[iSpawnWaipointCount], sizeof(spawnClassName[]), parts[6]);
Действительно заработало. Значит были пробелы. Все, исправил, работает! Спасибо за подсказку.
Добавлено (03.03.2018, 13:38:04) --------------------------------------------- --------------------------------------------------------------------------------------------------------------------------
Первые шаги. https://youtu.be/pZkGNlzGGj4
Добавлено (03.03.2018, 19:57:49) --------------------------------------------- Плавные повороты на точках. https://youtu.be/ibErR1igBRI
Сообщение отредактировал tonline_kms65 - Суббота, 03.03.2018, 20:02:23 |
|
| |
_wS_
|
Дата: Воскресенье, 04.03.2018, 06:56:51 | Сообщение # 14 |
|
Цитата tonline_kms65 ( ) Плавные повороты на точках. Было бы лучше если бы он не останавливался во время поворота.
|
|
| |
tonline_kms65
|
Дата: Среда, 07.03.2018, 04:31:38 | Сообщение # 15 |
|
Сообщений: 215
Репутация: 3 [ +/- ]
|
|
Цитата _wS_ ( ) Было бы лучше если бы он не останавливался во время поворота.
Это можно, у меня сейчас проблема возникла другая. Сейчас я сделал так: Вейпоинты Дрон видит только те, которые спереди, в указанном градусе. Те вейпоинты, на которых нет крутого поворота, Дрон проходит без остановки.
Я не могу трассировкой получить стену (браш). То-есть, видно ближайший вейпоинт через стены. Не могу сообразить как сделать. Проблема сейчас в том, что некоторые вейпоинты, которые скрыты за стенами, "видно", соответственно Дрон двигается к скрытому за стеной вейпоинту, Трассировкой я могу получить конечную точку, могу получить ENT, а вот как получить браш(мир) не пойму, нужно что то мудрить. Может быть сравнивать длинны векторов, например вектор от Дрона до вейпоинта, и вектор от Дрона до конечной точки. Но это одна из моих мыслей. Возможно есть что-то, чем можно определить браш?
Немного подкорректировал код, стены вроде увидел, но нужно более подробно тестировать. https://youtu.be/XghJbFJIMcs
Сообщение отредактировал tonline_kms65 - Среда, 07.03.2018, 11:40:28 |
|
| |
|