• Страница 1 из 1
  • 1
Модератор форума: Dimitro  
Ошибка в коде + Вопрос по поводу SmartAI
Stormtrooper
Командир
Всем добрый день
Есть вот такой вот скрипт для моба:


Код
/*#####
npc_dreghooddrudge
#####*/

enum edrudge
{
    NPC_DRUDGE = 18122,

    SPELL_SHAREDBONDS = 34788
};

class npc_dreghooddrudge : public CreatureScript
{
    public:
        npc_dreghooddrudge() : CreatureScript("npc_dreghooddrudge") {}

    struct npc_dreghooddrudgeAI : public ScriptedAI
    {
        npc_dreghooddrudgeAI(Creature* pCreature) : ScriptedAI(pCreature) {}

        uint32 share_timer{};

        uint64 drudgeGUID{};

        void Reset()
        {
            share_timer = 1000;    
            drudgeGUID = 0;
        }
    
        void EnterCombat(Unit* /*who*/) {}
    
        void UpdateAI(const uint32 uiDiff)
        {
            if (share_timer <= uiDiff)
            {
                if (Creature * ally = GetClosestCreatureWithEntry(me, NPC_DRUDGE, 20.0f, true))
                {
                    if (me->IsInCombat() && ally->IsInCombat() && me->IsInRange(ally, 0.0f, 20.0f))
                    {
                        drudgeGUID = ally->GetGUID();

                        if (Unit * drud = Unit::GetCreature(*me, drudgeGUID))
                        {
                            DoCast(drud, SPELL_SHAREDBONDS);
                        }
                    }
                }
                share_timer = 1000;
            }
            else share_timer -= uiDiff;

            if (!UpdateVictim())
                return;

            DoMeleeAttackIfReady();
        }
    };

    CreatureAI* GetAI(Creature* creature) const
    {
        return new npc_dreghooddrudgeAI(creature);
    }
};

Вроде всё просто - моб по таймеру ищет соседа и если находит то кастует в него спелл
Но вот проблема - моб который ищет и сам имеет тот же Entry что и сосед
По какой-то причине данный скрипт находит самого себя и касутет спелл тоже в себя (я проверял - если бы он кастовал не в себя то он накладывал бы щит на соседа, а он на самом мобе появлется)

Если такой же по сути скрипт написать на SmartAI то всё кастуется нормально

Объясните где я ошибаюсь? Почему эта падла обнаруживает сам себя а не моба-соседа в 10 метрах?

p.s при чём я нарочно делал ещё одну проверку - me->IsInRange(ally, 0.0f, 20.0f))
я ставил не 0.0f а 0.1f чтобы скрипт не шёл дальше если моб нашёл сам себя - вот собственно дальше скрипт и не шёл
тоесть соседа он не ищет а только самого себя

Второй вопрос:
Подскажите плиз как на SmartAI написать скрипт который будет обнаруживать труп моба и заставлять того кто его обнаружил менять фракцию?
На С++ это элементарно а вот на SmartAI я так и не понял как это сделать

Поясню:
Есть моб-Стражник и моб-Хозяин
Если моб-Хозяин помер в бою то моб-Стражник должен поменять фракцию на 35 и свалить с воплями "аааааа не бей меня!!!"
Если помог, ставь плюсик в репу :)

Сообщение # 1 отредактировано Stormtrooper - Понедельник, 01.02.2021, 17:09
Sergey996
Чемпион
добавить в if дополнительное условие ally != me
Продажа готовых сборок cataclysm 4.3.4, legion (7.3.5), shadowlands, draginflight. Исправление спеллов, квестов, крашей на любых версиях вов. Цена договорная. Пишите в лс, не дорого.
Сообщение # 2 написано 01.02.2021 в 20:44
Stormtrooper
Командир
Цитата Sergey996 ()
добавить в if дополнительное условие ally != me

И скрипт на этом завершится так как не пройдёт условие

На строке  if (Creature * ally = GetClosestCreatureWithEntry(me, NPC_DRUDGE, 20.0f, true)) он обнаружит самого себя,
а условие if (ally != me) завершит выполнение проверок так как ally == me после первой строки поиска
всё
Если помог, ставь плюсик в репу :)

Сообщение # 3 написано 02.02.2021 в 13:32
Sergey996
Чемпион
Цитата Stormtrooper ()
GetClosestCreatureWithEntry
в таком случае необходимо отказаться от его и заменить на функцию которая выдает всех мобов с таким же ид, а не конкретно одного ближайшего.
Так же убрал лишний код, брать GetGuid() моба и повторно вызывать его через GetCreature() в данном (как и в предыдущем случае не требуется) если druid = ally.
Код
std::list<Creature*> tempList;
// me->GetCreatureListWithEntryInGrid(tempList, NPC_DRUDGE, 20.0f); - на тринити
GetCreatureListWithEntryInGrid(tempList, me, NPC_DRUDGE, 20.0f); // вероятно на орегоне.

//for (Creature* druid : tempList) - на тринити (если подойдет, предпочтительно)
for (std::list<Creature*>::iterator itr = tempList.begin(); itr != tempList.end(); ++itr) // по старому
{
if (Creature* druid = *itr) // старый вариант, убрать если от тринити подошло.
    if (me != druid && me-->IsInCombat() && druid->IsInCombat() && druid->IsAlive()) // проверка моб1 != моб2, оба моба в бою, моб2 живой.
        DoCast(drud, SPELL_SHAREDBONDS);
}
С Орегоном не знаком, работаю только с тринити, но зная старые ревы, все функции должны присутствовать, разве что начинаются с маленькой буквы.

Так же, по логике такого скрипта, если стоит 3 и более моба, то первый наложит на всех остальных. Если нужно конкретно на одного, DoCast вставить в скобки и после его вставить break который прервет цикл.
Продажа готовых сборок cataclysm 4.3.4, legion (7.3.5), shadowlands, draginflight. Исправление спеллов, квестов, крашей на любых версиях вов. Цена договорная. Пишите в лс, не дорого.
Сообщение # 4 отредактировано Sergey996 - Вторник, 02.02.2021, 16:28
Stormtrooper
Командир
ВСЁЁЁЁЁЁ ПОНЯЛ!
ОСОЗНАЛ!
ЗАРАБОТАЛО!

Чувак спасибо огромное! Ставлю плюсик

А по поводу SmartAI нет идей? smile
Если помог, ставь плюсик в репу :)

Сообщение # 5 отредактировано Stormtrooper - Вторник, 02.02.2021, 17:15
Sergey996
Чемпион
Цитата Stormtrooper ()
А по поводу SmartAI нет идей?

Я бы рекомендовал не париться и делать на ScriptedAI.
В ином случае, логику предложил бы не много изменить:
При смерти хозяина использовать action 45 SetData по цели - прислужник.
прислужник получая SetData (event_type 38) меняет фракцию на 35 и говорит текст через зависимое событие (61 event type, а в смарте с заменой фракции ранее - link зависимого события).

Это при условии, что там смарт пашет так же как у ТС.
Продажа готовых сборок cataclysm 4.3.4, legion (7.3.5), shadowlands, draginflight. Исправление спеллов, квестов, крашей на любых версиях вов. Цена договорная. Пишите в лс, не дорого.
Сообщение # 6 написано 02.02.2021 в 18:53
Stormtrooper
Командир
Проблема в том что прислужников всегда 2 и они оба должны дать дёру если хозяин помер
при чём не обязательно в бою
можно просто офигачить хозяина а тусящие рядом прислужники должны свалить даже не входя в бой с игроком

поэтому скрипт должен работать со стороны прислужников а не со стороны умершего хозяина
тоесть прислужники должны сканировать мир вокруг себя на предмет трупа хозяина и драпать если таковой найдётся

на С++ подобное сканирование пишется элементарно а вот на SmartAI или на ScriptedAI хз как делается
Если помог, ставь плюсик в репу :)

Сообщение # 7 отредактировано Stormtrooper - Среда, 03.02.2021, 13:26
Sergey996
Чемпион
Цитата Stormtrooper ()
ScriptedAI

Ну так сделай на scriptedai,вставь в updateai прислужникам чек наличия хозяина, чек фракции и при соблюдении условий поменять фракцию и юзнуть Talk(0) - текст из creature_text. Чек фракции необходим чтоб не срабатывало сразу несколько раз.
Если хозяин один, не обязательно юзать GetCreatureListWithEntryInGrid, достаточно будет FindNearestCreature - аналог функции GetClosestCreatureWithEntry.

Если нужно, можно реализовать ниже чтоб через определенное время чекалось наличие "хозяина" и фракция менялась обратно. В таком случае, ивента уже 2, в таком случае можно использовать для удобства events в UpdateAI (EventMap).

Со смартом я почти не работаю, там свои ограничения и какой смарт на орегоне мне неизвестно. На тринити его за последние 5-7 лет достаточно сильно изменили и дополнили. Так что ScriptedAI проще.
Продажа готовых сборок cataclysm 4.3.4, legion (7.3.5), shadowlands, draginflight. Исправление спеллов, квестов, крашей на любых версиях вов. Цена договорная. Пишите в лс, не дорого.
Сообщение # 8 написано 03.02.2021 в 14:48
  • Страница 1 из 1
  • 1
Поиск: