Jump to content

rechapa79

Members
  • Posts

    33
  • Joined

  • Last visited

    Never
  • Donations

    0.00 GBP 

Everything posted by rechapa79

  1. updated again. i think its mostly ready to go to the "under review" section
  2. why no one told me the patch was unusable? updated again
  3. looking into the DBCs Im getting the feeling AURA_STATE_IMMOLATE is a misnomer, because it indicates if it is possible to cast Conflagrate on the target so it should be something like AURA_STATE_CONFLAGRATE. if its true(not saying that it is, just looking for confirmation here), that would mean: - On the event of Shadowflame DOT removal, it should be checked the existence of a Immolate debuff and vice versa before the removal of the Aura State. - The current implementation of Incinerate should be changed because it checks for AURA_STATE_IMMOLATE instead of searching for the actual Immolate debuff. So: should i file bug for this?
  4. Here is a patch for applying DOT effect of the warlock spell "shadowflame" and ranks. Updated: 4/17/09: changelog: -modified code so ShadowFlame DOT triggers AURA_STATE_IMMOLATE (yes this is a hackfix) -conflagrate will remove the shadowflame dot. Updated 4/18/09 Changelog: -Reimplemented incinerate so it looks for an actual Immolate aura instead of AURA_STATE_IMMOLATE -AURA_STATE_IMMOLATE will stay on as long there is a Shadowflame DOT or an Immolate aura -Use SpellFamilyFlags2 for Shadowflame DOT TODO?: -modify conflagate to search for the aura with the least duration instead the first one that pops up? -rename AURA_STATE_IMMOLATE to AURA_STATE_CONFLAGRATE? (I think it is the proper name) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index f3140cb..af14380 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2388,7 +2388,7 @@ void Spell::cast(bool skipCheck) Unit::AuraList const &mPeriodic = m_targets.getUnitTarget()->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); for(Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i) { - if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags & 4) && + if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (((*i)->GetSpellProto()->SpellFamilyFlags & 4) || ((*i)->GetSpellProto()->SpellFamilyFlags2 & 2) ) && (*i)->GetCasterGUID()==m_caster->GetGUID() ) { m_targets.getUnitTarget()->RemoveAura((*i)->GetId(), (*i)->GetEffIndex()); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index a02ea15..59e2d90 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -978,9 +978,9 @@ void Aura::_AddAura() if (IsSealSpell(m_spellProto)) m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true); - // Conflagrate aura state on Immolate - if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellProto->SpellFamilyFlags & 4) - m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true); + // Conflagrate aura state on Immolate and Shadowflame + if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && ((m_spellProto->SpellFamilyFlags & 4) || (m_spellProto->SpellFamilyFlags2 & 2))) + m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true); // Faerie Fire (druid versions) if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) @@ -1082,8 +1082,37 @@ void Aura::_RemoveAura() removeState = AURA_STATE_JUDGEMENT; // Update Seals information break; case SPELLFAMILY_WARLOCK: - if(m_spellProto->SpellFamilyFlags & 4) - removeState = AURA_STATE_IMMOLATE; // Conflagrate aura state + if(m_spellProto->SpellFamilyFlags & 4){ + //check if there is a shadowflame DOT present, if not, remove AURA_STATE_IMMOLATE + Unit::AuraList const& SFDOT = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + bool removeAuraState=true; + for(Unit::AuraList::const_iterator i = SFDOT.begin(); i != SFDOT.end(); ++i) + { + if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags2 & 2)) + { + removeAuraState=false; + break; + } + } + if(removeAuraState) + removeState = AURA_STATE_IMMOLATE; + } + else if(m_spellProto->SpellFamilyFlags2 & 2){ + //check if there is a Immolate DOT present, if not, remove AURA_STATE_IMMOLATE + Unit::AuraList const& IMDOT = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + bool removeAuraState=true; + for(Unit::AuraList::const_iterator i = IMDOT.begin(); i != IMDOT.end(); ++i) + { + if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags & 4)) + { + removeAuraState=false; + break; + } + } + if(removeAuraState) + removeState = AURA_STATE_IMMOLATE; + } + break; case SPELLFAMILY_DRUID: if(m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 13d1f03..eeebd89 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -400,8 +400,29 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) if((m_spellInfo->SpellFamilyFlags & 0x00004000000000LL) && m_spellInfo->SpellIconID==2128) { // Incinerate does more dmg (dmg*0.25) if the target is Immolated. - if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE)) - damage += int32(damage*0.25f); + Unit::AuraList const& RejorRegr = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + + for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) + { + if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags & 4)) + { + + damage += int32(damage*0.25f); + break; + } + } + } + // Shadowflame DOT + else if (m_spellInfo->SpellFamilyFlags & 0x0001000000000000LL) + { + switch(m_spellInfo->Id) + { + case 47897: m_caster->CastSpell(unitTarget, 47960, true); break; + case 61290: m_caster->CastSpell(unitTarget, 61291, true); break; + default: + sLog.outError("Spell::EffectDummy: Unhandeled Shadowflame spell rank %u",m_spellInfo->Id); + break; + } } break; }
  5. if i understood you correctly, with this patch, Ranged and melee based attacks wont benefit from spell power and magic based attacks will not benefit from attack power. if that is the case, wouldn't that screw paladin's damage calculation completely? i mean, as patch 3.x most paladins damage dealing abilities benefit from AP and SP. in ie: Seal of Command, witch is Melee based, benefits from spell power. Judgements, Exorcisms, and Consecration are "magic" based abilities and they benefit from attack power.
  6. silly me. if Nourish reacts to all Druid HOTs, then is useless to check for individual auras. patch updated EDIT: 3.1.0 is not out yet, so lets not get ahead of ourselves
  7. you are right, i missed lifebloom. ill update the patch after i can test it
  8. Who wrote this patch: me again,with special thanks to gsa and Sarjuuk for their imput What this patch does: Increase the amount healed by Nourish by 20% when the target is affected by regrow, rejuvenation, lifebloom or wild grown For what revision this patch was made: 7553+ any thread reporting this bug: None that i could find. If there is one please tell --- mangos/src/game/SpellEffects.cpp 2009-03-27 14:41:29.000000000 -0300 +++ patch/src/game/SpellEffects.cpp 2009-03-27 14:22:00.000000000 -0300 @@ -2473,6 +2473,23 @@ addhealth += tickheal * tickcount; } + //Nourish 20% of heal increase if target is afected by Druids HOTs + else if(m_spellInfo->SpellFamilyFlags&0x0200000000000000LL){ + Unit::AuraList const& RejorRegr = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); + + for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) + { + if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID) + { + addhealth+=addhealth*0.2; + break; + } + } + + + + } else addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);
  9. you are right. i missed that percentMana=(player->GetPower(POWER_MANA)*100)/player->GetMaxPower(POWER_MANA); that would be the correct way to do it. odd this problem hasnt shown up on the first patch
  10. 1)??? weird. you could try and replace it by percentMana=((player->GetPower(POWER_MANA)/player->GetMaxPower(POWER_MANA) * 100); 2) i guess i'd never thought of using the object for some player thats not mana based. the replenishment function filters them out. however someone might do something nasty. this check on the constructor will prevent that ReplenishPlayerWraper(Player* player):Player(player) { if(Target->getPowerType() == POWER_MANA) percentMana=((player->GetPower(POWER_MANA)/player->GetMaxPower(POWER_MANA) * 100); else percentMana=101; }
  11. there are two versions of the patch: 1-the unoptimized but most tested version 2- the optimized but mostly untested version both are in all-in one diff format. the second version removes redundant calculation of the filled mana percentages, so it should be quicker
  12. if is not causing cpu spikes then thats ok
  13. not saying it doesnt. im just saying i don't know this for a fact
  14. i you replace on SpellEffects.cpp: m_caster->CastSpell(m_caster,57669,true,NULL,m_caster->GetDummyAura(aur),m_caster->GetGUID()); by if (((Player*)m_caster)->GetGroup()) m_caster->CastSpell(m_caster,57669,true,NULL,m_caster->GetDummyAura(aur),m_caster->GetGUID()); replenishment will not be cast while not in group
  15. i have been over the comparer, and i think the currently used is less than optimal. so im puting a wrapper around the player object. it calculates the filled mana percentage upon construction. this prevents the constant calculation of the percentages every time the sorting takes place speeding up things a bit. Spell.cpp: --- patch/src/game/Spell.cpp 2009-03-13 11:36:30.000000000 -0200 +++ mangos/src/game/Spell.cpp 2009-03-13 12:14:55.000000000 -0200 @@ -48,6 +48,27 @@ #define SPELL_CHANNEL_UPDATE_INTERVAL (1*IN_MILISECONDS) extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS]; +class ReplenishPlayerWraper +{ + Player* player; + uint32 percentMana; + friend class PrioritizeMana; +public: + ReplenishPlayerWraper(Player* player):Player(player) + { + percentMana=(player->GetPower(POWER_MANA)/player->GetMaxPower(POWER_MANA)) * 100; + } + Player* getPlayer(){ + return player; + } +}; +class PrioritizeMana +{ + public:int operator()( const ReplenishPlayerWraper& x, const ReplenishPlayerWraper& y ) const { + return x.percentMana < y.percentMana; + } +}; + bool IsQuestTameSpell(uint32 spellId) { @@ -1592,25 +1613,52 @@ if(pGroup) { - 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); - } - } + if(m_spellInfo->Id==57669) //Replenishment + { + typedef std::Priority_queue<ReplenishPlayerWraper, std::vector<ReplenishPlayerWraper>, 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)) + { + ReplenishPlayerWraper WTarget(Target); + manaUsers.push(WTarget); + } + } + + for(int countera=0; ( !manaUsers.empty() )&& countera<10;countera++) + { + ReplenishPlayerWraper WTarget = manaUsers.top(); + Player* Target = WTarget.getPlayer(); + 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); + } + } + } } else { for SpellEffects.cpp use the patch on my previous post. PS: i have been testing it. and it seems is granting replenishment whatever the player is on a party or not. dont know if this is intented or not
  16. here is kozelo's patch on diff format Spell.cpp: --- patch/src/game/Spell.cpp 2009-03-13 11:36:30.000000000 -0200 +++ mangos/src/game/Spell.cpp 2009-03-13 11:40:01.000000000 -0200 @@ -49,6 +49,14 @@ 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) { SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId); @@ -1592,25 +1600,50 @@ if(pGroup) { - 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); - } - } + 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); + } + } + } } else { SpellEffects.cpp: --- patch/src/game/SpellEffects.cpp 2009-03-13 11:36:39.000000000 -0200 +++ mangos/src/game/SpellEffects.cpp 2009-03-13 11:42:19.000000000 -0200 @@ -5158,6 +5158,24 @@ 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 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)
  17. god. we have created a monster :lol:
  18. 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.
  19. 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
  20. 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
  21. 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.
×
×
  • 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