diff options
20 files changed, 155 insertions, 42 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index bbd5a70e933..d2ec0a94a2b 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1129,7 +1129,7 @@ DROP TABLE IF EXISTS `characters`; CREATE TABLE `characters` ( `guid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier', `account` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Account Identifier', - `name` varchar(12) NOT NULL DEFAULT '', + `name` varchar(12) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `race` tinyint(3) unsigned NOT NULL DEFAULT '0', `class` tinyint(3) unsigned NOT NULL DEFAULT '0', `gender` tinyint(3) unsigned NOT NULL DEFAULT '0', @@ -2276,4 +2276,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2012-03-25 21:14:19 +-- Dump completed on 2012-09-08 15:27:29 diff --git a/sql/updates/world/2012_09_08_01_world_creature_template.sql b/sql/updates/world/2012_09_08_01_world_creature_template.sql new file mode 100644 index 00000000000..fb34f345f2d --- /dev/null +++ b/sql/updates/world/2012_09_08_01_world_creature_template.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry` IN (32930,33909); -- Kologarn diff --git a/sql/updates/world/2012_09_08_02_world_achievement_criteria_data.sql b/sql/updates/world/2012_09_08_02_world_achievement_criteria_data.sql new file mode 100644 index 00000000000..2f25f6f20fa --- /dev/null +++ b/sql/updates/world/2012_09_08_02_world_achievement_criteria_data.sql @@ -0,0 +1,10 @@ +-- Criteria data for achievement 'Wrecking Ball' +DELETE FROM `disables` WHERE `sourceType`=4 AND `entry` IN (3368, 3369, 3370, 12578, 7623, 3371); +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (3368, 3369, 3370, 12578, 7623, 3371); +INSERT INTO `achievement_criteria_data`(`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +(3368,2,0,0,''), +(3369,2,0,0,''), +(3370,2,0,0,''), +(12578,2,0,0,''), +(7623,2,0,0,''), +(3371,2,0,0,''); diff --git a/sql/updates/world/2012_09_09_00_world_command.sql b/sql/updates/world/2012_09_09_00_world_command.sql new file mode 100644 index 00000000000..1fb3247bfbb --- /dev/null +++ b/sql/updates/world/2012_09_09_00_world_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` = 'start'; +DELETE FROM `command` WHERE `name` = 'unstuck'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('unstuck', 0, 'Syntax: .unstuck $playername [inn/graveyard/startzone]\n\nTeleports specified player to specified location. Default location is player\'s current hearth location.'); diff --git a/sql/updates/world/2012_09_09_01_world_trinity_string.sql b/sql/updates/world/2012_09_09_01_world_trinity_string.sql new file mode 100644 index 00000000000..2f3c0aa1938 --- /dev/null +++ b/sql/updates/world/2012_09_09_01_world_trinity_string.sql @@ -0,0 +1,3 @@ +DELETE FROM `trinity_string` WHERE `entry`=63; -- Existing entry 63 is not present in Language.h. It's safe to remove it. +INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES +(63, 'You can''t do that right now.'); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 808cbd9a5e4..c28ff21bfa5 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1707,6 +1707,11 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const float dy = y - GetPositionY(); float dz = z - GetPositionZ(); float dist = sqrt(dx*dx + dy*dy); + //! Check if the distance between the 2 objects is 0, can happen if both objects are on the same position. + //! The code below this check wont crash if dist is 0 because 0/0 in float operations is valid, and returns infinite + if (G3D::fuzzyEq(dist, 0.0f)) + return true; + float sinB = dx / dist; float cosB = dy / dist; dx = dist * (cosA * cosB + sinA * sinB); diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 2205efa8724..cc800dce7b8 100755 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2537,6 +2537,15 @@ GameObject* WorldObject::FindNearestGameObject(uint32 entry, float range) const return go; } +GameObject* WorldObject::FindNearestGameObjectOfType(GameobjectTypes type, float range) const +{ + GameObject* go = NULL; + Trinity::NearestGameObjectTypeInObjectRangeCheck checker(*this, type, range); + Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectTypeInObjectRangeCheck> searcher(this, go, checker); + VisitNearbyGridObject(range, searcher); + return go; +} + void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>& gameobjectList, uint32 entry, float maxSearchRange) const { CellCoord pair(Trinity::ComputeCellCoord(this->GetPositionX(), this->GetPositionY())); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index ab9ea2daea9..410903f6619 100755 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -799,6 +799,7 @@ class WorldObject : public Object, public WorldLocation Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const; GameObject* FindNearestGameObject(uint32 entry, float range) const; + GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const; void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& lList, uint32 uiEntry, float fMaxSearchRange) const; void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, uint32 uiEntry, float fMaxSearchRange) const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d8b20454321..dc3fe6b0f0b 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7913,6 +7913,9 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, -val, apply); m_spellPenetrationItemMod += apply ? val : -val; break; + case ITEM_MOD_BLOCK_VALUE: + HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(val), apply); + break; // deprecated item mods case ITEM_MOD_SPELL_HEALING_DONE: case ITEM_MOD_SPELL_DAMAGE_DONE: @@ -14723,7 +14726,7 @@ bool Player::CanSeeStartQuest(Quest const* quest) bool Player::CanTakeQuest(Quest const* quest, bool msg) { - return !DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this) + return !DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this) && SatisfyQuestStatus(quest, msg) && SatisfyQuestExclusiveGroup(quest, msg) && SatisfyQuestClass(quest, msg) && SatisfyQuestRace(quest, msg) && SatisfyQuestLevel(quest, msg) && SatisfyQuestSkill(quest, msg) && SatisfyQuestReputation(quest, msg) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f46ad17b033..4efdf3b6357 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -4367,10 +4367,10 @@ int32 Unit::GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) if ((*i)->GetMiscValue() & misc_mask) if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup)) modifier += (*i)->GetAmount(); - + for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr) modifier += itr->second; - + return modifier; } @@ -13235,13 +13235,13 @@ int32 Unit::ModSpellDuration(SpellInfo const* spellProto, Unit const* target, in } break; case SPELLFAMILY_PALADIN: - if (spellProto->SpellFamilyFlags[0] & 0x00000002) + if (spellProto->SpellFamilyFlags[0] & 0x00000002 && spellProto->SpellIconID == 298) { // Glyph of Blessing of Might if (AuraEffect* aurEff = GetAuraEffect(57958, 0)) duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS; } - else if (spellProto->SpellFamilyFlags[0] & 0x00010000) + else if (spellProto->SpellFamilyFlags[0] & 0x00010000 && spellProto->SpellIconID == 306) { // Glyph of Blessing of Wisdom if (AuraEffect* aurEff = GetAuraEffect(57979, 0)) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 3d58d5f4ce9..ecafc879b65 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -7301,6 +7301,11 @@ uint8 ObjectMgr::CheckPlayerName(const std::string& name, bool create) if (!isValidString(wname, strictMask, false, create)) return CHAR_NAME_MIXED_LANGUAGES; + wstrToLower(wname); + for (size_t i = 2; i < wname.size(); ++i) + if (wname[i] == wname[i-1] && wname[i] == wname[i-2]) + return CHAR_NAME_THREE_CONSECUTIVE; + return CHAR_NAME_SUCCESS; } diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 072db578220..db4dc819557 100755 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -694,6 +694,30 @@ namespace Trinity NearestGameObjectEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck const&); }; + // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO with a certain type) + class NearestGameObjectTypeInObjectRangeCheck + { + public: + NearestGameObjectTypeInObjectRangeCheck(WorldObject const& obj, GameobjectTypes type, float range) : i_obj(obj), i_type(type), i_range(range) {} + bool operator()(GameObject* go) + { + if (go->GetGoType() == i_type && i_obj.IsWithinDistInMap(go, i_range)) + { + i_range = i_obj.GetDistance(go); // use found GO range as new range limit for next check + return true; + } + return false; + } + float GetLastRange() const { return i_range; } + private: + WorldObject const& i_obj; + GameobjectTypes i_type; + float i_range; + + // prevent clone this object + NearestGameObjectTypeInObjectRangeCheck(NearestGameObjectTypeInObjectRangeCheck const&); + }; + class GameObjectWithDbGUIDCheck { public: diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index c294dd9b772..39704828d7f 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1308,12 +1308,29 @@ void WorldSession::HandleAlterAppearance(WorldPacket & recv_data) if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->getGender())) return; - uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor); + GameObject* go = _player->FindNearestGameObjectOfType(GAMEOBJECT_TYPE_BARBER_CHAIR, 5.0f); + if (!go) + { + WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); + data << uint32(2); + SendPacket(&data); + return; + } + + if (_player->getStandState() != UNIT_STAND_STATE_SIT_LOW_CHAIR + go->GetGOInfo()->barberChair.chairheight) + { + WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); + data << uint32(2); + SendPacket(&data); + return; + } + + uint32 cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor); // 0 - ok // 1, 3 - not enough money // 2 - you have to seat on barber chair - if (!_player->HasEnoughMoney(Cost)) + if (!_player->HasEnoughMoney(cost)) { WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); data << uint32(1); // no money @@ -1327,8 +1344,8 @@ void WorldSession::HandleAlterAppearance(WorldPacket & recv_data) SendPacket(&data); } - _player->ModifyMoney(-int32(Cost)); // it isn't free - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, Cost); + _player->ModifyMoney(-int32(cost)); // it isn't free + _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, cost); _player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id)); _player->SetByteValue(PLAYER_BYTES, 3, uint8(Color)); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index a766108dbb0..9c4f760fcff 100755 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -86,7 +86,8 @@ enum TrinityStrings LANG_CONNECTED_PLAYERS = 60, LANG_ACCOUNT_ADDON = 61, LANG_IMPROPER_VALUE = 62, - // Room for more level 0 63-99 not used + LANG_CANT_DO_NOW = 63, + // Room for more level 0 64-99 not used // level 1 chat LANG_GLOBAL_NOTIFY = 100, diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index a701b9d143e..3b4e72286d3 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -917,7 +917,7 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa { case TARGET_UNIT_CHANNEL_TARGET: { - WorldObject* target = ObjectAccessor::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID()); + WorldObject* target = ObjectAccessor::GetUnit(*m_caster, m_originalCaster->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT)); CallScriptObjectTargetSelectHandlers(target, effIndex); // unit target may be no longer avalible - teleported out of map for example if (target && target->ToUnit()) @@ -929,7 +929,7 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa case TARGET_DEST_CHANNEL_TARGET: if (channeledSpell->m_targets.HasDst()) m_targets.SetDst(channeledSpell->m_targets); - else if (WorldObject* target = ObjectAccessor::GetWorldObject(*m_caster, channeledSpell->m_targets.GetObjectTargetGUID())) + else if (WorldObject* target = ObjectAccessor::GetWorldObject(*m_caster, m_originalCaster->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT))) { CallScriptObjectTargetSelectHandlers(target, effIndex); if (target) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index d37ff1465bd..1141517bfe8 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1127,10 +1127,6 @@ bool SpellInfo::CanPierceImmuneAura(SpellInfo const* aura) const bool SpellInfo::CanDispelAura(SpellInfo const* aura) const { - // These auras (like ressurection sickness) can't be dispelled - if (aura->Attributes & SPELL_ATTR0_NEGATIVE_1) - return false; - // These spells (like Mass Dispel) can dispell all auras if (Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) return true; diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index fea96cc80f3..1778dc9be67 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -81,7 +81,7 @@ public: { "save", SEC_PLAYER, false, &HandleSaveCommand, "", NULL }, { "saveall", SEC_MODERATOR, true, &HandleSaveAllCommand, "", NULL }, { "kick", SEC_GAMEMASTER, true, &HandleKickPlayerCommand, "", NULL }, - { "start", SEC_PLAYER, false, &HandleStartCommand, "", NULL }, + { "unstuck", SEC_PLAYER, true, &HandleUnstuckCommand, "", NULL }, { "linkgrave", SEC_ADMINISTRATOR, false, &HandleLinkGraveCommand, "", NULL }, { "neargrave", SEC_ADMINISTRATOR, false, &HandleNearGraveCommand, "", NULL }, { "showarea", SEC_ADMINISTRATOR, false, &HandleShowAreaCommand, "", NULL }, @@ -928,34 +928,68 @@ public: return true; } - static bool HandleStartCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleUnstuckCommand(ChatHandler* handler, char const* args) { - Player* player = handler->GetSession()->GetPlayer(); + //No args required for players + if (handler->GetSession() && AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) + { + Player* player = handler->GetSession()->GetPlayer(); + if (player->isInFlight() || player->isInCombat()) + { + handler->SendSysMessage(LANG_CANT_DO_NOW); + handler->SetSentErrorMessage(true); + return false; + } - if (player->isInFlight()) + //7355: "Stuck" + player->CastSpell(player, 7355, false); + return true; + } + + if (!*args) + return false; + + char* player_str = strtok((char*)args, " "); + if (!player_str) + return false; + + char* location_str = strtok(NULL, ""); + if (!location_str) + location_str = "inn"; + + Player* player = NULL; + std::string playerName; + if (!handler->extractPlayerTarget((char*)player_str, &player, NULL, &playerName)) + return false; + + if (player->isInFlight() || player->isInCombat()) { - handler->SendSysMessage(LANG_YOU_IN_FLIGHT); + handler->SendSysMessage(LANG_CANT_DO_NOW); handler->SetSentErrorMessage(true); return false; } - if (player->isInCombat()) + if (!stricmp(location_str, "inn")) { - handler->SendSysMessage(LANG_YOU_IN_COMBAT); - handler->SetSentErrorMessage(true); - return false; + player->TeleportTo(player->m_homebindMapId, player->m_homebindX, player->m_homebindY, player->m_homebindZ, player->GetOrientation()); + return true; } - if (player->isDead() || player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + if (!stricmp(location_str, "graveyard")) { - // if player is dead and stuck, send ghost to graveyard player->RepopAtGraveyard(); return true; } - // cast spell Stuck - player->CastSpell(player, 7355, false); - return true; + if (!stricmp(location_str, "startzone")) + { + player->TeleportTo(player->GetStartPosition()); + return true; + } + + //Not a supported argument + return false; + } static bool HandleLinkGraveCommand(ChatHandler* handler, char const* args) diff --git a/src/server/scripts/Kalimdor/ashenvale.cpp b/src/server/scripts/Kalimdor/ashenvale.cpp index 248932ecbb6..6a9dd77433a 100644 --- a/src/server/scripts/Kalimdor/ashenvale.cpp +++ b/src/server/scripts/Kalimdor/ashenvale.cpp @@ -447,7 +447,7 @@ class npc_muglash : public CreatureScript DoScriptText(SAY_MUG_START1, creature); creature->setFaction(113); - pEscortAI->Start(true, true, player->GetGUID()); + pEscortAI->Start(true, false, player->GetGUID()); } } return true; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp index ea51f07dbe3..87e7801566e 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp @@ -330,7 +330,7 @@ public: me->DespawnOrUnsummon(); } - void UpdateAI(uint32 const diff) {} + void UpdateAI(uint32 const /*diff*/) {} }; }; @@ -441,7 +441,7 @@ public: me->DespawnOrUnsummon(); } - void UpdateAI(uint32 const diff) {} + void UpdateAI(uint32 const /*diff*/) {} }; }; diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index a48661d4aed..0def62b7d3a 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -679,38 +679,38 @@ class spell_warl_health_funnel : public SpellScriptLoader { public: spell_warl_health_funnel() : SpellScriptLoader("spell_warl_health_funnel") { } - + class spell_warl_health_funnel_AuraScript : public AuraScript { - PrepareAuraScript(spell_warl_health_funnel_AuraScript) - + PrepareAuraScript(spell_warl_health_funnel_AuraScript); + void ApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* caster = GetCaster(); if (!caster) return; - + Unit* target = GetTarget(); if (caster->HasAura(WARLOCK_IMPROVED_HEALTH_FUNNEL_R2)) target->CastSpell(target, WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2, true); else if (caster->HasAura(WARLOCK_IMPROVED_HEALTH_FUNNEL_R1)) target->CastSpell(target, WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R1, true); } - + void RemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); target->RemoveAurasDueToSpell(WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R1); target->RemoveAurasDueToSpell(WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2); } - + void Register() { OnEffectRemove += AuraEffectRemoveFn(spell_warl_health_funnel_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL); OnEffectApply += AuraEffectApplyFn(spell_warl_health_funnel_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL); } }; - + AuraScript* GetAuraScript() const { return new spell_warl_health_funnel_AuraScript(); |