Jump to content

rowman

Members
  • Posts

    18
  • Joined

  • Last visited

    Never
  • Donations

    0.00 GBP 

Everything posted by rowman

  1. this is quite useful because you can decide how you want to use it ( on dodge,parry,...,... )
  2. dont think that this is the right implementation The cyclones follow random targets for x seconds ( -> SD2) Changing the target is not connected with this spell -> they cast zap on each player A who casts sth WHILE they're following a random target B ( B can be != A ) so why set new attacking target ? and select attacking target random is wrong because it also returns totems & pets
  3. yeah but this has nothing to do with this fix you cant implement feign death in ->isTargetableForAttack() for example - pet must be stopped if the hunter uses feign death, but if the pet is send to attack (to interupt feign death) this must be possible
  4. hmm ok wrong memories... its been a long time but a renewal shouldnt assume the old calculation ?!
  5. im quite sure thats the way it worked @ 2.4.3, but not yet found any source ...
  6. little example: activate trinkets and other addheal buffs use booming life (now high tick caused by high addheal) trinkets etc expire blooming life tick is still high as long as you renew bl
  7. * What bug does the patch fix? What features does the patch add? periodicheal ignored changing addheal (caster) * For which repository revision was the patch created? ONE * Is there a thread in the bug report section or at lighthouse? If yes, please add a link to the thread. dont know * Who has been writing this patch? Please include either forum user names or email addresses. me diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index b36131d..6299286 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -5853,6 +5934,7 @@ void Aura::PeriodicTick() else pdamage = amount; + pdamage = pCaster->SpellHealingBonusDone(target,spellProto,pdamage,DOT,GetStackAmount()); pdamage = target->SpellHealingBonusTaken(pCaster, spellProto, pdamage, DOT, GetStackAmount()); DETAIL_FILTER_LOG(LOG_FILTER_PERIODIC_AFFECTS, "PeriodicTick: %s heal of %s for %u health inflicted by %u",
  8. you can use flags and other bg objects with spirit of remdemtion diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4ea97f9..818e079 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -19758,7 +19777,7 @@ bool Player::isTotalImmune() if( immuneMask & SPELL_SCHOOL_MASK_ALL ) // total immunity return true; } - return false; + return HasAura(27827);//spirit of redemption } bool Player::HasTitle(uint32 bitIndex) const
  9. think petai ignores stealth in two cases 1) dont attack rogues too early 2) dont attack them any longer if they use stealth diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index 9f9b4dd..32c1f09 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -61,8 +61,11 @@ void PetAI::MoveInLineOfSight(Unit *u) { if(m_creature->IsWithinLOSInMap(u)) { - AttackStart(u); - u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + if (IsVisible(u)) + { + AttackStart(u); + u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } } } } @@ -99,7 +102,7 @@ bool PetAI::_needToStop() const if(m_creature->isCharmed() && m_creature->getVictim() == m_creature->GetCharmer()) return true; - return !m_creature->getVictim()->isTargetableForAttack(); + return !m_creature->getVictim()->isTargetableForAttack() && IsVisible(m_creature->getVictim()); }
  10. a few more features for this method diff --git a/src/game/Creature.h b/src/game/Creature.h index b4421cb..0534698 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -284,11 +284,28 @@ enum AttackingTarget ATTACKING_TARGET_RANDOM = 0, //Just selects a random target ATTACKING_TARGET_TOPAGGRO, //Selects targes from top aggro to bottom ATTACKING_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top - /* not implemented ATTACKING_TARGET_RANDOM_PLAYER, //Just selects a random target (player only) ATTACKING_TARGET_TOPAGGRO_PLAYER, //Selects targes from top aggro to bottom (player only) ATTACKING_TARGET_BOTTOMAGGRO_PLAYER, //Selects targets from bottom aggro to top (player only) - */ + ATTACKING_TARGET_NEAREST_PLAYER, + ATTACKING_TARGET_FARTHEST_PLAYER, + ATTACKING_TARGET_LOWEST_HP, + ATTACKING_TARGET_HIGHEST_HP, +}; +// +enum AttackingTargetRangeFlag +{ + AT_RANGE_FLAG_NO_FLAG = 0, + AT_RANGE_FLAG_IN_MELEE_RANGE = 1, + AT_RANGE_FLAG_OUT_OF_MELEE_RANGE= 2, + +}; +//add rage & energy? +enum AttackingTargetExtraFlag +{ + AT_EXTRA_FLAG_NO_FLAG = 0, + AT_EXTRA_FLAG_NO_MANA_CLASS = 1, + AT_EXTRA_FLAG_MANA_CLASS = 2, }; // Vendors @@ -674,7 +691,7 @@ class MANGOS_DLL_SPEC Creature : public Unit void SetInCombatWithZone(); - Unit* SelectAttackingTarget(AttackingTarget target, uint32 position) const; + Unit* SelectAttackingTarget(AttackingTarget target, uint32 position, AttackingTargetRangeFlag RangeFlag = AT_RANGE_FLAG_NO_FLAG, AttackingTargetExtraFlag ExtraFlag = AT_EXTRA_FLAG_NO_FLAG) const; bool HasQuest(uint32 quest_id) const; bool HasInvolvedQuest(uint32 quest_id) const; diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 82bbb67..ffeaf33 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -2019,7 +2019,8 @@ void Creature::SetInCombatWithZone() } } -Unit* Creature::SelectAttackingTarget(AttackingTarget target, uint32 position) const + +Unit* Creature::SelectAttackingTarget(AttackingTarget target, uint32 position, AttackingTargetRangeFlag RangeFlag, AttackingTargetExtraFlag ExtraFlag) const { if (!CanHaveThreatList()) return NULL; @@ -2027,33 +2028,101 @@ Unit* Creature::SelectAttackingTarget(AttackingTarget target, uint32 position) c //ThreatList m_threatlist; ThreatList const& threatlist = getThreatManager().getThreatList(); ThreatList::const_iterator i = threatlist.begin(); - ThreatList::const_reverse_iterator r = threatlist.rbegin(); if (position >= threatlist.size() || !threatlist.size()) return NULL; + + std::vector<Unit *> target_list; + + //prepare target list + for (;i != threatlist.end(); ++i) + { + Unit* pTarget = GetMap()->GetUnit((*i)->getUnitGuid()); + + // only player cases: + if (target == ATTACKING_TARGET_RANDOM_PLAYER || target == ATTACKING_TARGET_TOPAGGRO_PLAYER || target == ATTACKING_TARGET_BOTTOMAGGRO_PLAYER + || target == ATTACKING_TARGET_NEAREST_PLAYER || target == ATTACKING_TARGET_FARTHEST_PLAYER ) + { + if (pTarget && (pTarget->GetTypeId() != TYPEID_PLAYER || !pTarget->isAlive())) + { + pTarget = NULL; + continue; + } + } + + //check range flags + if ((RangeFlag==AT_RANGE_FLAG_OUT_OF_MELEE_RANGE && this->CanReachWithMeleeAttack(pTarget)) + || (RangeFlag==AT_RANGE_FLAG_IN_MELEE_RANGE && !this->CanReachWithMeleeAttack(pTarget))) + { + pTarget = NULL; + continue; + } + + //check extra flags + if ((ExtraFlag == AT_EXTRA_FLAG_NO_MANA_CLASS && pTarget->getPowerType() == POWER_MANA) + || (ExtraFlag == AT_EXTRA_FLAG_MANA_CLASS && pTarget->getPowerType() != POWER_MANA)) + { + pTarget = NULL; + continue; + } + + if (pTarget) + target_list.push_back(pTarget); + } + + //Flags excluded all existing targets: + if (!target_list.size()) + return NULL; + + //select target: + switch(target) { case ATTACKING_TARGET_RANDOM: + case ATTACKING_TARGET_RANDOM_PLAYER: { - advance(i, position + (rand() % (threatlist.size() - position))); - return GetMap()->GetUnit((*i)->getUnitGuid()); + return *(target_list.begin()+position+rand()%target_list.size()); } case ATTACKING_TARGET_TOPAGGRO: + case ATTACKING_TARGET_TOPAGGRO_PLAYER: { - advance(i, position); - return GetMap()->GetUnit((*i)->getUnitGuid()); + return *(target_list.begin()+position); } case ATTACKING_TARGET_BOTTOMAGGRO: + case ATTACKING_TARGET_BOTTOMAGGRO_PLAYER: { - advance(r, position); - return GetMap()->GetUnit((*r)->getUnitGuid()); + return *(target_list.end()-position); } - // TODO: implement these - //case ATTACKING_TARGET_RANDOM_PLAYER: - //case ATTACKING_TARGET_TOPAGGRO_PLAYER: - //case ATTACKING_TARGET_BOTTOMAGGRO_PLAYER: - } + case ATTACKING_TARGET_NEAREST_PLAYER: + case ATTACKING_TARGET_FARTHEST_PLAYER: + { + Unit* currentTarget = NULL; + for (size_t s_i = 0 ; s_i < target_list.size() ; ++s_i) + { + if (!currentTarget || + (target == ATTACKING_TARGET_NEAREST_PLAYER ? this->GetDistance(currentTarget) > this->GetDistance(target_list[s_i]) : + this->GetDistance(currentTarget) < this->GetDistance(target_list[s_i]))) + + currentTarget = target_list[s_i]; + } + return currentTarget; + } + case ATTACKING_TARGET_LOWEST_HP: + case ATTACKING_TARGET_HIGHEST_HP: + { + Unit* currentTarget = NULL; + for (size_t s_i = 0 ; s_i < target_list.size() ; ++s_i) + { + if (!currentTarget || + (target == ATTACKING_TARGET_LOWEST_HP ? currentTarget->GetHealth() > target_list[s_i]->GetHealth() : + currentTarget->GetHealth() < target_list[s_i]->GetHealth())) + + currentTarget = target_list[s_i]; + } + return currentTarget; + } + } return NULL; }
  11. oh i've overlooked your changes in applyspellmods
  12. isnt lastAffected only set if charge == 0 ? so you never get the chance apply restore in charges > 1 cases ? (in order to your second change)
  13. 1 mistake fixed ( Patch also fixes the "instant cast" Bug (instant never used)
  14. i tried to understand the "spell modifier system" I think there's a bug: after canceling a spell the spellmods (changed at the start in applyspellmods) are never reseted due to this failure, started and later on canceled casts use buffs like "clearcasting" although they're never finished so the buff is "used" but not removed dont know whether i understood this correctly may this fix help ? [== c++ ==] diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4ea97f9..818e079 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -17158,6 +17158,25 @@ void Player::RemoveSpellMods(Spell const* spell) } } +void Player::ResetSpellModsDueToCanceledSpell (Spell const* spell) +{ + for(int i=0;i<MAX_SPELLMOD;++i) + { + for (SpellModList::const_iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end() + { + SpellModifier *mod = *itr; + ++itr; + if (mod && mod->charges == -1 && (mod->lastAffected == spell)) + { + mod->charges += 2; + mod->lastAffected = NULL; + if (m_SpellModRemoveCount > 0) + --m_SpellModRemoveCount; + } + } + } +} + // send Proficiency void Player::SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) { diff --git a/src/game/Player.h b/src/game/Player.h index d384a69..f1bcce4 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1465,6 +1465,7 @@ class MANGOS_DLL_SPEC Player : public Unit template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL); SpellModifier* GetSpellMod(SpellModOp op, uint32 spellId) const; void RemoveSpellMods(Spell const* spell); + void ResetSpellModsDueToCanceledSpell (Spell const* spell); static uint32 const infinityCooldownDelay = MONTH; // used for set "infinity cooldowns" for spells and check static uint32 const infinityCooldownDelayCheck = MONTH/2; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 74000ef..aaff825 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2639,6 +2641,8 @@ void Spell::cancel() { } break; } + if (m_caster->GetTypeId() == TYPEID_PLAYER && !IsChanneledSpell(m_spellInfo)) + ((Player*)m_caster)->ResetSpellModsDueToCanceledSpell (this); finish(false); m_caster->RemoveDynObject(m_spellInfo->Id);
×
×
  • 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