Как я понимаю по коду работу эффекта 86 - Activate Object.
Работа фактически аналогична команде 13 в БД скриптах ГО
Пошагово как идет
Берем наш спелл - 17016
Код:
Effect: (086) SPELL_EFFECT_ACTIVATE_OBJECT
Base point = 0
Target A (TARGET_40), Target B (No target)
EffectMiscValue = 5
Код:
if(!gameObjTarget)
return;
static ScriptInfo activateCommand = generateActivateCommand();
int32 delay_secs = m_spellInfo->CalculateSimpleValue(eff_idx);
gameObjTarget->GetMap()->ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);
activateCommand = 13 всегда
delay_secs = 0, с нашего спелла(Base point = 0)
передаем дальше в ScriptCommandStart
2. там вычисляются гуиды таргета и кастера, добавляется в лист скриптов, и если задержка(delay_secs) равна 0, то передается дальше в ScriptsProcess();
3. Эта функция ищет нужный скрипт, и в зависимости от команды(она у нас всегда 13), делает проверки на кастера и таргет, на их типы - юнит или ГО, там много
Если все проверки пройдены, активируется функция ГО на кастера go->Use(caster);
4. а это уже интересней, именно в этой функции ГО кастует на кастера некий спелл(спеллы)
НО если есть скрипт GOHello - то return;
Код:
// by default spell caster is user
Unit* spellCaster = user;
uint32 spellId = 0;
bool triggered = false;
if (user->GetTypeId() == TYPEID_PLAYER && Script->GOHello((Player*)user, this))
return;
switch(GetGoType())
Но так как ГО не может кастовать спеллы, это делает сам кастер
Код:
Spell *spell = new Spell(spellCaster, spellInfo, triggered,GetGUID());
// spell target is user of GO
SpellCastTargets targets;
targets.setUnitTarget( user );
spell->prepare(&targets);
user - он же caster в п.3
ГО факел - принадлежит к 5 типу, обработки которого нет в Use(), мб стоит добавить? И в этой функции можно не только кастовать спеллы, но и другие действия выполнять(см. весь код функции)
Код:
default:
sLog.outError("GameObject::Use unhandled GameObject type %u (entry %u).", GetGoType(), GetEntry());
break;
Этим пока оканчивается попытка работать с 5 типом ГО
ПС : кстати, EffectMiscValue не используется в эффекте 86, но между тем, оно явно важно, т.к во всех спеллах оно разное, понять бы что это
Ответы на вопросы(по моему мнению)
1. GOHello активируется только вблизи обьекта(0 - 2 метра радиус)
2. Ошибка возникает здесь
Код:
ObjectGuid owner_guid = GetOwnerGUID();
if (!owner_guid.IsEmpty())
{
if (Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid))
owner->RemoveGameObject(this,false);
else
{
sLog.outError("Delete %s with SpellId %u LinkedGO %u that lost references to owner %s GO list. Crash possible later.",
GetObjectGuid().GetString().c_str(), m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), owner_guid.GetString().c_str());
}
}
Преположу, что гуид owner'a не пустой, но сервер по гуиду не может сослатся на обьект Unit, по каким причинам - пока не знаю
3. Оптимизировать тут врятли что-то можно, только мб написать отдельный универсальный поисковичок, с подачей любого листа ентри или гуидов(он сам их переберет - найдет нужный и вернет обьект)