|
Новичкам Информация для всех новичков, новичкам рекомендуется задавать свои вопросы здесь |
|
Опции темы | Поиск в этой теме | Опции просмотра |
20.05.2010, 13:04 | #1 |
Ученый
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
|
Функция для подсчета количества рангов спелла
Нужна помощь для создания функции которая выдаст общее количество рангов спелла (заклинания)
Набросок (в spellmgr.h) Код:
uint8 SpellRanksCount(uint32 spell_id) const { uint8 count = 0; SpellChainMap::const_iterator i = mSpellChains.find(spell_id); for (uint32 i = mSpellChains.begin(); mSpellChains.end() < i; i++) count+=i; return count; } Должно работать так: Допустим есть талант Improved Water Shield, у него 3 ранга Ид 1 ранга - 16180, Ид 2 ранга 16196, Ид 3 ранга 16198 Мы даем функции любой из них, она же ищет к какому Chain относится этот спелл и обращается к нему, у нас это делает Код:
SpellChainMap::const_iterator itr = mSpellChains.find(spell_id); в теле цикла нужно наращивать счетчик (у нас он count), функция должна возвращать счетчик (3 ранга таланта - вернет цифру 3)... К сожалению, оно не компилируется, т.к. я уверен, что я криво набросал :/ вот такая ошибка Код:
2>c:\mang\src\game\SpellMgr.h(914) : error C2440: 'initializing' : cannot convert from 'std::list<_Ty,_Ax>::_Const_iterator<_Secure_validation>' to 'uint32' 2> with 2> [ 2> _Ty=std::pair<const uint32,SpellChainNode>, 2> _Ax=std::allocator<std::pair<const uint32,SpellChainNode>>, 2> _Secure_validation=false 2> ] 2> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called Последний раз редактировалось Insider42; 20.05.2010 в 13:30. |
20.05.2010, 13:28 | #2 |
Пользователь
Регистрация: 12.03.2010
Сообщений: 85
Сказал(а) спасибо: 5
Поблагодарили 42 раз(а) в 17 сообщениях
|
Код:
uint8 GetSpellMaxRank(uint32 spell) const { uint32 HighSpell = spell; SpellChainMapNext::const_iterator itr = mSpellChainsNext.find(HighSpell); while (!itr->second) { HighSpell = itr->second; itr = mSpellChainsNext.find(HighSpell); } return GetSpellRank(HighSpell); } Последний раз редактировалось zhenya; 20.05.2010 в 13:35. |
20.05.2010, 13:31 | #3 |
Пользователь
Регистрация: 08.03.2010
Сообщений: 47
Сказал(а) спасибо: 45
Поблагодарили 29 раз(а) в 13 сообщениях
|
Ну если добавлять функцию в SpellMgr.h, то скрестим две GetSpellRank и doForHighRanks:
PHP код:
Последний раз редактировалось xex; 20.05.2010 в 13:36. |
20.05.2010, 13:35 | #4 | |
Ученый
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
|
Цитата:
Для проверки на деле использую Код:
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 0b548ee..ed9fc64 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -7035,6 +7035,15 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu // Lesser Healing Wave need aditional 60% roll if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) && !roll_chance_i(60)) return false; + // Chain Heal needs additional 10/20/30 % roll + if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000100))) + { + int32 maxChance = 30; + int32 curRank = sSpellMgr.GetSpellRank(dummySpell->Id); + int32 rankCount = sSpellMgr.SpellRanksCount(dummySpell->Id); + if (!roll_chance_i(maxChance/rankCount*curRank)) + return false; + } // lookup water shield AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) Код:
int32 curRank = sSpellMgr.GetSpellRank(dummySpell->Id); int32 rankCount = sSpellMgr.SpellRanksCount(dummySpell->Id); if (!roll_chance_i(maxChance/rankCount*curRank)) нужна ещё функция которая выполнит maxChance/rankCount*curRank внутри себя получив ИД спелла и maxchance - выдаст число результат, вычисления явно получаются типа float, нужно привести их к int или uint, скорее всего она должна быть не в spellmgr, дабы не обращаться к нему каждый раз. Например такого вида Код:
uint8 CalcRankChance(uint32 spellId, uint8 maxchance) const { uint8 curRank = sSpellMgr.GetSpellRank(dummySpell->Id); uint8 rankCount = sSpellMgr.SpellRanksCount(dummySpell->Id); return maxChance/rankCount*curRank; } Вот даже как её использовать пример Код:
// Chain Heal needs additional 10/20/30% roll if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000100))) { if (!roll_chance_i(CalcRankChance(dummySpell->Id,30))) return false; } Последний раз редактировалось Insider42; 20.05.2010 в 14:00. |
|
20.05.2010, 13:59 | #5 |
Супер-модератор
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
|
А чем SpellMgr не понравился? Ну вызывается и вызывается, какая разница. (хотя я бы вообще перенес весь SpellMgr в SpellEntry)
|
20.05.2010, 14:04 | #6 | |
Ученый
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
|
Цитата:
Код:
if (!roll_chance_i(sSpellMgr.CalcRankChance(dummySpell->Id,30))) Для себя конечно я могу использовать Код:
uint8 SpellRanksCount(uint32 spellId) const { uint8 count = 0; if (SpellChainNode const* node = GetSpellChainNode(spellId)) { count = node->rank; SpellChainMapNext const& nextMap = GetSpellChainNext(); for (SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellId); itr != nextMap.upper_bound(spellId); ++itr) count++; } return count; } uint8 CalcRankChance(uint32 spellId, uint8 maxChance) const { uint8 curRank = GetSpellRank(spellId); uint8 rankCount = SpellRanksCount(spellId); uint8 result = uint8(maxChance/rankCount*curRank); return result; } Но мне же нужно принятие в git Последний раз редактировалось Insider42; 20.05.2010 в 14:56. |
|
20.05.2010, 14:06 | #7 |
Супер-модератор
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
|
Дак я думаю функцию CalcRankChance вообще никогда не примут...
|
20.05.2010, 14:10 | #8 |
Ученый
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
|
А что, тогда громоздить 10этажные switch - case для каждого ранга и чтобы проверить только случай с одним спелом, затем рядом ещё один? И это только для Improved Water Shield, а таких много. Я уже эту фичу раскусил, у близов всё гораздо проще сделано... этого я и хочу сделать у нас
Вот разберем опять же на примере того же Улучшенного щита воды на 1 ранге 20% шанс прокнуть с крита малого исцеления на 2 ранге 40% шанс прокнуть с крита малого исцеления на 3 ранге 60% шанс прокнуть с крита малого исцеления. Тоже самое идёт для Цепного исцеления, но с другими шансами 1 ранг 10% шанс 2 ранг 20% шанс 3 ранг 30% шанс. явно видно что можно всё взять простым расчетом с помощью этой функции т.к. прирост на одинаковое количество Вот так я у себя поправил этот талант Код:
// Improved Water Shield if (dummySpell->SpellIconID == 2287) { // Lesser Healing Wave need aditional 60% roll if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) && !roll_chance_i(sSpellMgr.CalcRankChance(dummySpell->Id,60))) return false; // Chain Heal needs additional 30% roll if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000100)) && !roll_chance_i(sSpellMgr.CalcRankChance(dummySpell->Id,30))) return false; Последний раз редактировалось Insider42; 20.05.2010 в 14:36. |
20.05.2010, 14:58 | #9 |
Ученый
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
|
ммм, оно крашится при проке :/
Код:
Call stack: Address Frame Function SourceFile 00499D55 00000000 SpellMgr::CalcRankChance+45 004983A5 00000000 Unit::HandleDummyAuraProc+4C95 004ABC22 00000000 Unit::ProcDamageAndSpellFor+9F2 004929CF 00000000 Unit::ProcDamageAndSpell+2F 007455AE 00000000 Spell::DoAllEffectOnTarget+41E 0074D2E6 00000000 Spell::handle_immediate+E6 0074D0C8 00000000 Spell::cast+BE8 0074DB8C 00000000 Spell::update+2EC Последний раз редактировалось Insider42; 20.05.2010 в 15:01. |
20.05.2010, 15:05 | #10 |
Супер-модератор
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
|
Прогоните в дебаггере, виндовзовские крашдампы малопонятны, по крайней мере не для asm кодера.
|
20.05.2010, 15:12 | #11 |
Ученый
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
|
|
20.05.2010, 15:16 | #12 |
Пользователь
Регистрация: 08.03.2010
Сообщений: 47
Сказал(а) спасибо: 45
Поблагодарили 29 раз(а) в 13 сообщениях
|
roll_chance_i инлайн функция и ждёт int, может так?
PHP код:
Последний раз редактировалось xex; 20.05.2010 в 15:29. |
20.05.2010, 15:23 | #13 | |
Ученый
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
|
Цитата:
|
|
20.05.2010, 15:23 | #14 |
MaNGOS Dev
Регистрация: 07.03.2010
Сообщений: 314
Сказал(а) спасибо: 30
Поблагодарили 153 раз(а) в 83 сообщениях
|
Деление на 0?
|
20.05.2010, 15:32 | #15 |
Ученый
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
|
так оно и есть, но тут хлеще. Деление 0 на 0 xD
Выявил когда провел небольшой дебаг Код:
int CalcRankChance(uint32 spellId, int maxChance) const { sLog.outError("SpellId %i", spellId); int curRank = GetSpellRank(spellId); sLog.outError("Value1 %i", curRank); int rankCount = SpellRanksCount(spellId); sLog.outError("Value2 %i", rankCount); int result = int(maxChance/rankCount*curRank); sLog.outError("Value3 %i", result); return result; } Код:
2010-05-20 20:38:25 ERROR:SpellId 16198 2010-05-20 20:38:25 ERROR:Value1 0 2010-05-20 20:38:25 ERROR:Value2 0 Последний раз редактировалось Insider42; 20.05.2010 в 15:39. |
20.05.2010, 16:27 | #16 |
Ученый
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
|
Что-то я не подумал что можно же было сделать проще :/
Код:
// Improved Water Shield if (dummySpell->SpellIconID == 2287) { uint8 rank = sSpellMgr.GetSpellRank(dummySpell->Id); // Lesser Healing Wave need aditional 20/40/60% roll if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) && !roll_chance_i(20*rank)) return false; // Chain Heal needs additional 10/20/30% roll if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000100)) && !roll_chance_i(10*rank)) return false; Последний раз редактировалось Insider42; 20.05.2010 в 16:40. |
20.05.2010, 16:45 | #17 | |
Модератор
|
Попробуй
Возможно для талантов так: Код:
bool talentCost = GetTalentSpellCost(dummySpell->Id); uint8 rank = talentCost ? talentCost : sSpellMgr.GetSpellRank(dummySpell->Id); Цитата:
|
|
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
[9788][patch] Игнорирование количества игроков на БГ при включённом дебаге. | Anti | Принятые патчи | 1 | 24.04.2010 09:27 |
Каст спелла объектом на нпц | virusav | Новичкам | 9 | 13.03.2010 14:19 |
Сообщения при касте спелла 2764 | virusav | Баг-репорты | 0 | 07.03.2010 21:46 |