diff options
-rw-r--r-- | sql/FULL/world_spell_full.sql | 37 | ||||
-rw-r--r-- | sql/updates/4320_world_.sql | 20 | ||||
-rw-r--r-- | src/game/PetHandler.cpp | 13 | ||||
-rw-r--r-- | src/game/Player.cpp | 3 | ||||
-rw-r--r-- | src/game/Spell.cpp | 120 | ||||
-rw-r--r-- | src/game/Spell.h | 8 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 3 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 2 | ||||
-rw-r--r-- | src/game/Unit.cpp | 13 |
9 files changed, 175 insertions, 44 deletions
diff --git a/sql/FULL/world_spell_full.sql b/sql/FULL/world_spell_full.sql index c8656ee3ecc..42fdce82132 100644 --- a/sql/FULL/world_spell_full.sql +++ b/sql/FULL/world_spell_full.sql @@ -1446,15 +1446,34 @@ INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `Spell -- -------- TRUNCATE TABLE `spell_enchant_proc_data`; INSERT INTO spell_enchant_proc_data (`entry`, `customChance`, `PPMChance`,`procEx`) VALUES -(2, 0, 8.8,0), -- Frostbrand Weapon -(12, 0, 8.8,0), -- Frostbrand Weapon -(524, 0, 8.8,0), -- Frostbrand Weapon -(1667, 0, 8.8,0), -- Frostbrand Weapon -(1668, 0, 8.8,0), -- Frostbrand Weapon -(2635, 0, 8.8,0), -- Frostbrand Weapon -(3782, 0, 8.8,0), -- Frostbrand Weapon -(3783, 0, 8.8,0), -- Frostbrand Weapon -(3784, 0, 8.8,0); -- Frostbrand Weapon + -- Frostbrand Weapon +(2, 0, 8.8,0), +(12, 0, 8.8,0), +(524, 0, 8.8,0), +(1667, 0, 8.8,0), +(1668, 0, 8.8,0), +(2635, 0, 8.8,0), +(3782, 0, 8.8,0), +(3783, 0, 8.8,0), +(3784, 0, 8.8,0), + -- Wound Poison +(703, 0, 21.43,0), +(704, 0, 21.43,0), +(705, 0, 21.43,0), +(706, 0, 21.43,0), +(2644, 0, 21.43,0), +(3772, 0, 21.43,0), +(3773, 0, 21.43,0), + -- Instant Poison +(323, 0, 8.53,0), +(324, 0, 8.53,0), +(325, 0, 8.53,0), +(623, 0, 8.53,0), +(624, 0, 8.53,0), +(625, 0, 8.53,0), +(2641, 0, 8.53,0), +(3768, 0, 8.53,0), +(3769, 0, 8.53,0); -- -------- -- SPELL AFFECT diff --git a/sql/updates/4320_world_.sql b/sql/updates/4320_world_.sql new file mode 100644 index 00000000000..a89e44b88b2 --- /dev/null +++ b/sql/updates/4320_world_.sql @@ -0,0 +1,20 @@ +DELETE FROM `spell_enchant_proc_data` WHERE `entry` IN (703, 704, 705, 706, 2644, 3772, 3773, 323, 324, 325, 623, 624, 625, 2641, 3768, 3769); +INSERT INTO spell_enchant_proc_data (`entry`, `customChance`, `PPMChance`,`procEx`) VALUES + -- Wound Poison +(703, 0, 21.43,0), +(704, 0, 21.43,0), +(705, 0, 21.43,0), +(706, 0, 21.43,0), +(2644, 0, 21.43,0), +(3772, 0, 21.43,0), +(3773, 0, 21.43,0), + -- Instant Poison +(323, 0, 8.53,0), +(324, 0, 8.53,0), +(325, 0, 8.53,0), +(623, 0, 8.53,0), +(624, 0, 8.53,0), +(625, 0, 8.53,0), +(2641, 0, 8.53,0), +(3768, 0, 8.53,0), +(3769, 0, 8.53,0); diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 3dc7c6d4ff1..67e6576c25b 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -615,12 +615,6 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) return; } - if (caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->GetGlobalCooldown() > 0) - { - caster->SendPetCastFail(spellid, SPELL_FAILED_NOT_READY); - return; - } - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid); if(!spellInfo) { @@ -628,6 +622,13 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) return; } + if (spellInfo->StartRecoveryCategory > 0) //Check if spell is affected by GCD + if (caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->GetGlobalCooldown() > 0) + { + caster->SendPetCastFail(spellid, SPELL_FAILED_NOT_READY); + return; + } + // do not cast not learned spells if(!caster->HasSpell(spellid) || IsPassiveSpell(spellid)) return; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 62f712aabf1..0a90f721899 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -17316,6 +17316,9 @@ void Player::SetSpellModTakingSpell(Spell * spell, bool apply) if (!spell || (m_spellModTakingSpell && m_spellModTakingSpell != spell)) return; + if (apply && spell->getState() == SPELL_STATE_FINISHED) + return; + if (apply) m_spellModTakingSpell = spell; else diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 2dd24dcfc6c..88e815352e1 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -371,6 +371,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi m_applyMultiplierMask = 0; m_effectMask = 0; + m_auraScaleMask = 0; // Get data for type of attack switch (m_spellInfo->DmgClass) @@ -701,7 +702,6 @@ void Spell::FillTargetMap() break; } } - if(IsChanneledSpell(m_spellInfo)) { uint8 mask = (1<<i); @@ -714,6 +714,29 @@ void Spell::FillTargetMap() } } } + else if (m_auraScaleMask) + { + bool checkLvl = !m_UniqueTargetInfo.empty(); + for(std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end();) + { + // remove targets which did not pass min level check + if(m_auraScaleMask && ihit->effectMask == m_auraScaleMask) + { + // Do not check for selfcast + if (!ihit->scaleAura && ihit->targetGUID != m_caster->GetGUID()) + { + m_UniqueTargetInfo.erase(ihit++); + continue; + } + } + ++ihit; + } + if (checkLvl && m_UniqueTargetInfo.empty()) + { + SendCastResult(SPELL_FAILED_LOWLEVEL); + finish(false); + } + } } if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) @@ -859,6 +882,13 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex) { if (!immuned) ihit->effectMask |= 1 << effIndex; // Add only effect mask if not immuned + ihit->scaleAura = false; + if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != pVictim) + { + SpellEntry const * auraSpell = sSpellStore.LookupEntry(spellmgr.GetFirstSpellInChain(m_spellInfo->Id)); + if ((pVictim->getLevel() + 10) >= auraSpell->spellLevel) + ihit->scaleAura = true; + } return; } } @@ -873,6 +903,13 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex) target.alive = pVictim->isAlive(); target.damage = 0; target.crit = false; + target.scaleAura = false; + if (m_auraScaleMask && target.effectMask == m_auraScaleMask && m_caster != pVictim) + { + SpellEntry const * auraSpell = sSpellStore.LookupEntry(spellmgr.GetFirstSpellInChain(m_spellInfo->Id)); + if ((pVictim->getLevel() + 10) >= auraSpell->spellLevel) + target.scaleAura = true; + } // Calculate hit result if(m_originalCaster) @@ -1053,7 +1090,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) if(spellHitTarget) { - SpellMissInfo missInfo = DoSpellHitOnUnit(spellHitTarget, mask); + SpellMissInfo missInfo = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura); if(missInfo != SPELL_MISS_NONE) { if(missInfo != SPELL_MISS_MISS) @@ -1179,7 +1216,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) } } -SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) +SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask, bool scaleAura) { if(!unit || !effectMask) return SPELL_MISS_EVADE; @@ -1270,22 +1307,43 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) if (aura_effmask) { + // Select rank for aura with level requirements only in specific cases + // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target + SpellEntry const * aurSpellInfo = m_spellInfo; + int32 basePoints[3]; + if (scaleAura) + { + aurSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(m_spellInfo,unitTarget->getLevel()); + assert (aurSpellInfo); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + basePoints[i] = aurSpellInfo->EffectBasePoints[i]; + } + } + else + { + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + basePoints[i] = m_currentBasePoints[i]; + } + } + Unit * caster = m_originalCaster ? m_originalCaster : m_caster; - Aura * Aur = new Aura(m_spellInfo, aura_effmask, m_currentBasePoints, unit, m_caster, caster, m_CastItem); + Aura * Aur = new Aura(aurSpellInfo, aura_effmask, basePoints, unit, m_caster, caster, m_CastItem); if (!Aur->IsAreaAura()) { // Now Reduce spell duration using data received at spell hit int32 duration = Aur->GetAuraMaxDuration(); - int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup,m_spellInfo); + int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup,aurSpellInfo); unitTarget->ApplyDiminishingToDuration(m_diminishGroup, duration, m_caster, m_diminishLevel,limitduration); Aur->setDiminishGroup(m_diminishGroup); - duration = caster->ModSpellDuration(m_spellInfo, unit, duration, Aur->IsPositive()); + duration = caster->ModSpellDuration(aurSpellInfo, unit, duration, Aur->IsPositive()); //mod duration of channeled aura by spell haste if (IsChanneledSpell(m_spellInfo)) - caster->ModSpellCastTime(m_spellInfo, duration, this); + caster->ModSpellCastTime(aurSpellInfo, duration, this); if(duration != Aur->GetAuraMaxDuration()) { @@ -1294,9 +1352,9 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) } // Prayer of Mending (jump animation), we need formal caster instead original for correct animation - if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST) + if( aurSpellInfo->SpellFamilyName == SPELLFAMILY_PRIEST) { - if(m_spellInfo->SpellFamilyFlags[1] & 0x000020) + if(aurSpellInfo->SpellFamilyFlags[1] & 0x000020) m_caster->CastSpell(unit, 41637, true, NULL, NULL, m_originalCasterGUID); } } @@ -2486,6 +2544,27 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura } } + // Fill aura scaling information + if (m_caster->IsControlledByPlayer() && !IsPassiveSpell(m_spellInfo->Id) && m_spellInfo->spellLevel && !IsChanneledSpell(m_spellInfo) && !m_IsTriggeredSpell) + { + for (uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i) + { + if (m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA) + { + // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive + if (IsPositiveEffect(m_spellInfo->Id, i)) + { + m_auraScaleMask |= (1<<i); + if (m_currentBasePoints[i] != m_spellInfo->EffectBasePoints[i]) + { + m_auraScaleMask = 0; + break; + } + } + } + } + } + m_spellState = SPELL_STATE_PREPARING; if(triggeredByAura) @@ -2665,6 +2744,7 @@ void Spell::cast(bool skipCheck) && !target->IsFriendlyTo(m_caster) && !m_caster->canSeeOrDetect(target, true)) { SendCastResult(SPELL_FAILED_BAD_TARGETS); + SendInterrupted(0); finish(false); return; } @@ -2698,6 +2778,7 @@ void Spell::cast(bool skipCheck) if(castResult != SPELL_CAST_OK) { SendCastResult(castResult); + SendInterrupted(0); finish(false); SetExecutedCurrently(false); return; @@ -2706,6 +2787,14 @@ void Spell::cast(bool skipCheck) FillTargetMap(); + // Spell may be finished after target map check + if(m_spellState == SPELL_STATE_FINISHED) + { + SendInterrupted(0); + SetExecutedCurrently(false); + return; + } + if(m_spellInfo->SpellFamilyName) { if (m_spellInfo->excludeCasterAuraSpell && !IsPositiveSpell(m_spellInfo->excludeCasterAuraSpell)) @@ -3337,11 +3426,11 @@ void Spell::SendSpellGo() //sLog.outDebug("Sending SMSG_SPELL_GO id=%u", m_spellInfo->Id); uint32 castFlags = CAST_FLAG_UNKNOWN3; - + // triggered spells with spell visual != 0 if(m_IsTriggeredSpell || m_triggeredByAuraSpell) castFlags |= CAST_FLAG_UNKNOWN0; - + if(m_spellInfo->Attributes & SPELL_ATTR_REQ_AMMO) castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual if ((m_caster->GetTypeId() == TYPEID_PLAYER || @@ -4217,13 +4306,6 @@ SpellCastResult Spell::CheckCast(bool strict) if(!m_IsTriggeredSpell && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target)) return SPELL_FAILED_LINE_OF_SIGHT; - // auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode - // this case can be triggered if rank not found (too low-level target for first rank) - if(m_caster->GetTypeId() == TYPEID_PLAYER && !IsPassiveSpell(m_spellInfo->Id) && !m_CastItem) - for(int i=0;i<3;i++) - if(IsPositiveEffect(m_spellInfo->Id, i) && m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA) - if(target->getLevel() + 10 < m_spellInfo->spellLevel) - return SPELL_FAILED_LOWLEVEL; } else if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster { @@ -5922,7 +6004,7 @@ bool Spell::CheckTarget(Unit* target, uint32 eff) return false; } - //Do not check LOS for triggered spells + //Do not do further checks for triggered spells if(m_IsTriggeredSpell) return true; diff --git a/src/game/Spell.h b/src/game/Spell.h index 59f21fd6bae..21a73b2597a 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -568,9 +568,10 @@ class Spell SpellMissInfo reflectResult:8; uint8 effectMask:8; bool processed:1; - bool alive:1; + bool alive:1; + bool crit:1; + bool scaleAura:1; int32 damage; - bool crit; }; std::list<TargetInfo> m_UniqueTargetInfo; uint8 m_needAliveTargetMask; // Mask req. alive targets @@ -597,7 +598,7 @@ class Spell void AddGOTarget(uint64 goGUID, uint32 effIndex); void AddItemTarget(Item* target, uint32 effIndex); void DoAllEffectOnTarget(TargetInfo *target); - SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask); + SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura); void DoTriggersOnSpellHit(Unit *unit); void DoAllEffectOnTarget(GOTargetInfo *target); void DoAllEffectOnTarget(ItemTargetInfo *target); @@ -638,6 +639,7 @@ class Spell uint32 m_customAttr; bool m_skipCheck; uint32 m_effectMask; + uint8 m_auraScaleMask; #ifdef MAP_BASED_RAND_GEN int32 irand(int32 min, int32 max) { return int32 (m_caster->GetMap()->mtRand.randInt(max - min)) + min; } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index aa6db06f4a8..5503dce1b3d 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -4259,6 +4259,9 @@ void AuraEffect::HandleAuraModDecreaseSpeed(bool /*apply*/, bool Real, bool chan m_target->UpdateSpeed(MOVE_RUN, true); m_target->UpdateSpeed(MOVE_SWIM, true); m_target->UpdateSpeed(MOVE_FLIGHT, true); + m_target->UpdateSpeed(MOVE_RUN_BACK, true); + m_target->UpdateSpeed(MOVE_SWIM_BACK, true); + m_target->UpdateSpeed(MOVE_FLIGHT_BACK, true); } void AuraEffect::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real, bool changeAmount) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index e479c529d50..c92a75e4661 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -576,6 +576,8 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex, bool deep) switch(spellId) { + case 46392: // Focused Assault + case 46393: // Brutal Assault case 28441: // not positive dummy spell case 37675: // Chaos Blast case 41519: // Mark of Stormrage diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 393137833bb..e1ed8cb44b1 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -60,7 +60,7 @@ float baseMoveSpeed[MAX_MOVE_TYPE] = { 2.5f, // MOVE_WALK 7.0f, // MOVE_RUN - 1.25f, // MOVE_RUN_BACK + 3.0f, // MOVE_RUN_BACK 4.722222f, // MOVE_SWIM 4.5f, // MOVE_SWIM_BACK 3.141594f, // MOVE_TURN_RATE @@ -10860,6 +10860,11 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) switch(mtype) { + // Only apply debuffs + case MOVE_FLIGHT_BACK: + case MOVE_RUN_BACK: + case MOVE_SWIM_BACK: + break; case MOVE_WALK: return; case MOVE_RUN: @@ -10878,15 +10883,11 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) } break; } - case MOVE_RUN_BACK: - return; case MOVE_SWIM: { main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_SWIM_SPEED); break; } - case MOVE_SWIM_BACK: - return; case MOVE_FLIGHT: { if (GetTypeId()==TYPEID_UNIT && IsControlledByPlayer()) // not sure if good for pet @@ -10918,8 +10919,6 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) vehicle->UpdateSpeed(MOVE_FLIGHT, true); break; } - case MOVE_FLIGHT_BACK: - return; default: sLog.outError("Unit::UpdateSpeed: Unsupported move type (%d)", mtype); return; |