Ru-MaNGOS

Вернуться   Ru-MaNGOS > Документация > Новичкам

Важная информация

Новичкам Информация для всех новичков, новичкам рекомендуется задавать свои вопросы здесь

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 20.05.2010, 13:04   #1
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию Функция для подсчета количества рангов спелла

Нужна помощь для создания функции которая выдаст общее количество рангов спелла (заклинания)

Набросок (в 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);
далее нам нужно загнать это в цикл от первого ранга до последнего (получается цикл от 1 до 3х, т.к. 3 ранга в нашем случае),
в теле цикла нужно наращивать счетчик (у нас он 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.
Insider42 вне форума   Ответить с цитированием
Старый 20.05.2010, 13:28   #2
zhenya
Пользователь
 
Регистрация: 12.03.2010
Сообщений: 85
Сказал(а) спасибо: 5
Поблагодарили 42 раз(а) в 17 сообщениях
zhenya Скоро придёт к известности
По умолчанию

Код:
        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.
zhenya вне форума   Ответить с цитированием
Старый 20.05.2010, 13:31   #3
xex
Пользователь
 
Регистрация: 08.03.2010
Сообщений: 47
Сказал(а) спасибо: 45
Поблагодарили 29 раз(а) в 13 сообщениях
xex На верном пути
По умолчанию

Ну если добавлять функцию в SpellMgr.h, то скрестим две GetSpellRank и doForHighRanks:

PHP код:
        uint8 GetSpellRankCount(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;
        } 
Так точно работать будет.

Последний раз редактировалось xex; 20.05.2010 в 13:36.
xex вне форума   Ответить с цитированием
Старый 20.05.2010, 13:35   #4
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от xex Посмотреть сообщение
Ну если добавлять функцию в SpellMgr.h, то скрестим две GetSpellRank и doForHighRanks:

PHP код:
        void GetSpellRankCount(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;
        } 
Так точно работать будет.
Только наверно не void, а uint8. Спасибо, вроде компилируется, сейчас проверю на деле.

Для проверки на деле использую
Код:
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.
Insider42 вне форума   Ответить с цитированием
Старый 20.05.2010, 13:59   #5
LordJZ
Супер-модератор
 
Аватар для LordJZ
 
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
LordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранита
По умолчанию

А чем SpellMgr не понравился? Ну вызывается и вызывается, какая разница. (хотя я бы вообще перенес весь SpellMgr в SpellEntry)
LordJZ вне форума   Ответить с цитированием
Старый 20.05.2010, 14:04   #6
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от LordJZ Посмотреть сообщение
А чем SpellMgr не понравился? Ну вызывается и вызывается, какая разница. (хотя я бы вообще перенес весь SpellMgr в SpellEntry)
Ну какбэ в мангос с такими обращениями из unit.cpp (а оно там будет не одно)
Код:
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;
        }
в spellmgr.h

Но мне же нужно принятие в git

Последний раз редактировалось Insider42; 20.05.2010 в 14:56.
Insider42 вне форума   Ответить с цитированием
Старый 20.05.2010, 14:06   #7
LordJZ
Супер-модератор
 
Аватар для LordJZ
 
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
LordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранита
По умолчанию

Дак я думаю функцию CalcRankChance вообще никогда не примут...
LordJZ вне форума   Ответить с цитированием
Старый 20.05.2010, 14:10   #8
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от LordJZ Посмотреть сообщение
Дак я думаю функцию CalcRankChance вообще никогда не примут...
А что, тогда громоздить 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.
Insider42 вне форума   Ответить с цитированием
Старый 20.05.2010, 14:58   #9
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

ммм, оно крашится при проке :/
Код:
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.
Insider42 вне форума   Ответить с цитированием
Старый 20.05.2010, 15:05   #10
LordJZ
Супер-модератор
 
Аватар для LordJZ
 
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
LordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранита
По умолчанию

Прогоните в дебаггере, виндовзовские крашдампы малопонятны, по крайней мере не для asm кодера.
LordJZ вне форума   Ответить с цитированием
Старый 20.05.2010, 15:12   #11
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от LordJZ Посмотреть сообщение
Прогоните в дебаггере, виндовзовские крашдампы малопонятны, по крайней мере не для asm кодера.
У меня с этим проблема, сервер тестирую на удаленной машинке, там нету студии и нет возможности поставить :/
Insider42 вне форума   Ответить с цитированием
Старый 20.05.2010, 15:16   #12
xex
Пользователь
 
Регистрация: 08.03.2010
Сообщений: 47
Сказал(а) спасибо: 45
Поблагодарили 29 раз(а) в 13 сообщениях
xex На верном пути
По умолчанию

roll_chance_i инлайн функция и ждёт int, может так?
PHP код:
-       uint8 CalcRankChance(uint32 spellIduint8 maxChance) const
+       
int CalcRankChance(uint32 spellIduint8 maxChance) const
        {
            
uint8 curRank GetSpellRank(spellId);
            
uint8 rankCount SpellRanksCount(spellId);
-            
uint8 result uint8(maxChance/rankCount*curRank);
-            return 
result;
+            return 
int(maxChance/rankCount*curRank);
        } 
или тип привести: roll_chance_i(int(sSpellMgr.CalcRankChance(dummySpell->Id,60)))

Последний раз редактировалось xex; 20.05.2010 в 15:29.
xex вне форума   Ответить с цитированием
Старый 20.05.2010, 15:23   #13
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от xex Посмотреть сообщение
roll_chance_i инлайн функция и ждёт int, может так?
PHP код:
-       uint8 CalcRankChance(uint32 spellIduint8 maxChance) const
+       
int CalcRankChance(uint32 spellIduint8 maxChance) const
        {
            
uint8 curRank GetSpellRank(spellId);
            
uint8 rankCount SpellRanksCount(spellId);
-            
uint8 result uint8(maxChance/rankCount*curRank);
-            return 
result;
+            return 
int(maxChance/rankCount*curRank);
        } 
всё равно тот же краш
Insider42 вне форума   Ответить с цитированием
Старый 20.05.2010, 15:23   #14
zergtmn
MaNGOS Dev
 
Аватар для zergtmn
 
Регистрация: 07.03.2010
Сообщений: 314
Сказал(а) спасибо: 30
Поблагодарили 153 раз(а) в 83 сообщениях
zergtmn Обладатель прекрасной аурыzergtmn Обладатель прекрасной ауры
По умолчанию

Деление на 0?
zergtmn вне форума   Ответить с цитированием
Старый 20.05.2010, 15:32   #15
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от zergtmn Посмотреть сообщение
Деление на 0?
так оно и есть, но тут хлеще. Деление 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
до 3го не дошло

Последний раз редактировалось Insider42; 20.05.2010 в 15:39.
Insider42 вне форума   Ответить с цитированием
Старый 20.05.2010, 16:27   #16
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Что-то я не подумал что можно же было сделать проще :/
Код:
            // 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.
Insider42 вне форума   Ответить с цитированием
Старый 20.05.2010, 16:45   #17
MaS0n
Модератор
 
Регистрация: 09.03.2010
Адрес: dev/null
Сообщений: 126
Сказал(а) спасибо: 44
Поблагодарили 111 раз(а) в 47 сообщениях
MaS0n Скоро придёт к известностиMaS0n Скоро придёт к известности
Отправить сообщение для MaS0n с помощью ICQ
По умолчанию

Попробуй
Возможно для талантов так:
Код:
bool talentCost = GetTalentSpellCost(dummySpell->Id);
uint8 rank = talentCost ? talentCost : sSpellMgr.GetSpellRank(dummySpell->Id);
В комментах к функции GetSpellRank просто стоит
Цитата:
// Note: not use rank for compare to spell ranks: spell chains isn't linear order
MaS0n вне форума   Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[9788][patch] Игнорирование количества игроков на БГ при включённом дебаге. Anti Принятые патчи 1 24.04.2010 09:27
Каст спелла объектом на нпц virusav Новичкам 9 13.03.2010 14:19
Сообщения при касте спелла 2764 virusav Баг-репорты 0 07.03.2010 21:46


Текущее время: 06:22. Часовой пояс GMT +3.


ru-mangos.ru - Русское сообщество MaNGOS
Главная цель проекта MaNGOS - обучающая, поэтому разрешается использовать исходный код и собранную программу только для образовательных целей.
Вы не можете использовать MaNGOS в коммерческих целях, а также не разрешается устанавливать публичные серверы на базе MaNGOS.
Любое копирование материалов, информации в любом виде без указания источника - форума Ru-MaNGOS будет считаться нарушением авторских прав и нарушением Уголовного Кодекса РФ, ст. 146 ст. 147.
Перевод vBulletin: zCarot