Jump to content

[FIX] Judgement of the wise


kozelo

Recommended Posts

What bug does the patch fix? What features does the patch add?

- This patch would fix paladin talent Judgement of the wise.

For which repository revision was the patch created?

- 7414

Who has been writing this patch

kozelo, rechapa79 with active support from Lightguard and the other who helped with advise.

In SpellEffects.cpp

                          // Judgement self add switch
               switch (m_spellInfo->Id)
               {
                   case 41467: break;                      // Judgement
                   case 53407: spellId1 = 20184; break;    // Judgement of Justice
                   case 20271:                             // Judgement of Light
                   case 57774: spellId1 = 20185; break;    // Judgement of Light
                   case 53408: spellId1 = 20186; break;    // Judgement of Wisdom
                   default:
                       return;
               }

+                //Judgement of the wise
+                int chance =0;
+                int32 aur =0;
+                if(m_caster->HasAura(31876)) {chance=33;aur=31876;}
+                else if (m_caster->HasAura(31877)) {chance=66;aur=31877;}
+                else if (m_caster->HasAura(31878)) {chance=100;aur=31878;}
+                if(chance != 0)
+                {
+                    int32 mana15 = m_caster->GetCreateMana() * 0.15;
+                    if(urand(1,100) <= chance) 
+                    {
+                        m_caster->CastCustomSpell(m_caster,31930,&mana15,false,false,true,NULL,m_caster->GetDummyAura(aur),m_caster->GetGUID());
+                                             m_caster->CastSpell(m_caster,57669,true,NULL,m_caster->GetDummyAura(aur),m_caster->GetGUID());
+                    }
+                    
+                }        
+                //Judgement of the wise end 

               // all seals have aura dummy in 2 effect

in Spell.cpp

#define SPELL_CHANNEL_UPDATE_INTERVAL (1*IN_MILISECONDS)

extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];

+class PrioritizeMana
+    {
+        public:int operator()( const Player* x, const Player* y ) const {
+            return ((x->GetPower(POWER_MANA)/x->GetMaxPower(POWER_MANA) * 100) < (y->GetPower(POWER_MANA)/y->GetMaxPower(POWER_MANA)*100)); 
+    }
+};

bool IsQuestTameSpell(uint32 spellId)
{

In Spell.cpp, Spell::SetTargetMap

       case TARGET_ALL_PARTY_AROUND_CASTER:
       case TARGET_ALL_PARTY_AROUND_CASTER_2:
       case TARGET_ALL_PARTY:
       case TARGET_ALL_RAID_AROUND_CASTER:
       {
        Player *pTarget = m_caster->GetCharmerOrOwnerPlayerOrPlayerItself();
           Group *pGroup = pTarget ? pTarget->GetGroup() : NULL;

           if(pGroup)
           {
+        if(m_spellInfo->Id==57669) //Replenishment
+        {
+        typedef std::Priority_queue<Player*, std::vector<Player*>, PrioritizeMana> Top10;
+        Top10 manaUsers;
+
+            for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+                {
+                    Player* Target = itr->getSource();
+                    if(m_caster->GetGUID() != Target->GetGUID() && Target->getPowerType() == POWER_MANA && !Target->isDead() && m_caster->IsWithinDistInMap(Target, radius))
+                    {
+                        manaUsers.push(Target);
+                    }
+                }
+
+                for(int countera=0; ( !manaUsers.empty() )&& countera<10;countera++)
+                {
+                    Player* Target = manaUsers.top();
+                    manaUsers.pop();
+                    TagUnitMap.push_back(Target);
+                }
+        }
+        else
+        {
          uint8 subgroup = pTarget->GetSubGroup();

               for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
               {
                   Player* Target = itr->getSource();

                   // IsHostileTo check duel and controlled by enemy
                   if( Target &&
                       (cur==TARGET_ALL_RAID_AROUND_CASTER || Target->GetSubGroup()==subgroup) &&
                       !m_caster->IsHostileTo(Target) )
                   {
                       if( m_caster->IsWithinDistInMap(Target, radius) )
                           TagUnitMap.push_back(Target);

                       if(Pet* pet = Target->GetPet())
                           if( m_caster->IsWithinDistInMap(pet, radius) )
                               TagUnitMap.push_back(pet);
                   }
               }
           }
+    }

Link to comment
Share on other sites

  • Replies 77
  • Created
  • Last Reply

Top Posters In This Topic

The main idea is good:) But,

1. Whatever you do, you should not use hard-coded spellids if there's any other solution, or not everywhere.

2. Using the variables provided by the class, or even dbc values would make it more dynamic, and less hacky.

3. Using random selection is incorrect here, as i think, we should iterate through the group, and select 10 with the lowest power, that needs an ordering what's probably the hardest in this spell.

This is just my opinion, maybe other can give you better advices.

Link to comment
Share on other sites

Thanks for the advise, but:

The caster with lowest power isnt always the caster that needs more regen, per example healers have greater regen than mage in combat and often have more mana, but they need more regen in raids. So let the first 10 mana-powered members have the buff. :D

Link to comment
Share on other sites

int32 mana15 = m_caster->GetMaxPower(POWER_MANA) * 0.15;

It 's wrong, we must use a base mana.

Quote from wowwiki.com

Your Judgement spells have a X% chance to grant up to 10 party or raid members mana regeneration equal to 0.25% of their maximum mana per second, and to immediately grant you 15% of your base mana.

Use a function GetCreateMana() for your fix.

Thanks for patch :)

Link to comment
Share on other sites

Replenishment should be granted to the 10 people with the lowest mana.

In addition to this change, we also needed to address the "mana battery" roles in a raid. The mana regeneration effect they grant is no longer limited to their own party, and it no longer depends on the amount of damage they deal. Each time they trigger the mana regeneration effect, 10 people in their raid group will receive a buff which causes them to regenerate 0.5% of their maximum mana each second. This buff, Replenishment, will be given preferentially to raid members with the lowest mana, but will re-evaluate which raid members receive it each time it is fired. Replenishment is provided by Shadow Priests, Survival Hunters, and Retribution Paladins.

Source

Link to comment
Share on other sites

i was thinking, paladins arent the only class that grants the replenishment effect. there's the shadow priests and the survival hunters, also other classes might grant this effect on the future. so i think the part of the code that grants replenishment should be moved to a separate function so its available to the other classes too.

about the selection of who gets replenishment. i think a priority queue should be used to find out who are the first 10 mana users with the least power.

Link to comment
Share on other sites

i havent tested it yet, but by looking at it:

i think this:

typedef std::map<Player*,int32> Top10;

shound look like:

typedef std::map<int32,Player*> Top10;

because as it is, gets sorted not by the mana, but by the player's position on the memory :lol:

Edit: also i dont think using maps is a good idea. there could be weird cases where 2 or more people have the same amount of mana. best case scenario: only one of them will get the replenishment

Link to comment
Share on other sites

multimaps could work but i fear it would cause too many iterations.

actually i was thinking in something like this(didnt test it):

class PrioritizeMana{
   public : int operator()( const Player* x, const Player* y ) {
        return x->GetPower(POWER_MANA) < y->GetPower(POWER_MANA); 
   } 
}
priority_queue<Player*, vector<Player*>, PrioritizeMana> Top10; 
if( pGroup)
{
   for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
   {
       Player* Target = itr->getSource();
       if(m_caster->GetGUID() != Target->GetGUID() && Target->getPowerType() == POWER_MANA && !Target->isDead())
       {
           Top10.push(Target);
       }
   }

   for(int countera=0; ( !Top10.empty() )&& countera<10;countera++)
   {
       Player* Target = Top10.top();
       Top10.pop();
       if(m_caster != Target) m_caster->CastSpell(Target,57669,true,NULL,m_caster->GetDummyAura(aur),m_caster->GetGUID());
   }
}

the priority queue automatically sorts the players using the comparer above. the one on the top will be the one with the least mana

Link to comment
Share on other sites

I am sorry to say that, but Replenishment is already implemented at server side.

First code updated.

Here is the result of our common efforts:

void Spell::CastReplenishmentToParty(Unit* caster, int32 SpellId,  int MembersToAffect)
{
               Group *pGroup = NULL;

                   if (caster->GetTypeId() == TYPEID_PLAYER)
                       pGroup = ((Player*)caster)->GetGroup();

                   class PrioritizeMana
                   {
                   public:int operator()( const Player* x, const Player* y ) const {
                                return ((x->GetPower(POWER_MANA)/x->GetMaxPower(POWER_MANA) * 100) < (y->GetPower(POWER_MANA)/y->GetMaxPower(POWER_MANA)*100)); 
                            } 
                   };


                   typedef std::Priority_queue<Player*, std::vector<Player*>, PrioritizeMana> Top10;
                   Top10 manaUsers;
                   if( pGroup)
                   {
                       for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) 
                       {
                           Player* Target = itr->getSource();
                           if(caster->GetGUID() != Target->GetGUID() && Target->getPowerType() == POWER_MANA && !Target->isDead()) 
                           {
                               manaUsers.push(Target);
                           }
                       }

                       for(int countera=0; ( !manaUsers.empty() ) && countera<MembersToAffect;++countera)
                       {
                           Player* Target = manaUsers.top();
                           manaUsers.pop();
                           if(caster->GetGUID() != Target->GetGUID()) 
                           {
                               caster->CastSpell(Target,SpellId,true,NULL,NULL,caster->GetGUID());
                           }
                       }

                   }
}


Link to comment
Share on other sites

I tried to clear it a bit:

diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 25372e5..603c587 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -2369,6 +2369,39 @@ void Spell::cast(bool skipCheck)
    SetExecutedCurrently(false);
}

+void Spell::CastReplenishmentToParty(Unit* caster, int32 SpellId,  int MembersToAffect)
+{
+    Group *pGroup = NULL;
+
+    if (caster->GetTypeId() == TYPEID_PLAYER)
+        pGroup = ((Player*)caster)->GetGroup();
+
+    class PrioritizeMana
+    {
+        public:int operator()( const Player* x, const Player* y ) const {
+            return ((x->GetPower(POWER_MANA)/x->GetMaxPower(POWER_MANA) * 100) < (y->GetPower(POWER_MANA)/y->GetMaxPower(POWER_MANA)*100)); 
+    }
+
+    Top10 manaUsers;
+    if( pGroup)
+    {
+        for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) 
+        {
+            Player* Target = itr->getSource();
+            if(caster->GetGUID() != Target->GetGUID() && Target->getPowerType() == POWER_MANA && !Target->isDead())
+                manaUsers.push(Target);
+        }
+        
+        for(int countera=0; ( !manaUsers.empty() ) && countera<MembersToAffect;++countera)
+        {
+            Player* Target = manaUsers.top();
+            manaUsers.pop();
+            if(caster->GetGUID() != Target->GetGUID()) 
+                caster->CastSpell(Target,SpellId,true,NULL,NULL,caster->GetGUID());
+        }
+    }
+};
+
void Spell::handle_immediate()
{
    // start channeling if applicable
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 2b70422..fe5b356 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -207,6 +207,7 @@ enum SpellState
#define SPELL_SPELL_CHANNEL_UPDATE_INTERVAL (1*IN_MILISECONDS)

typedef std::multimap<uint64, uint64> SpellTargetTimeMap;
+typedef std::Priority_queue<Player*, std::vector<Player*>, PrioritizeMana> Top10;

class Spell
{ 

Link to comment
Share on other sites

i think that wont compile. trying to declare the "PriorizeMana" class inside the function got me STL errors.that was on linux.

here is my version of the patch:



--- mangos/src/game/SpellEffects.cpp    2009-03-11 21:58:10.000000000 -0200
+++ patch/src/game/SpellEffects.cpp    2009-03-11 21:57:20.000000000 -0200
@@ -4645,7 +4645,11 @@
        }
    }
}
-
+class PrioritizeMana{
+    public : int operator()( const Player* x, const Player* y ) {
+         return x->GetPower(POWER_MANA) < y->GetPower(POWER_MANA); 
+    } 
+};
void Spell::EffectScriptEffect(uint32 effIndex)
{
    // TODO: we must implement hunter pet summon at login there (spell 6962)
@@ -5093,6 +5097,44 @@
                    default:
                        return;
                }
+        //Judgement of the wise
+        int chance =0;
+        int32 aur =0;
+        if(m_caster->HasAura(31876)) {chance=33;aur=31876;}
+        else if (m_caster->HasAura(31877)) {chance=66;aur=31877;}
+        else if (m_caster->HasAura(31878)) {chance=100;aur=31878;}
+        if(chance != 0)
+        {
+            int32 mana15 = m_caster->GetCreateMana() * 0.15;
+            if(urand(1,100) <= chance) m_caster->CastCustomSpell(m_caster,31930,&mana15,false,false,true,NULL,m_caster->GetDummyAura(aur),m_caster->GetGUID());
+            int countera =0;
+
+            
+            Group *pGroup = NULL;
+            if (m_caster->GetTypeId() == TYPEID_PLAYER)
+                pGroup = ((Player*)m_caster)->GetGroup();
+
+            std::Priority_queue<Player*, std::vector<Player*>, PrioritizeMana> Top10; 
+            if( pGroup)
+            {
+                for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+                {
+                    Player* Target = itr->getSource();
+                    if(m_caster->GetGUID() != Target->GetGUID() && Target->getPowerType() == POWER_MANA && !Target->isDead())
+                    {
+                        Top10.push(Target);
+                    }
+                }
+
+                for(int countera=0; ( !Top10.empty() )&& countera<10;countera++)
+                {
+                    Player* Target = Top10.top();
+                    Top10.pop();
+                    if(m_caster != Target) m_caster->CastSpell(Target,57669,true,NULL,m_caster->GetDummyAura(aur),m_caster->GetGUID());
+                }
+            }
+        }        









+        //Judgement of the wise end
                // all seals have aura dummy in 2 effect
                Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
                for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr)


compiles and runs. sadly i havent been able to test the replenishment part. :(

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use