diff options
author | QAston <none@none> | 2009-08-17 02:53:39 +0200 |
---|---|---|
committer | QAston <none@none> | 2009-08-17 02:53:39 +0200 |
commit | 41c12d173b8d0cf297edf70e40b8e13b9bf3af35 (patch) | |
tree | 483b138dcad5abd803330495cc211c3a90218173 | |
parent | 6359bfb27ac42392dc3a314fc5fe194964485931 (diff) |
*Add spell_bonus_data for lightwell - by Elron
*Add aura_required, aura_forbidden, user_type columns to npc_spellclick_spells table for additional requirement checks
*Remove workarounds from lightwell code and use new npc_spellclick_spells fields instead.
--HG--
branch : trunk
-rw-r--r-- | sql/FULL/world_spell_full.sql | 36 | ||||
-rw-r--r-- | sql/updates/5119_world.sql | 17 | ||||
-rw-r--r-- | sql/world.sql | 4 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/world/npcs_special.cpp | 19 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 69 | ||||
-rw-r--r-- | src/game/ObjectMgr.h | 5 | ||||
-rw-r--r-- | src/game/Player.cpp | 2 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 14 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 70 | ||||
-rw-r--r-- | src/game/SpellHandler.cpp | 10 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 9 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 3 |
12 files changed, 144 insertions, 114 deletions
diff --git a/sql/FULL/world_spell_full.sql b/sql/FULL/world_spell_full.sql index 3b3f5a6e672..97833dd59c6 100644 --- a/sql/FULL/world_spell_full.sql +++ b/sql/FULL/world_spell_full.sql @@ -1715,6 +1715,7 @@ INSERT INTO `spell_bonus_data` (`entry`, `direct_bonus`, `dot_bonus`, `ap_bonus` (34433, 0.65, -1, -1, -1, 'Priest - Shadowfiend'), (585, 0.714, -1, -1, -1, 'Priest - Smite'), (34914, -1, 0.4, -1, -1, 'Priest - Vampiric Touch'), +(7001, -1, 0.3333, -1, -1, 'Priest - Lightwell Renew Rank 1'), (2818, -1, -1, -1, 0.03, 'Rogue - Deadly Poison Rank 1($AP*0.12 / number of ticks)'), (2819, -1, -1, -1, 0.03, 'Rogue - Deadly Poison Rank 2($AP*0.12 / number of ticks)'), (11353, -1, -1, -1, 0.03, 'Rogue - Deadly Poison Rank 3($AP*0.12 / number of ticks)'), @@ -2006,12 +2007,17 @@ INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `quest_start`, `qu (28606, 52263, 12680, 1, 12680, 1), (28607, 52263, 12680, 1, 12680, 1), (28782, 52280, 12687, 1, 12687, 1), -- Unbound Charger -(28833, 52447, 12701, 1, 12701, 1); -- Scarlet Cannon Master -# (28887, 52447, 12701, 1, 12701, 1); -- dead cannon - -UPDATE creature_template SET spell1=52435,spell2=52576,spell5=52588,VehicleId=79,speed=0 WHERE entry = 28833; -UPDATE `creature_template` SET vehicleid=138 WHERE (`entry`='28817'); -- mine car +(28833, 52447, 12701, 1, 12701, 1), -- Scarlet Cannon Master +(28887, 52447, 12701, 1, 12701, 1); +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN(31883, 31893, 31894, 31895, 31896, 31897); +INSERT INTO `npc_spellclick_spells` (npc_entry, spell_id, quest_start, quest_start_active, quest_end, cast_flags, aura_required, aura_forbidden, user_type) VALUES +(31883, 60123, 0, 0, 0, 0x2, 0, 48085, 2), +(31893, 60123, 0, 0, 0, 0x2, 0, 48084, 2), +(31894, 60123, 0, 0, 0, 0x2, 0, 28276, 2), +(31895, 60123, 0, 0, 0, 0x2, 0, 27874, 2), +(31896, 60123, 0, 0, 0, 0x2, 0, 27873, 2), +(31897, 60123, 0, 0, 0, 0x2, 0, 7001, 2); -- -------- -- NAXXARAMAS @@ -2128,22 +2134,4 @@ REPLACE INTO `npc_spellclick_spells` (npc_entry, spell_id, quest_start, quest_st (31894, 60123, 0, 0, 0, 2, 0), (31895, 60123, 0, 0, 0, 2, 0), (31896, 60123, 0, 0, 0, 2, 0), -(31897, 60123, 0, 0, 0, 2, 0); - - --- temp - -UPDATE `creature_template` SET `ScriptName`='boss_netherspite', `RegenHealth` = '1' WHERE `entry`='15689'; -UPDATE `creature_template` SET `faction_A` = '35', `faction_H` = '35', `modelid_A`='11686', `modelid_H`='11686', `unit_flags` = '33554496', `ScriptName` = '' WHERE `entry` IN ('17367','17368','17369'); -UPDATE `creature_template` SET `minlevel` = '70', `maxlevel` = '70',`flags_extra`= '2', `speed`= '0.0001', `faction_A` = '16', `faction_H` = '16', `ScriptName` = 'mob_eventai' WHERE `entry` = '16697'; -DELETE FROM `creature_ai_scripts` WHERE `creature_id` = '16697'; -INSERT INTO `creature_ai_scripts` -(`id`,`creature_id`,`event_type`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`comment`) VALUES -('1669701', '16697', '0', '100', '3', '3000', '3000', '3000', '3000', '11', '46264', '0', '2','Void Zone - Cast Void Zone Effect'), -('1669702', '16697', '1', '100', '3', '3000', '3000', '3000', '3000', '11', '46264', '0', '2','Void Zone - Cast Void Zone Effect'); -DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN ('-30421','-30422','-30423','38637','38638','38639'); -INSERT INTO `spell_linked_spell`(`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES -('-30421','38637','0','Netherspite\'s Perseverence'), -('-30422','38638','0','Netherspite\'s Serenity'), -('-30423','38639','0','Netherspite\'s Dominance'); -UPDATE `script_texts` SET `type` = '3' WHERE `entry` IN ('-1532089','-1532090');
\ No newline at end of file +(31897, 60123, 0, 0, 0, 2, 0);
\ No newline at end of file diff --git a/sql/updates/5119_world.sql b/sql/updates/5119_world.sql new file mode 100644 index 00000000000..03450749b90 --- /dev/null +++ b/sql/updates/5119_world.sql @@ -0,0 +1,17 @@ +ALTER TABLE `npc_spellclick_spells` DROP COLUMN `quest_status`; +ALTER TABLE `npc_spellclick_spells` ADD `aura_required` INT(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'player without aura cant click' AFTER `cast_flags`; +ALTER TABLE `npc_spellclick_spells` ADD `aura_forbidden` INT(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'player with aura cant click' AFTER `aura_required`; +ALTER TABLE `npc_spellclick_spells` ADD `user_type` SMALLINT(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'relation with summoner: 0-no 1-friendly 2-raid 3-party player can click' AFTER `aura_forbidden`; + +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN(31883, 31893, 31894, 31895, 31896, 31897); +INSERT INTO `npc_spellclick_spells` (npc_entry, spell_id, quest_start, quest_start_active, quest_end, cast_flags, aura_required, aura_forbidden, user_type) VALUES +(31883, 60123, 0, 0, 0, 0x2, 0, 48085, 2), +(31893, 60123, 0, 0, 0, 0x2, 0, 48084, 2), +(31894, 60123, 0, 0, 0, 0x2, 0, 28276, 2), +(31895, 60123, 0, 0, 0, 0x2, 0, 27874, 2), +(31896, 60123, 0, 0, 0, 0x2, 0, 27873, 2), +(31897, 60123, 0, 0, 0, 0x2, 0, 7001, 2); + +DELETE FROM `spell_bonus_data` WHERE `npc_entry` IN(7001); +REPLACE INTO `spell_bonus_data` (entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus, comments) VALUES +(7001, -1, 0.3333, -1, -1, 'Priest - Lightwell Renew Rank 1');
\ No newline at end of file diff --git a/sql/world.sql b/sql/world.sql index 21ae1fe7a35..d8b81c9897f 100644 --- a/sql/world.sql +++ b/sql/world.sql @@ -1892,7 +1892,9 @@ CREATE TABLE `npc_spellclick_spells` ( `spell_id` int(10) unsigned NOT NULL COMMENT 'spell which should be casted ', `quest_id` int(10) unsigned NOT NULL COMMENT 'reference to quest_template', `cast_flags` tinyint(3) unsigned NOT NULL COMMENT 'first bit defines caster: 1=player, 0=creature; second bit defines target, same mapping as caster bit', - `quest_status` int(11) unsigned NOT NULL default '3' COMMENT 'Quest status: 3 incompleted, 1 completed/rewarded' + `aura_required` int(11) unsigned NOT NULL default '0' COMMENT 'player without aura cant click', + `aura_forbidden` int(11) unsigned NOT NULL default '0' COMMENT 'player with aura cant click', + `user_type` smallint(3) unsigned NOT NULL default '0' COMMENT 'relation with summoner: 0-no 1-friendly 2-raid 3-party player can click' ) ENGINE=MyISAM DEFAULT CHARSET=utf8; SET character_set_client = @saved_cs_client; diff --git a/src/bindings/scripts/scripts/world/npcs_special.cpp b/src/bindings/scripts/scripts/world/npcs_special.cpp index ef826d4af3a..2fa1df0c128 100644 --- a/src/bindings/scripts/scripts/world/npcs_special.cpp +++ b/src/bindings/scripts/scripts/world/npcs_special.cpp @@ -1766,33 +1766,14 @@ CreatureAI* GetAI_npc_ebon_gargoyle(Creature* pCreature) return new npc_ebon_gargoyleAI (pCreature); } -//TODO: 30% Attackdamage check for Lightwell struct TRINITY_DLL_DECL npc_lightwellAI : public PassiveAI { npc_lightwellAI(Creature *c) : PassiveAI(c) {} - //uint32 desummon_timer; - void Reset() { - //desummon_timer = 180000; m_creature->CastSpell(m_creature, 59907, false); // Spell for Lightwell Charges } - - /* - void UpdateAI(const uint32 diff) - { - if (desummon_timer < diff) - { - m_creature->Kill(m_creature); - }else desummon_timer -= diff; - - if (!m_creature->HasAura(59907)) - { - m_creature->Kill(m_creature); - } - } - */ }; CreatureAI* GetAI_npc_lightwellAI(Creature* pCreature) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 8d5861bc72b..216ee2ece7c 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -110,7 +110,7 @@ LanguageDesc const* GetLanguageDescByID(uint32 lang) return NULL; } -bool SpellClickInfo::IsFitToRequirements(Player const* player) const +bool SpellClickInfo::IsFitToRequirements(Player const* player, Creature const * clickNpc) const { if(questStart) { @@ -126,6 +126,38 @@ bool SpellClickInfo::IsFitToRequirements(Player const* player) const return false; } + if (auraRequired) + if (!player->HasAura(auraRequired)) + return false; + + sLog.outError("Aura forbid: %d", auraForbidden); + if (auraForbidden) + if (player->HasAura(auraForbidden)) + return false; + + Unit const * summoner = NULL; + // Check summoners for party + if (clickNpc->isSummon()) + summoner = ((TempSummon*)clickNpc)->GetSummoner(); + if (!summoner) + summoner = clickNpc; + + switch (userType) + { + case SPELL_CLICK_USER_FRIEND: + if (!player->IsFriendlyTo(summoner)) + return false; + break; + case SPELL_CLICK_USER_RAID: + if (!player->IsInRaidWith(summoner)) + return false; + break; + case SPELL_CLICK_USER_PARTY: + if (!player->IsInPartyWith(summoner)) + return false; + break; + } + return true; } @@ -6642,8 +6674,8 @@ void ObjectMgr::LoadNPCSpellClickSpells() uint32 count = 0; mSpellClickInfoMap.clear(); - // 0 1 2 3 4 5 - QueryResult *result = WorldDatabase.Query("SELECT npc_entry, spell_id, quest_start, quest_start_active, quest_end, cast_flags FROM npc_spellclick_spells"); + // 0 1 2 3 4 5 6 7 8 + QueryResult *result = WorldDatabase.Query("SELECT npc_entry, spell_id, quest_start, quest_start_active, quest_end, cast_flags, aura_required, aura_forbidden, user_type FROM npc_spellclick_spells"); if(!result) { @@ -6682,6 +6714,28 @@ void ObjectMgr::LoadNPCSpellClickSpells() continue; } + uint32 auraRequired = fields[6].GetUInt32(); + if (auraRequired) + { + SpellEntry const *aurReqInfo = sSpellStore.LookupEntry(auraRequired); + if (!aurReqInfo) + { + sLog.outErrorDb("Table npc_spellclick_spells references unknown aura required %u. Skipping entry.", auraRequired); + continue; + } + } + + uint32 auraForbidden = fields[7].GetUInt32(); + if (auraForbidden) + { + SpellEntry const *aurForInfo = sSpellStore.LookupEntry(auraForbidden); + if (!aurForInfo) + { + sLog.outErrorDb("Table npc_spellclick_spells references unknown aura forbidden %u. Skipping entry.", auraForbidden); + continue; + } + } + uint32 quest_start = fields[2].GetUInt32(); // quest might be 0 to enable spellclick independent of any quest @@ -6692,7 +6746,6 @@ void ObjectMgr::LoadNPCSpellClickSpells() sLog.outErrorDb("Table npc_spellclick_spells references unknown start quest %u. Skipping entry.", quest_start); continue; } - } bool quest_start_active = fields[3].GetBool(); @@ -6706,9 +6759,12 @@ void ObjectMgr::LoadNPCSpellClickSpells() sLog.outErrorDb("Table npc_spellclick_spells references unknown end quest %u. Skipping entry.", quest_end); continue; } - } + uint8 userType = fields[8].GetUInt8(); + if (userType >= SPELL_CLICK_USER_MAX) + sLog.outErrorDb("Table npc_spellclick_spells references unknown user type %u. Skipping entry.", uint32(userType)); + uint8 castFlags = fields[5].GetUInt8(); SpellClickInfo info; info.spellId = spellid; @@ -6716,6 +6772,9 @@ void ObjectMgr::LoadNPCSpellClickSpells() info.questStartCanActive = quest_start_active; info.questEnd = quest_end; info.castFlags = castFlags; + info.auraRequired = auraRequired; + info.auraForbidden = auraForbidden; + info.userType = SpellClickUserTypes(castFlags); mSpellClickInfoMap.insert(SpellClickInfoMap::value_type(npc_entry, info)); // mark creature template as spell clickable diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index a3c39f18fc9..6624cc7e76d 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -106,9 +106,12 @@ struct SpellClickInfo uint32 questEnd; // quest end (quest don't must be rewarded for spell apply) bool questStartCanActive; // if true then quest start can be active (not only rewarded) uint8 castFlags; + uint32 auraRequired; + uint32 auraForbidden; + SpellClickUserTypes userType; // helpers - bool IsFitToRequirements(Player const* player) const; + bool IsFitToRequirements(Player const* player, Creature const * clickNpc) const; }; typedef std::multimap<uint32, SpellClickInfo> SpellClickInfoMap; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 40dc8b21c62..81e67126ca2 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -21297,7 +21297,7 @@ bool Player::canSeeSpellClickOn(Creature const *c) const return true; for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) - if(itr->second.IsFitToRequirements(this)) + if(itr->second.IsFitToRequirements(this, c)) return true; return false; diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 24d9a7be213..faf091e253a 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -456,6 +456,20 @@ enum SpellCategory #define MAX_TALENT_SPECS 2 #define MAX_GLYPH_SLOT_INDEX 6 +// Custom values +enum SpellClickUserTypes +{ + SPELL_CLICK_USER_ANY = 0, + SPELL_CLICK_USER_FRIEND = 1, + SPELL_CLICK_USER_RAID = 2, + SPELL_CLICK_USER_PARTY = 3, + SPELL_CLICK_USER_MAX = 4 +}; + +#define NPC_CLICK_CAST_CASTER_PLAYER 0x01 +#define NPC_CLICK_CAST_TARGET_PLAYER 0x02 +#define NPC_CLICK_CAST_ORIG_CASTER_OWNER 0x04 + enum SheathTypes { SHEATHETYPE_NONE = 0, diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 39eb470bc9c..fb54844430a 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5177,56 +5177,34 @@ void Spell::EffectScriptEffect(uint32 effIndex) if(Unit *passenger = ((Vehicle*)m_caster)->GetPassenger(0)) passenger->CastSpell(m_caster->m_Vehicle, damage, true); return; - case 60123: // Lightwell Renew, TODO: 30% Attackdamage check for Lightwell + case 60123: // Lightwell { - if(unitTarget && m_originalCaster) - { - Unit* owner = m_originalCaster->GetOwner(); - uint32 spell_heal; - uint32 spell_charges = 59907; + if (m_caster->GetTypeId() != TYPEID_UNIT || !((Creature*)m_caster)->isSummon()) + return; - switch(m_originalCaster->GetEntry()) - { - case 31897: spell_heal = 7001; break; - case 31896: spell_heal = 27873; break; - case 31895: spell_heal = 27874; break; - case 31894: spell_heal = 28276; break; - case 31893: spell_heal = 48084; break; - case 31883: spell_heal = 48085; break; - } + uint32 spell_heal; - if(owner && spell_heal && spell_charges) - { - if(owner->GetTypeId() == TYPEID_PLAYER && unitTarget->GetTypeId() == TYPEID_PLAYER) - { - if(((Player*)owner)->IsInSameRaidWith(((Player*)unitTarget)) && (!((Player*)unitTarget)->duel || unitTarget == owner) && !unitTarget->HasAura(spell_heal)) - { - Aura *chargesaura = m_originalCaster->GetAura(spell_charges); - if(chargesaura) - { - if(chargesaura->GetAuraCharges() > 1) - { - chargesaura->SetAuraCharges(chargesaura->GetAuraCharges() - 1); - owner->CastSpell(unitTarget, spell_heal, true); - if(unitTarget->IsPvP() && !owner->IsPvP()) - { - owner->SetPvP(true); - } - } - else - { - m_originalCaster->RemoveAura(chargesaura); - owner->CastSpell(unitTarget, spell_heal, true); - if(unitTarget->IsPvP() && !owner->IsPvP()) - { - owner->SetPvP(true); - } - } - } - } - } - } + switch(m_caster->GetEntry()) + { + case 31897: spell_heal = 7001; break; + case 31896: spell_heal = 27873; break; + case 31895: spell_heal = 27874; break; + case 31894: spell_heal = 28276; break; + case 31893: spell_heal = 48084; break; + case 31883: spell_heal = 48085; break; + default: + sLog.outError("Unknown Lightwell spell caster %u", m_caster->GetEntry()); + return; } + Aura * chargesaura = m_caster->GetAura(59907); + + if(chargesaura && chargesaura->GetAuraCharges() > 1) + { + chargesaura->SetAuraCharges(chargesaura->GetAuraCharges() - 1); + m_caster->CastSpell(unitTarget, spell_heal, true, NULL, NULL, ((TempSummon*)m_caster)->GetSummonerGUID()); + } + else + ((TempSummon*)m_caster)->UnSummon(); } } break; diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index dd88ef8e50a..ab338f932ab 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -525,12 +525,12 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data ) SpellClickInfoMapBounds clickPair = objmgr.GetSpellClickInfoMapBounds(unit->GetEntry()); for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) { - if(itr->second.IsFitToRequirements(_player)) + if(itr->second.IsFitToRequirements(_player, unit)) { - Unit *caster = (itr->second.castFlags & 0x1) ? (Unit*)_player : (Unit*)unit; - Unit *target = (itr->second.castFlags & 0x2) ? (Unit*)_player : (Unit*)unit; - - caster->CastSpell(target, itr->second.spellId, true); + Unit *caster = (itr->second.castFlags & NPC_CLICK_CAST_CASTER_PLAYER) ? (Unit*)_player : (Unit*)unit; + Unit *target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_PLAYER) ? (Unit*)_player : (Unit*)unit; + uint64 origCasterGUID = (itr->second.castFlags & NPC_CLICK_CAST_ORIG_CASTER_OWNER) ? unit->GetOwnerGUID() : 0; + caster->CastSpell(target, itr->second.spellId, true, NULL, NULL, origCasterGUID); } } diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 19b9a42b014..03626d9f7e7 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -3505,15 +3505,6 @@ void SpellMgr::LoadSpellCustomAttr() { switch(spellInfo->EffectApplyAuraName[j]) { - case SPELL_AURA_PERIODIC_DAMAGE: - case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: - case SPELL_AURA_PERIODIC_LEECH: - mSpellCustomAttr[i] |= SPELL_ATTR_CU_AURA_DOT; - break; - case SPELL_AURA_PERIODIC_HEAL: - case SPELL_AURA_OBS_MOD_HEALTH: - mSpellCustomAttr[i] |= SPELL_ATTR_CU_AURA_HOT; - break; case SPELL_AURA_MOD_ROOT: mSpellCustomAttr[i] |= SPELL_ATTR_CU_AURA_CC; mSpellCustomAttr[i] |= SPELL_ATTR_CU_MOVEMENT_IMPAIR; diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 6ba55bf7572..4bb966f16e3 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -709,10 +709,7 @@ inline bool IsProfessionSkill(uint32 skill) #define SPELL_ATTR_CU_CONE_BACK 0x00000002 #define SPELL_ATTR_CU_CONE_LINE 0x00000004 #define SPELL_ATTR_CU_SHARE_DAMAGE 0x00000008 -#define SPELL_ATTR_CU_AURA_HOT 0x00000010 -#define SPELL_ATTR_CU_AURA_DOT 0x00000020 #define SPELL_ATTR_CU_AURA_CC 0x00000040 -#define SPELL_ATTR_CU_AURA_SPELL 0x00000080 #define SPELL_ATTR_CU_DIRECT_DAMAGE 0x00000100 #define SPELL_ATTR_CU_CHARGE 0x00000200 #define SPELL_ATTR_CU_LINK_CAST 0x00000400 |