PDA

Просмотр полной версии : Поиск всех нпц в радиусе + проверка актуальности цели


virusav
13.03.2010, 20:43
В разных точках находятся нпц с кодами А, Б и В.
Используем итем - засчитывается точка.
Если вешать скрипт на итем, то нужно в момент использования найти одного из трех нпц.

С помощью GetClosestCreatureWithEntry можно найти нпц с определенным кодом.
Можно 3 раза данную вызвать функцию, но, как мне кажется, это нецелесообразно.

Возможно, поиск всех нпц в радиусе, а потом сравнение кодов с нужными будет более правильно.

Нашел веселые конструкции вида MaNGOS::NearestCreatureEntryWithLiveStateInObjectR angeCheck и т.д., но там тоже, вроде, привязка к коду, т.е. можно найти всех нпц, но одного кода.

1. Каким образом можно найти всех нпц в радиусе?
2. До кучи: как проверить, нпц/го/итем все еще является целью квеста или нет?

MaS0n
13.03.2010, 22:12
1. Был поисковик всех юнитов, завтра напишу точнее. В конце концов можно написать свой.
2. Если нпц - килл-кредиты, то их можно убивать, насчет го/итема не совсем понял

YuruY
13.03.2010, 22:13
И конкретный пример-бы наверно всем не помешал-бы. ;)

zevgen
13.03.2010, 22:28
В Object.cpp

ifier, *aMap, *this, aMap->GetVisibilityDistance());

ClearUpdateMask(false);
}
+void WorldObject::GetCreatureListWithEntryInGrid(std::l ist<Creature*>& lList, uint32 uiEntry, float fMaxSearchRange)
+{
+ CellPair pair(MaNGOS::ComputeCellPair(this->GetPositionX(), this->GetPositionY()));
+ Cell cell(pair);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ MaNGOS::NearestCreatureEntryWithLiveStateInObjectR angeCheck check(*this, uiEntry, true, fMaxSearchRange);
+ MaNGOS::CreatureListSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectR angeCheck> searcher(this, lList, check);
+ TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectR angeCheck>, GridTypeMapContainer> visitor(searcher);
+
+ cell.Visit(pair, visitor, *(this->GetMap()));
+}

bool WorldObject::IsControlledByPlayer() const
{
switch (GetTypeId())
{


В Object.h

@@ -497,10 +497,11 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void BuildUpdateData(UpdateDataMapType &);

Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
Vehicle* SummonVehicle(uint32 id, float x, float y, float z, float ang, uint32 vehicleId = NULL);
GameObject* SummonGameobject(uint32 id, float x, float y, float z, float ang, uint32 despwTime);
+ void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, uint32 uiEntry, float fMaxSearchRange);

protected:
explicit WorldObject();

//these functions are used mostly for Relocate() and Corpse/Player specific stuff...



Воспользовался логикой из Trinity переписал функцию, так как, если мне не изменяет память стандартными средствами требуемая задача не решается.

Далее пример как с таким работать. Я использую у себя в скрипте на Игниса. Создаем список
std::list<Creature*> CreatureList;
m_creature->GetCreatureListWithEntryInGrid(CreatureList,ТО-ЧТО-ИЩЕМ,РАДИУСf);

И перебираем циклом
for (std::list<Creature*>::iterator itr = CreatureList.begin(); itr != CreatureList.end(); ++itr)
{
(*itr)->Действаия
}

virusav
13.03.2010, 22:47
GetCreatureListWithEntryInGrid - это поиск всех нпц с указанным кодом в радиусе.

Поясню: есть квесты http://ru.wowhead.com/?quest=5097/5098, в которых надо использовать итем в 4 точках, при этом суммонится го (факел).

Насколько я помню, квесты никогда не работали.

Написал скрипт, выполнил квест, все в порядке, но это на скорую руку, поэтому использовал 4 раза вызов GetClosestCreatureWithEntry, что нерационально.
Как мне кажется, было бы лучше найти всех нпц в радиусе, прокрутить их в цикле и сравнивать с кодами имеющихся нпц.

Для этой цели мне и нужен поиск всех мобов в радиусе.

zevgen
13.03.2010, 23:04
Так в чем проблема. Есть функция для поиска всех объектов в радиусе, создавайте списки 1 - с котором хранятся указатели на все объекты в заданом радиусе и во втором нужные entry и работайте с ними в цикле. Я просто не могу вкурить в чем проблема.

virusav
13.03.2010, 23:11
Есть функция поиска всех нпц с определенным кодом.
Т.е. я не могу с помощью них взять всех нпц и, прокрутив один раз цикл, найти нужных.

Мне нужно взять сразу всех независимо от кода, чтобы прокрутить цикл один раз.

zevgen
13.03.2010, 23:17
Прууу что есть код? Entry :) ?

virusav
13.03.2010, 23:22
Да.
Есть нпц с кодами=entry А, Б, В и Г.
Надо найти в радиусе ВСЕХ нпц одним методом/функцией, чтобы потом можно было прокрутить цикл и найти одного из них.

MaS0n
15.03.2010, 08:10
Вот такой симпатичный поисковичок
GridNotifiers.h

AnyUnitInObjectRangeCheck


По-моему, раз мы собрались использовать ее только в скриптах, обьявление в Object не требуется)

sc_creature.cpp

std::list<Creature*> ScriptedAI::GetCreatureList(float fRange)
{
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();

std::list<Creature*> pList;

MaNGOS::AnyUnitInObjectRangeCheck u_check(m_creature, fRange);
MaNGOS::CreatureListSearcher<MaNGOS::AnyUnitInObjectRangeCheck> searcher(m_creature, pList, u_check);

TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::AnyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);

CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *(m_creature->GetMap()));

return pList;
}


sc_creature.h

//Returns a list of all units within range
std::list<Creature*> GetCreatureList(float fRange);


ищет любых ЖИВЫХ мобов в определенном радиусе

В скриптах испотльзовать

std::list<Creature*> CreatureList = m_creature->GetCreatureList(10.0f(радиус));


и перебираем листик циклом, как у zevgen'a

Если потребуется специфический поисковичок - напиши что надо, выложу

virusav
15.03.2010, 09:25
Такой же, как и http://ru-mangos.ru/showthread.php?t=291?

Было бы неплохо увидеть реализацию в ядре или СД2, чтобы не тягать каждый раз класс за собой.
В патчи для ядра уже выложен.

MaS0n
15.03.2010, 09:54
патч фактически не нужен, это уже есть в мангосе, я брал с чистых свежих сорцов :)
Хотя все-таки отличается, патч zevgen'a считает всех мобов, которые в радиусе и на линии видимости
Стандартный мангосовский - считает только живых и просто в радиусе, не считаясь с линией видимости

Надо более точно определить задачи этого поисковика, если он не будет использоватся в ядре, зачем его туда добавлять, достаточно в скриптах.

virusav
15.03.2010, 10:16
Нужно искать всех мобов в радиусе (вокруг), мертвых можно определить в цикле.

zevgen
15.03.2010, 10:45
А вы уверены что в методе AnyUnitInObjectRangeCheck первым аргументом может быть m_creature?

KiriX
15.03.2010, 12:47
Мне кажется, вопрос немного шире, чем предложил virusav. При этом он сам это говорил на мангос-конференции и при личном общении в аське.
В первую очередь нужно бы реализовать spell_effect ActivateObject... А потом уже и пытаться реализовать подобные квесты...