Просмотр полной версии : Поиск всех нпц в радиусе + проверка актуальности цели
В разных точках находятся нпц с кодами А, Б и В.
Используем итем - засчитывается точка.
Если вешать скрипт на итем, то нужно в момент использования найти одного из трех нпц.
С помощью GetClosestCreatureWithEntry можно найти нпц с определенным кодом.
Можно 3 раза данную вызвать функцию, но, как мне кажется, это нецелесообразно.
Возможно, поиск всех нпц в радиусе, а потом сравнение кодов с нужными будет более правильно.
Нашел веселые конструкции вида MaNGOS::NearestCreatureEntryWithLiveStateInObjectR angeCheck и т.д., но там тоже, вроде, привязка к коду, т.е. можно найти всех нпц, но одного кода.
1. Каким образом можно найти всех нпц в радиусе?
2. До кучи: как проверить, нпц/го/итем все еще является целью квеста или нет?
1. Был поисковик всех юнитов, завтра напишу точнее. В конце концов можно написать свой.
2. Если нпц - килл-кредиты, то их можно убивать, насчет го/итема не совсем понял
И конкретный пример-бы наверно всем не помешал-бы. ;)
В 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)->Действаия
}
GetCreatureListWithEntryInGrid - это поиск всех нпц с указанным кодом в радиусе.
Поясню: есть квесты http://ru.wowhead.com/?quest=5097/5098, в которых надо использовать итем в 4 точках, при этом суммонится го (факел).
Насколько я помню, квесты никогда не работали.
Написал скрипт, выполнил квест, все в порядке, но это на скорую руку, поэтому использовал 4 раза вызов GetClosestCreatureWithEntry, что нерационально.
Как мне кажется, было бы лучше найти всех нпц в радиусе, прокрутить их в цикле и сравнивать с кодами имеющихся нпц.
Для этой цели мне и нужен поиск всех мобов в радиусе.
Так в чем проблема. Есть функция для поиска всех объектов в радиусе, создавайте списки 1 - с котором хранятся указатели на все объекты в заданом радиусе и во втором нужные entry и работайте с ними в цикле. Я просто не могу вкурить в чем проблема.
Есть функция поиска всех нпц с определенным кодом.
Т.е. я не могу с помощью них взять всех нпц и, прокрутив один раз цикл, найти нужных.
Мне нужно взять сразу всех независимо от кода, чтобы прокрутить цикл один раз.
Прууу что есть код? Entry :) ?
Да.
Есть нпц с кодами=entry А, Б, В и Г.
Надо найти в радиусе ВСЕХ нпц одним методом/функцией, чтобы потом можно было прокрутить цикл и найти одного из них.
Вот такой симпатичный поисковичок
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
Если потребуется специфический поисковичок - напиши что надо, выложу
Такой же, как и http://ru-mangos.ru/showthread.php?t=291?
Было бы неплохо увидеть реализацию в ядре или СД2, чтобы не тягать каждый раз класс за собой.
В патчи для ядра уже выложен.
патч фактически не нужен, это уже есть в мангосе, я брал с чистых свежих сорцов :)
Хотя все-таки отличается, патч zevgen'a считает всех мобов, которые в радиусе и на линии видимости
Стандартный мангосовский - считает только живых и просто в радиусе, не считаясь с линией видимости
Надо более точно определить задачи этого поисковика, если он не будет использоватся в ядре, зачем его туда добавлять, достаточно в скриптах.
Нужно искать всех мобов в радиусе (вокруг), мертвых можно определить в цикле.
А вы уверены что в методе AnyUnitInObjectRangeCheck первым аргументом может быть m_creature?
Мне кажется, вопрос немного шире, чем предложил virusav. При этом он сам это говорил на мангос-конференции и при личном общении в аське.
В первую очередь нужно бы реализовать spell_effect ActivateObject... А потом уже и пытаться реализовать подобные квесты...
vBulletin® v3.8.4, Copyright ©2000-2024, Jelsoft Enterprises Ltd. Перевод: zCarot