PDA

Просмотр полной версии : Начинающим разбираться в коде MaNGOS


Wish
09.03.2010, 13:15
Помню гдето был патч на комманду ст, при использование ее, когда ты дух, тебя телепортировало на близайщее кладбище, воскрещало и кидало
Собственно патч данный я не смог найти, решил сам написать

Вроде все нормально при юзание комманды ст, он тп к кладбищу и воскрещается, но немогу реализовать добавление ауры (http://www.wowhead.com/?spell=15007) к персу, лазил в коде искал примеры, конкретного ничего не нашел(может и видел, но собственно незнаю как она зовется там)

Кто знает прошу помочь

BombermaG
09.03.2010, 13:20
Для начала стоит ссылочки указывать на wowhead, а не какой-то лан сайт :)

Wish
09.03.2010, 13:23
Для начала стоит ссылочки указывать на wowhead, а не какой-то лан сайт :)
чтож бывает, как вы заметили это лан сайт, где мне удобней работать, чем на вовхеде

virusav
09.03.2010, 22:33
В скрипте СД2 использовал:
pPlayer->CastSpell(pPlayer,SPELL_ID,false);
, где Player* pPlayer.

Работает, подставь свой спелл вместо SPELL_ID и проверь.

Wish
10.03.2010, 04:47
В скрипте СД2 использовал:
pPlayer->CastSpell(pPlayer,SPELL_ID,false);
, где Player* pPlayer.

Работает, подставь свой спелл вместо SPELL_ID и проверь.
Спасибо
chr->CastSpell(chr,15007,false);
Не подскажите для чего в свойствах функции, последнее свойство, тру, фолс?

virusav
10.03.2010, 09:16
Если не ошибаюсь, последний параметр отвечает за триггерность спелла, т.е. если спелл триггерный, то ставим true, иначе false.

Wish
10.03.2010, 11:35
virusav
Спасибо за оказанное время и помощь, вроде проект обучающий но помогаете один только вы

Предлагаю тему переименовать в "Изучение кода мангоса", помнится такая была на предыдущем форуме и автор был ее Kirix, столько полезной инфы было в ней:sorry:

Еще 1 вопрос
что нужно подключить или прописать чтобы данный код работал
if(int32(getLevel()) < startLevel+9)
{
int32 delta = (int32(getLevel()) - startLevel + 1)*MINUTE;

if(Aura * aur = GetAura(15007, GetGUID()))
}
При попытке скомпилировать выдает ошибку в неизвестных идентификаторах

KiriX
10.03.2010, 12:43
virusav
Спасибо за оказанное время и помощь, вроде проект обучающий но помогаете один только вы

Предлагаю тему переименовать в "Изучение кода мангоса", помнится такая была на предыдущем форуме и автор был ее Kirix, столько полезной инфы было в ней:sorry:

Еще 1 вопрос
что нужно подключить или прописать чтобы данный код работал
if(int32(getLevel()) < startLevel+9)
{
int32 delta = (int32(getLevel()) - startLevel + 1)*MINUTE;

if(Aura * aur = GetAura(15007, GetGUID()))
}
При попытке скомпилировать выдает ошибку в неизвестных идентификаторах

1) Не все успевают моментально ответить на появляющиеся вопросы. Лично я три своих выходных полностью посвятил настройке форума, было не до заполнения. А сейчас я работаю - времени мало... А вообще моя жена на меня сильно обиделась, когда я потратил на форум все свои выходные и совершенно (стыдно :sorry:) не уделил внимания ей... Так что вполне вероятно меня домашним арестом на время от интернета вообще "отлучат"...
2) Спасибо что напомнили о хорошей теме. Ваше пожелание учтено =)

Dereka
10.03.2010, 12:44
Еще 1 вопрос
что нужно подключить или прописать чтобы данный код работал
if(int32(getLevel()) < startLevel+9)
{
int32 delta = (int32(getLevel()) - startLevel + 1)*MINUTE;

if(Aura * aur = GetAura(15007, GetGUID()))
}
При попытке скомпилировать выдает ошибку в неизвестных идентификаторах

ищи где описаны getLevel() GetAura() и чей GetGUID() тебе нужен
потом прописывай эти хеадеры(*.h файлы) в своём .cpp файле

KiriX
10.03.2010, 13:00
А что, функции воскрешения отсутствует или она отделена от наложения маски воскрешения?

Сейчас на работе - под рукой нет исходников =)

Wish
10.03.2010, 13:10
А что, функции воскрешения отсутствует или она отделена от наложения маски воскрешения?
отделена,
воскрешение прописано так chr->ResurrectPlayer(0.0f, false);
ищи где описаны getLevel() GetAura() и чей GetGUID() тебе нужен
потом прописывай эти хеадеры(*.h файлы) в своём .cpp файле
Прописывал эти самые *.h файлы в инклуде, но ошибка таже, неизсветный идентификатор
getLevel, GetGUID, предполагаю они конкретно не определены в *.h файлах, а определяются при юзание опредленно какихто моментов
если муть несу, то не пинайте пожалуйста, я пытаюсь понять неизвестное мне

LordJZ
10.03.2010, 14:15
if(Aura * aur = GetAura(15007, EFFECT_INDEX_0))

GetGUID() тут ни к чему.

MaS0n
10.03.2010, 17:42
использование функций GetAura() и getLevel() напрямую можно только в Player.cpp, Unit.cpp. Это аналогично this->getLevel(), this->GetAura(). В остальных случаях требуется игрок(или юнит), с которого мы получаем левел или ауру
Т.е

plr->getLevel()
plr->GetAura(..)


PS : и как могут быть не определены эти ф-ци в .h файлах, если вы используете файлы исходников, а не свои добавленные

Wish
10.03.2010, 18:34
использование функций GetAura() и getLevel() напрямую можно только в Player.cpp, Unit.cpp. Это аналогично this->getLevel(), this->GetAura(). В остальных случаях требуется игрок(или юнит), с которого мы получаем левел или ауру
Т.е

plr->getLevel()
plr->GetAura(..)


PS : и как могут быть не определены эти ф-ци в .h файлах, если вы используете файлы исходников, а не свои добавленные
Спасибо на многие вопросы сразу получил вопрос
if(Aura * aur = GetAura(15007, EFFECT_INDEX_0))

GetGUID() тут ни к чему.
собственно EFFECT_INDEX_0 я вообще в коде не нашел существование ее

Вот реализовал что хотел, в игре вроде все отлично работает, ошибок в коде нет?
// if player is dead and stuck, send ghost to graveyard
chr->RepopAtGraveyard();
chr->ResurrectPlayer(0.0f, false);

int32 startLevel = sWorld.getConfig(CONFIG_DEATH_SICKNESS_LEVEL);

if(int32(chr->getLevel()) >= startLevel)
{
// set resurrection sickness
chr->CastSpell(chr,15007,false);

// not full duration
if(int32(chr->getLevel()) < startLevel+9)
{
int32 delta = (int32(chr->getLevel()) - startLevel + 1)*MINUTE;

if(Aura * aur = chr->GetAura(15007, chr->GetGUID()))
{
aur->SetDuration(delta*IN_MILISECONDS);
}
}
}
return true;
}

// cast spell Stuck
chr->RepopAtGraveyard();
return true;
и еще пару вопросов
1.unit64,unit32,unit8 и тд, что значит это? и какая разница между ими?
2.Можно ли гдето в коде посмотреть описание функций? к примеру
CastSpell(Обект на который будет задействовано,ИД спелла,Тригерность);

MaS0n
10.03.2010, 18:45
// if player is dead and stuck, send ghost to graveyard
chr->RepopAtGraveyard();
chr->ResurrectPlayer(0.0f, false);

int32 startLevel = sWorld.getConfig(CONFIG_DEATH_SICKNESS_LEVEL);

if(int32(chr->getLevel()) >= startLevel)
{
// set resurrection sickness
chr->CastSpell(chr,15007,false);

// not full duration
if(int32(chr->getLevel()) < startLevel+9)
{
int32 delta = (int32(chr->getLevel()) - startLevel + 1)*MINUTE;

if(Aura * aur = chr->GetAura(15007, chr->GetGUID()))
{
aur->SetDuration(delta*IN_MILISECONDS);
aur->SetAuraMaxDuration(delta * IN_MILISECONDS);
aur->RefreshAura();
}
}
}
return true;
}

// cast spell Stuck
chr->RepopAtGraveyard();
return true;


1. в GetAura второй параметр нужен индекс эффекта, сейчас не знаю как, а раньше всегда было 0, щас мб EFF_INDEX_0, т.к enum, вобщем смотреть по коду

2. ЧТоб установить свою длительность ауры, надо установить макс. длительность а потом ее зарефрешить

PS - каст маски 15007 лучше делать true, т.к true- означает триггерный спелл, кастуется инстантом, не требуя ни энергии(маны, ярости и т.д), ни реагентов, игонря любые эффекты LOS

chr->CastSpell(chr,15007,true);


PS2 - Visual Studio там есть такая вещь как "Go to Definition", "Go to Declaration" - в контекст меню правым целчком мыши на ф-ции в коде, первое к самой функции, второе - к ее обьявлению,
uint8, uint16, uint32, uint64 - unsigned int, беззнаковый целочисленный тип, цифра - битовость
беззнаковый - биты могут быть либо 0, либо положительными, за счет отрицательных значений мы вдвое расширяем диапазон, uint32 - 0 to 65536

Это обьясняет и любимый всеми баг с уходом спд в минус и появлятся 65536 при значении < 0

Wish
24.03.2010, 07:15
Подскажите еще 2 функции
1. На проверку у персонажа итема
пробовал так GetItemByEntry(entry);
либо нето либо не догнал как прописать
2. На удаление Итема у персонажа
также пробовал RemoveItem
но не догоняю почему при комплиляции ему ненравится она:resent:


По первому вопросу нашел ответ на форуме

I fart
24.03.2010, 07:51
Подскажите еще 2 функции
1. На проверку у персонажа итема
пробовал так GetItemByEntry(entry);
либо нето либо не догнал как прописать
Player->HasItemCount()
2. 2. На удаление Итема у персонажа
также пробовал RemoveItem
void Player::RemoveItem( uint8 bag, uint8 slot, bool update )
А она разве не для замены? А то есть если true - то замена, false - не замена??

Anti
24.03.2010, 13:01
void Player::RemoveItem( uint8 bag, uint8 slot, bool update )
А она разве не для замены? А то есть если true - то замена, false - не замена??
Нет, не для замены:
if( IsInWorld() && update )
pItem->SendCreateUpdateToPlayer( this );
Обновлять ли состояние игрока для самомго игрока или нет. Полагаю, если не обновлять, то итем будет видим для игрока, но будет отсутствовать для сервера.


собственно EFFECT_INDEX_0 я вообще в коде не нашел существование ее


Список индексов для спеллов лежит в DBCEnums.h
enum SpellEffectIndex
{
EFFECT_INDEX_0 = 0,
EFFECT_INDEX_1 = 1,
EFFECT_INDEX_2 = 2
};

1.unit64,unit32,unit8 и тд, что значит это? и какая разница между ими?

Описание каждого из типов можно посмотреть в ACE_Wrapper/ace/Basic_Types.h

2.Можно ли гдето в коде посмотреть описание функций? к примеру
CastSpell(Обект на который будет задействовано,ИД спелла,Тригерность);
Ну это можно сделать либо в докси, но те что я видел были староватыми, однако инфы там много.
Но самый эффективный вариант (имхо) - просмотр кода.
CastSpell - перегруженный метод, имеющий 4 разных перегрузки.
Используемая нами:
void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem = NULL, Aura* triggeredByAura = NULL, uint64 originalCaster = 0);

========================

А вообще для лучшего понимания кода, советую пройтись по иерархии классов сущностей. Начиная с Object и вниз. А если вы пользуетесь ВС, то советую сделать следующее:
правой кнопкой мыши по проекту game, в выпадающем меню выбираем "Перейти к схеме классов", ВС немного потупит, но в конце концов успешно создаст схему.

Hantet
24.03.2010, 13:31
Простите, а что такое тригерность?
Слово слышу очень давно, но до сих пор не разобрался с этим понятием. :(

С английского языка, естественно (если глагол), переводится как вызывать.
Поясните, пожалуйста, добрые человеки :(

Спасибо, Anti! Выручил :)

Anti
24.03.2010, 13:41
Простите, а что такое тригерность?
Слово слышу очень давно, но до сих пор не разобрался с этим понятием. :(

С английского языка, естественно (если глагол), переводится как вызывать.
Поясните, пожалуйста, добрые человеки :(

Спел вызывается другим спелом, ну и судя по всему обрабатывается каким-то специфическим способом.

MangMan
24.03.2010, 18:46
При осмотре кода Scriptdev увидел такую функцию void ScriptsFree(), void ScriptsFree()
{
// Free Spell Summary
delete []SpellSummary;

// Free resources before library unload
for(int i=0; i<MAX_SCRIPTS; ++i)
delete m_scripts[i];

num_sc_scripts = 0;
} Меня интересует вот эта строка delete []SpellSummary;Правильна ли она?

Anti
24.03.2010, 18:57
При осмотре кода Scriptdev увидел такую функцию void ScriptsFree(), void ScriptsFree()
{
// Free Spell Summary
delete []SpellSummary;

// Free resources before library unload
for(int i=0; i<MAX_SCRIPTS; ++i)
delete m_scripts[i];

num_sc_scripts = 0;
} Меня интересует вот эта строка delete []SpellSummary;Правильна ли она?

http://www.google.ru/search?hl=ru&source=hp&q=%D0%A1%2B%2B+%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%B D%D0%B8%D0%B5+%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8 %D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE+%D0%BC% D0%B0%D1%81%D1%81%D0%B8%D0%B2%D0%B0&lr=&aq=f&aqi=&aql=&oq=&gs_rfai=

Обычное удаление динамического массива.

MaS0n
24.03.2010, 19:15
Насколько я понимаю по коду, триггерные спеллы не требуют реагентов и энергии, кастятся без учета ЛОС, и видимо инстант

Wish
27.03.2010, 09:47
Подскажите как правильно удалить итем
не могу разобраться с RemoveItem

MangMan
27.03.2010, 10:09
RemoveItem(мешок, слот,Обновлять ли состояние игрока для самомго игрока или нет)

Wish
27.03.2010, 12:45
Возникает еще один вопрос
Как определить в каком мешке, слоту лежит итем?

MangMan
27.03.2010, 12:54
Я код мангоса плохо знаю, но можно так, через цикл, сделать проверку на определенный итим.

Anti
27.03.2010, 15:36
Возникает еще один вопрос
Как определить в каком мешке, слоту лежит итем?

Посмотрите Player::HasItemCount ну и пишите 2 функции.

Chestarfild
30.03.2010, 14:32
Есть ли на данный момент у ГО поддержка функции Update(), как у мобов?

Anti
30.03.2010, 16:51
Есть ли на данный момент у ГО поддержка функции Update(), как у мобов?По коду видно, что да.

void GameObject::Update(uint32 /*p_time*/)

Обрабатывает состояния объектов.

MangMan
03.04.2010, 06:54
Описания некоторых функций из фаила Item.cpp
void AddItemsSetItem(Player*player,Item *item) - Добавление набора предметов игроку. В объявление все понятно.
void RemoveItemsSetItem(Player*player,ItemPrototype const *proto) - Удаления набора предметов.
bool ItemCanGoIntoBag(ItemPrototype const *pProto, ItemPrototype const *pBagProto) - Проверка предмета в сумке игрока.(Возвращает лож)
bool Item::Create( uint32 guidlow, uint32 itemid, Player const* owner) - Создание предмета(????), возвращает истину
void Item::UpdateDuration(Player* owner, uint32 diff - ????
void Item::SaveToDB() - сохранить в базе данных
bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) - загрузить предмет из БД, (индификатор, владелец, результат запроса), возвращает истину
void Item::DeleteFromDB() - удалить предмет из Бд
void Item::DeleteFromInventoryDB() - удалить из списка Бд(????)
void Item::SetItemRandomProperties(int32 randomPropId) - установить предмету случайные свойства
bool Item::UpdateItemSuffixFactor() - (???)
void Item::SetState(ItemUpdateState state, Player *forplayer) - определение состояния, void Item::SetState(состояние, для какого игрока)
void Item::AddToUpdateQueueOf(Player *player) - Добавить из очереди(????), void Item::AddToUpdateQueueOf(игрок)
void Item::RemoveFromUpdateQueueOf(Player *player) Удалить из очереди(???), объявляется так же как предыдущая
bool Item::IsEquipped() const - (???)
bool Item::CanBeTraded(bool mail) - поверка, продается ли предмет, возвращает истину
bool Item::IsBoundByEnchant() - проверка, на инчант, возвращает лож
bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) - подходить ли для определенного заклинания, возвращает истину
bool Item::IsTargetValidForItemUse(Unit* pUnitTarget) - (???)
void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges) - установка инчанта, void Item::SetEnchantment(слот чар, id, продолжительность, расходы)
void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration) - установка временного инчанта.
void Item::SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges) - (???)
void Item::ClearEnchantment(EnchantmentSlot slot) - удаления инчанта
bool Item::GemsFitSockets() const - (???)
bool Item::IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const - ограничения использование предмета в другой зоне(????)
void Item::SendTimeUpdate(Player* owner) - (????)
bool Item::IsBindedNotWith( Player const* player ) const - (???)
void Item::AddToClientUpdateList() - добавить предмет в список обновления клиента
void Item::RemoveFromClientUpdateList() - удалить предмет из списка обновления клиента
void Item::BuildUpdateData(UpdateDataMapType& update_players) - ???
bool ItemRequiredTarget::IsFitToRequirements( Unit* pUnitTarget ) const - ???
bool Item::HasMaxCharges() const - ???
void Item::RestoreCharges() - ???

Chestarfild
03.04.2010, 10:44
Интересует, как правильно деспавнить ГО в инсте. Например Скорбь в залах, когда её Артас забирает.

Anti
04.04.2010, 11:12
Интересует, как правильно деспавнить ГО в инсте. Например Скорбь в залах, когда её Артас забирает.

Могу посоветовать посмотреть как это делает rsa в своём скрипте Колизея.
http://github.com/rsa/scriptdev2/blob/master/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp

Смотрите скрипт Артоса, он там ломает пол.

Chestarfild
18.04.2010, 10:17
По коду видно, что да.
Вот только как это привязать к скрипту? Смотрел в Script, там GetAI() только для креатур, а для го это сделать какнить можно?

Anti
18.04.2010, 11:00
Вот только как это привязать к скрипту? Смотрел в Script, там GetAI() только для креатур, а для го это сделать какнить можно?
А что реализовываем? Со скриптами ГО не сильно знакомился, но могу достаточно быстро разобраться.

Chestarfild
18.04.2010, 13:13
Нужно реализовать таймер в го, чтобы например он каждые 20 секунд выполнял на себя определенный метод. С тригерными нпц не особо охото мучацо, да и не близзлайк это наверное.

ЗЫ: Какими махинациями можно сделать неюзабельный го юзабельным?)

Anti
18.04.2010, 14:13
Нужно реализовать таймер в го, чтобы например он каждые 20 секунд выполнял на себя определенный метод. С тригерными нпц не особо охото мучацо, да и не близзлайк это наверное.

ЗЫ: Какими махинациями можно сделать неюзабельный го юзабельным?)

Похоже, что не получиться такое реализовать без переписывания большой части кода, да и ан сколько я знаю Го у нас сейчас не кастуют в принципе. Так что лучше "не лезть вперёд батьки", а делать через триггеры.

стамим ГО флаг = 4 - после удаляем (например скриптом).

Chestarfild
18.04.2010, 14:40
стамим ГО флаг = 4 - после удаляем (например скриптом).
Я немного не так сказал) Вобщем например, есть сундук в Очищении Стратхольма, он там стоит по дефлоту неюзабельный. Каким флагом/методом/функцией можно его через код сделать юзабельным?

Anti
18.04.2010, 17:50
Я тоже имел его ввиду :)

Вроде можно делать через базу, но я предпочитаю через С++ скрипт делать.
В скрипте инста будет примерно такая штука:
setData(uint32 case,uint32 data)
{
...
case MALGANIS:
if (data == DONE)
if (GameObject *pGo = instance->GetGameObject(MalganisChest))
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND) ;
...
}
А в го_темплейте для этого го ставим значение flags = 4.
Скриптуем моба тоже через С++. И как он умирает и отсылает данные в скрипт инста, тут то мы и делаем ГО юзабильным.

KiriX
28.04.2010, 17:07
Пара спеллов:
http://ru.wowhead.com/spell=38736
http://ru.wowhead.com/spell=57853

Проблема в следующем - при юзе итема, на котором они висят, они кастуются, но триггера спелла, висящего на них, не происходит. Не могу понять куда копать... Есть идеи?

KiriX
28.04.2010, 17:07
Пара спеллов:
http://ru.wowhead.com/spell=38736
http://ru.wowhead.com/spell=57853

Проблема в следующем - при юзе итема, на котором они висят, они кастуются, но триггера спелла, висящего на них, не происходит. Не могу понять куда копать... Есть идеи?

Ясно... Спелл имеет TARGET_SCRIPT. Значит эффект вешается на цель, указанную в базе и уже эта цель триггерит спелл. А нам надо триггерить спелл от кастера...

MaS0n
29.04.2010, 09:31
SpellAuras.cpp
Есть такая функция, которая вызывается при каждом тике триггерных аур

void Aura::TriggerSpell()


Ищем место где в коде будет

else
{
// Spell exist but require custom code
switch(auraId)
{


И здесь на нужное место вставляем тот же самый каст спелла, но уже на кастера, что-то вроде

case 38736:
{
if (Unit * caster = GetCaster())
caster->CastSpell(caster, trigger_spell_id, true, NULL, this, casterGUID);
return;
}

KiriX
29.04.2010, 12:03
Спасибо, как раз не мог найти этот обработчик =)
Но судя по данным ДБЦ спелла, создаётся впечатление, что надо в таблицу spell_script_target есть смысл добавить новый тип цели - self... Или же подобные спеллы просто добавлять в исключение в код - примут ли?

MaS0n
29.04.2010, 12:32
Это ответвление и было специально создано для таких случаев, перевод коммента
'триггер спелла есть, но требуется другой код'

В триггерном эффекте стоит квест-комплит с таргет-селф, я думаю, что этот эффект точно должен применятся на кастера-игрока

И если просмотреть все эти исключения, некоторые один в один повторяют основную обработку каста в самом конце :) как бы они уже не нужны, но стоят

KiriX
29.04.2010, 13:40
Это ответвление и было специально создано для таких случаев, перевод коммента
'триггер спелла есть, но требуется другой код'

В триггерном эффекте стоит квест-комплит с таргет-селф, я думаю, что этот эффект точно должен применятся на кастера-игрока

*И если просмотреть все эти исключения, некоторые один в один повторяют основную обработку каста в самом конце :) как бы они уже не нужны, но стоят
Я сообщение твоё получил на работе - коммент не читал вообще. Спасибо за комментарий.
Вот только последнего (под звёздочкой) я не очень понял смысл... Таких спеллов несколько минимум, которые используют TARGET_SCRIPT, но по логике триггерного спелла должны кастоваться от кастера. Есть ли смысл добавлять тип цели спелла - кастер?

zergtmn
03.05.2010, 09:39
Пытаюсь сделать, чтобы моб в момент смерти кастовал АоЕ спелл, например http://ru.wowhead.com/spell=62598 (с помощью EAI или SD2, не важно). Анимация есть, но спелл промахивается в 100% случаев (кастуется как triggered). В чем дело? (:
Ревизия 9808.

LordJZ
03.05.2010, 20:25
Пытаюсь сделать, чтобы моб в момент смерти кастовал АоЕ спелл, например http://ru.wowhead.com/spell=62598 (с помощью EAI или SD2, не важно). Анимация есть, но спелл промахивается в 100% случаев (кастуется как triggered). В чем дело? (:
Ревизия 9808.А как вы делаете? Через JustDied?

zergtmn
03.05.2010, 23:57
А как вы делаете? Через JustDied?
Да, в EventAI это EVENT_T_DEATH (6). Можете сами убедиться:
UPDATE creature_template SET AIName = 'EventAI', ScriptName = '' WHERE entry IN (32918);
DELETE FROM creature_ai_scripts WHERE creature_id IN (32918);
INSERT INTO creature_ai_scripts VALUES
('3291801','32918','0','0','100','7','5000','10000 ','10000','12000','11','62608','1','0','0','0','0' ,'0','0','0','0','0','Detonating Lasher - Cast Flame Lash'),
('3291802','32918','6','0','100','2','0', '0', '0', '0', '11','62598','0','3','0','0','0','0','0','0','0',' 0','Detonating Lasher (Normal) - Cast Detonate on Death'),
('3291803','32918','6','0','100','4','0', '0', '0', '0', '11','62937','0','3','0','0','0','0','0','0','0',' 0','Detonating Lasher (Heroic) - Cast Detonate on Death');

LordJZ
04.05.2010, 07:53
Ох уж это EventAI... :)
Попробуйте поставить мобу 1 хп INVINCIBILITY_LEVEL (кажется так), и на 1 хп кастануть этот спелл и умереть.

zergtmn
04.05.2010, 23:02
Сделал новый тип события EVENT_T_JUST_BEFORE_DEATH, который обрабатывается в DamageTaken при получении последнего удара.

MangMan
12.05.2010, 09:30
Подскажите где проверяется разница рейтов арены. Дапустим у одной тимы 300 а у другой 800.Они не могут участвовать в месте, потому что разница большая.

srv38
12.05.2010, 10:33
В конфиге есть такой параметр, по дефолту вроде 150, думаю с него и надо начинать поиск.

pavelzubkov
18.08.2010, 15:53
Помогите разобраться в коде. Mangos 0.12 кум 6928
Я тут посмотрел написал комментарии по правьте если ошибся. Я может и понимаю код, но что, для чего и зачем мне не понятно. Опишите пожалуйста функции которые в примере. Как я понимаю эта процедура почти стартовая при исполнение кода спеллов(еще старше та которая ее вызывает=))

void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
CHECK_PACKET_SIZE(recvPacket,4+1+2);

uint32 spellId;//Объявление двух переменных. Со SpellId понятно
uint8 cast_count;//Что храниться здесь??? И для ВНЕЗАПНОГО УДАРА и для ЛЕДЯННОЙ СТРЕЛЫ - 0.
recvPacket >> spellId;
recvPacket >> cast_count;

sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u data length = %i",
spellId, cast_count, recvPacket.size()); //Логи

SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
/*
В SpellEntry содержется описание ячеек из spell.dbc
клик по sSpellStore >>>> GO TO DEFINITION приводит к DBCStorage <SpellEntry> sSpellStore(SpellEntryfmt); судя по всему, описание какого-то DBC????
клик по LookupEntry >>>> GO TO DEFINITION приводит к T const* LookupEntry(uint32 id) const { return (id>=nCount)?NULL:indexTable[id]; }
не могу понять конструкцию, вроде тут условие и возвращение какого-то id???
судя по *SpellInfo...ммм, название говорит само за себя.
*/

if(!spellInfo)//проверка на успешное создание spellInfo
{
sLog.outError("WORLD: unknown spell id %u", spellId);
return;
}

// not have spell or spell passive and not casted by client(с английским проблемы) что-то вроде: не имеется спелл или спел пассивный и нет каста от клиента. вроде так.
if ( !_player->HasSpell (spellId) || IsPassiveSpell(spellId) )//Проверка на читерство???
{
//cheater? kick? ban?
return;
}

// client provided targets
SpellCastTargets targets;//Создание таргета
if(!targets.read(&recvPacket,_player))//Проверка на существование таргета?
return;

// auto-selection buff level base at target level (in spellInfo) Это мне не дано перевсти: авто-выбор полезного эфекта базового уровня....бррр......
if(targets.getUnitTarget())
{
SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(spellInfo,ta rgets.getUnitTarget()->getLevel());
/*
GO TO DEFINITION(SelectAuraRankForPlayerLevel) - SpellEntry const* SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const;// --- это прототип функции??
//А где тело функции описывается...хм...spellmrg.cpp
//go to definition привело меня в spellmrg.h, понятно.
SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const //посмотрим чё тут=)
{
// ignore passive spells игнорирование пассивных спеллов
if(IsPassiveSpell(spellInfo->Id))
return spellInfo; //Возвращаем изначальное спеллинфо

bool needRankSelection = false;//объявляем буль
for(int i=0;i<3;i++)//такс цикл
{
if( IsPositiveEffect(spellInfo->Id, i) && ( spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ) )
{//Если в spell.dbc хоть одна из ячеек effect равна SPELL_EFFECT_APPLY_AURA ||(или) SPELL_EFFECT_APPLY_AREA_AURA_PARTY
//а вот IsPositiveEffect(spellInfo->Id, i) как Я ПОНЯЛ там внутри идет проверка из множества свитч
кэйсов и другой бурды
//на полезный или вредный эффект спелла(всмысле эффект у спела положительный(хилит, бафает)
или отрицательный(урон...))
needRankSelection = true; //еслив хоть раз условие верно буль будет истин
break;//и выходим из цикла
}
}

// not required
if(!needRankSelection)//т.к буль НЕ истин
return spellInfo;//Возвращаем изначальное спеллинфо

for(uint32 nextSpellId = spellInfo->Id; nextSpellId != 0; nextSpellId = GetPrevSpellInChain(nextSpellId))
{
SpellEntry const *nextSpellInfo = sSpellStore.LookupEntry(nextSpellId);//опять шесть сот двадцать пять
if(!nextSpellInfo)//а есть ли оно?
break;//нет

// if found appropriate level
if(playerLevel + 10 >= nextSpellInfo->spellLevel)//больши или равен левел игрока уровня спелла??
return nextSpellInfo; //возвращаем nextSpellInfo

// one rank less then
}

// not found
return NULL;//ничего
}//Вообщем, я не понял что эта функция делает=)моски надо купить
*/

// if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
if(actualSpellInfo)//если не нулл
spellInfo = actualSpellInfo;
}

Spell *spell = new Spell(_player, spellInfo, false);//конструктор,хм _player, spellInfo, false. false - это тригерность???
spell->m_cast_count = cast_count; // set count of casts пожалуйста скажите для чего cast_count
spell->prepare(&targets);//Это следующее что я должен смотреть если хочу идти по следам спелла???
}//фуу вот и все

MaS0n
18.08.2010, 16:40
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
CHECK_PACKET_SIZE(recvPacket,4+1+2);

uint32 spellId; // ID спелла
uint8 cast_count; // количество кастов, увеличивается с каждым новым кастом для конкретного спелла
recvPacket >> spellId;
recvPacket >> cast_count;

sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u data length = %i",
spellId, cast_count, recvPacket.size()); //Логи

SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
/* Обьект SpellEntry - получение информации по спеллу из DBC */
/* т.е мы можем обращатся к полям структуры, типа spellInfo->ID, spellInfo->SpellIconID, см. DBCStructure.h, struct SpellEntry */

if(!spellInfo)//проверка на успешное создание spellInfo
{
sLog.outError("WORLD: unknown spell id %u", spellId);
return;
}

// not have spell or spell passive and not casted by client (нет данного спелла у игрока или спелл пассивный - а значит НИКАК не может быть скастован клиентом => читер
if ( !_player->HasSpell (spellId) || IsPassiveSpell(spellId) )//Проверка на читерство???
{
//cheater? kick? ban?
return;
}

// client provided targets
SpellCastTargets targets; //Создание таргета
if(!targets.read(&recvPacket,_player)) // Чтение целей из пакета и занесение их в таргет обработку
return;

// auto-selection buff level base at target level (in spellInfo) (выбор уровня спелла согласно левелу чара)
if(targets.getUnitTarget())
{
SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(spellInfo,ta rgets.getUnitTarget()->getLevel());
/*
GO TO DEFINITION(SelectAuraRankForPlayerLevel) - SpellEntry const* SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const; --- это прототип функции?? А где тело функции описывается...хм...spellmrg.cpp go to definition привело меня в spellmrg.h, понятно.
SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const //посмотрим чё тут=)
{
// ignore passive spells игнорирование пассивных спеллов
if(IsPassiveSpell(spellInfo->Id))
return spellInfo; //Возвращаем изначальное спеллинфо

bool needRankSelection = false;//объявляем буль
for(int i=0;i<3;i++)//такс цикл
{
if( IsPositiveEffect(spellInfo->Id, i) && ( spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ) )
{//Если в spell.dbc хоть одна из ячеек effect равна SPELL_EFFECT_APPLY_AURA ||(или) SPELL_EFFECT_APPLY_AREA_AURA_PARTY
//а вот IsPositiveEffect(spellInfo->Id, i) как Я ПОНЯЛ там внутри идет проверка из множества свитч кэйсов и другой бурды
//на полезный или вредный эффект спелла(всмысле эффект у спела положительный(хилит, бафает) или отрицательный(урон...))
needRankSelection = true; //еслив хоть раз условие верно буль будет истин
break;//и выходим из цикла
}
}

// not required
if(!needRankSelection)//т.к буль НЕ истин
return spellInfo;//Возвращаем изначальное спеллинфо

for(uint32 nextSpellId = spellInfo->Id; nextSpellId != 0; nextSpellId = GetPrevSpellInChain(nextSpellId))
{
SpellEntry const *nextSpellInfo = sSpellStore.LookupEntry(nextSpellId);//опять шесть сот двадцать пять
if(!nextSpellInfo)//а есть ли оно?
break;//нет

// if found appropriate level
if(playerLevel + 10 >= nextSpellInfo->spellLevel)//больши или равен левел игрока уровня спелла??
return nextSpellInfo; //возвращаем nextSpellInfo

// one rank less then
}

// not found
return NULL;//ничего
}//Вообщем я ни понял что эта функция делает=)моски надо купить
*/

// if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
if(actualSpellInfo)//если не нулл
spellInfo = actualSpellInfo;
}

Spell *spell = new Spell(_player, spellInfo, false);
// конструктор - создаем обьект Spell
// Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered)
spell->m_cast_count = cast_count; // устаналиваем количество кастов в глобальную переменнную для дальнейших расчетов
spell->prepare(&targets);// Переход в фазу подготовки спелла
}//фуу вот и все


Это же не с лича пакет, я так понимаю, структура не совпадает, это классик или тбц
Я изменил комменты кое-где, почитай - возникнут вопросы - пиши

pavelzubkov
18.08.2010, 18:14
так значит функция sSpellStore.LookupEntry(spellId) возвращает данные о спелле из dbc.
uint8 cast_count; // количество кастов, увеличивается с каждым новым кастом для конкретного спелла

А для чего это используеться? Что бы подсчитать стаки как-либо эффектов? Диминишинг?

// auto-selection buff level base at target level (in spellInfo) (выбор уровня спелла согласно левелу чара)

Всмысле? Т.е. в функции SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const - определяеться какй уровень спелла использовал player?В actualSpellInfo данные о спелле соответственного уровня.

LordJZ
18.08.2010, 19:23
cast_count, вроде бы, в мангосе не используется, но я могу ошибаться.

MaS0n
18.08.2010, 20:02
Используется.
Для чего - не знаю, мб для вычислений, например предотвращения зацикливания триггера в deadloop, обработки мульти-кастов и т.д

Насчет уровня спелла - да

pavelzubkov
19.08.2010, 10:20
Я правильно понял? Критика моим комментариям приветствуется=)


void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)/*Подготовка спелла*/
{
m_targets = *targets;/*Аргумент *targets нужен только для этого присваивания(еще не придумал как выразиться(*/


m_spellState = SPELL_STATE_PREPARING;/*Статистика спелла - подготовка*/

m_castPositionX = m_caster->GetPositionX();
m_castPositionY = m_caster->GetPositionY();
m_castPositionZ = m_caster->GetPositionZ();
m_castOrientation = m_caster->GetOrientation();
/*Получение координат и ориентации кастера*/
if(triggeredByAura)/**/
m_triggeredByAuraSpell = triggeredByAura->GetSpellProto();

// create and add update event for this spell Создание события для спелла?
SpellEvent* Event = new SpellEvent(this);//Создаем ЭВЕНТ для нашего спелла
m_caster->m_Events.AddEvent(Event, m_caster->m_Events.CalculateTime(1));/*Что за тайм считается? Время создания ЭВЕНТА? И для чего он создаеться?*/
/*Если не ошибаюсь ЭВЕНТ - событие. Создается событие для спелла?*/
//Prevent casting at cast another spell (ServerSide check) ??? /*Английский под учим, потом.*/
if(m_caster->IsNonMeleeSpellCasted(false, true) && m_cast_count)/*Милишный спелл и m_cast_count*/
{
/*Я прав что тут условие вида: if (m_caster->IsNonMeleeSpellCasted(false, true) == true && m_cast_count == true) {...}
но ведь m_cast_count не bool. Или он false если равен нулю и true если не равен нулю, ведь так?*/
SendCastResult(SPELL_FAILED_SPELL_IN_PROGRESS);//Отправка клиенту сведений о неудачном касте.
finish(false);/*Finish(bool) - это процедура говорящая о конце подготовки еслив на false то подготовка окончилась не удачей?*/
return;
}

// Fill cost data /*Данные о затратах на спелл(мана, энергия, ярость)*/
m_powerCost = CalculatePowerCost();/*CalculatePowerCost() подсчитывает затраты*/

uint8 result = CanCast(true);/*В CanCast проверяется возможность каста??*/
if(result != 0 && !IsAutoRepeat()) /*Всегда повторяем каст...*/ //always cast autorepeat dummy for triggering
{
if(triggeredByAura)/*Опять проверка на аргумент, который мы не передавали из WorldSession::HandleCastSpellOpcode*/
{/*И если он есть что-то делаем...*/
SendChannelUpdate(0);
triggeredByAura->SetAuraDuration(0);
}
SendCastResult(result);/*Посылка клиенту сведений о неудачи?????*/
finish(false);
return;
}

// calculate cast time (calculated after first CanCast check to prevent charge counting for first CanCast fail)
m_casttime = GetSpellCastTime(m_spellInfo, this);/*Достаем время каста спелла*/

// set timer base at cast time
ReSetTimer();/*Какой-то таймер ресаем*/
/*void ReSetTimer() { m_timer = m_casttime > 0 ? m_casttime : 0; } эта констция значит*/
// :
//void ReSetTimer()
//{
// if (m_casttime > 0)
// {
// m_timer = m_casttime;
// }
// else {m_timer = 0;}
//}

// stealth must be removed at cast starting (at show channel bar) Незаметность должна быть отменена при старте спелла?
// skip triggered spell (item equip spell casting and other not explicit character casts/item uses) Пропуск триггерного спелла?
if ( !m_IsTriggeredSpell && isSpellBreakStealth(m_spellInfo) )/*функция isSpellBreakStealth(m_spellInfo) определяет выводит ли спелл из режима незаметности??*/
{
m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);/*Выход из стелса*/
m_caster->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);/*Воскрешение????*/
}

if(m_IsTriggeredSpell)/*Тригерный ли спелл, если да каст(тру)*/
cast(true);/*Кастуется то что вызывает тригер??*/
else
{/*нет*/
m_caster->SetCurrentCastedSpell( this );/*Установление значений каста спелла. Там определяется крита, мисс, доджи, блок, пар...?*/
m_selfContainer = &(m_caster->m_currentSpells[GetCurrentContainer()]);/*?*/
SendSpellStart();/*Передача данных о старте спелла??*/
}
}

Vladimir
19.08.2010, 14:08
Используется.
Для чего - не знаю, мб для вычислений, например предотвращения зацикливания триггера в deadloop, обработки мульти-кастов и т.д

Насчет уровня спелла - да

Насколько помню в 2.x клиенте появилась возможность старта каста до подтверждения сервера об окончании предыдущего.
Т.е. игрок жмет каст - клиент видит что сервер не сообщил об окончании предыдущего каста, но посылает пакет каста серверу с +1 номером в упомянутом поле.
Сервер уже сам разбирается можно разрешить каст или нет.
Помогает при лагах когда клиент раньше не давал кастовать из-за лагов хотя по времени формально каст должен был уже закончится предыдущий.

pavelzubkov
19.08.2010, 18:54
Небольшой вопрос(на примере) по функциям в с++:
есть функция void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) из которой вызываеться другая функция void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura) и вот при вызове второй функции указываеться только один аргумент SpellCastTargets * targets, а второй нет. Как я понимаю на примере в предыдущих сообщениях функция вызовется, НО triggeredByAura(второй аргумент последней функции) будет не инициализирован. Я поторопился...нашел в spell.h прототип этой функции
void prepare(SpellCastTargets * targets, Aura* triggeredByAura = NULL); zergtmn стараюсь читать=)

zergtmn
19.08.2010, 19:08
Советую вам почитать книжки по С++.

Wish
18.01.2011, 18:48
Снова нужна помощь
решил переделать определение уровня гма, мне удобней чтобы все аккаунты на которые я захожу со своего айпи бали гмские
в accountmgr.cpp я прописываю
std::string IP_str = GetRemoteAddress();
и меняю запрос на нужный мне
при компиляции пишет неизвестный индификатор
пробовал так
player()->Getsesion()->GetRemoteAddress();
тоже неможет найти индефикатор

Подскажите что поправить:sorry:

Feel the Power
18.01.2011, 19:28
Снова нужна помощь
решил переделать определение уровня гма, мне удобней чтобы все аккаунты на которые я захожу со своего айпи бали гмские
в accountmgr.cpp я прописываю
std::string IP_str = GetRemoteAddress();
и меняю запрос на нужный мне
при компиляции пишет неизвестный индификатор
пробовал так
player()->Getsesion()->GetRemoteAddress();
тоже неможет найти индефикатор

Подскажите что поправить:sorry:

А библиотека std подключена в accountmgr.cpp?

rsa
18.01.2011, 20:42
тоже неможет найти индефикатор

я ваще тупой, тоже немогу найти ИНДЕФИКАТОР... и мне даже представить слабО что это такое...

Wish
19.01.2011, 17:19
А библиотека std подключена в accountmgr.cpp?

std подключена
WorldSocket.h подключаю, также выдает ошибку что найти не может

Sid
19.01.2011, 18:34
Имхо AccMgr это менеджер для работы с базой акков и не более. Тебе нужно копать WorldSession или AuthSocket.

HuntsMan
20.03.2011, 09:20
Каким образом экстрактор определяет что определенная карта должна иметь флаг DARKWATER? Старая тема от andstan'a на old.ru-mangos.ru не полностью :(

HuntsMan
14.05.2011, 15:05
Подскажите пожалуйста, какой SpellCastResult посылается клиенту, если спелл кастуется в движении, но в движении этот спелл кастовать нельзя?

Den
14.05.2011, 16:59
SPELL_FAILED_MOVING = 51, // Невозможно делать это на ходу.

acteros
24.07.2011, 03:50
как можно задать шанс крита спелу?
Например если весит аура ток спел с вероятностью в x% должен нанести крит урон

Den
24.07.2011, 07:18
bool Unit::IsSpellCrit(...)