*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
This commit is contained in:
QAston
2009-08-17 02:53:39 +02:00
parent 6359bfb27a
commit 41c12d173b
12 changed files with 145 additions and 115 deletions
+64 -5
View File
@@ -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
+4 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+14
View File
@@ -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,
+25 -47
View File
@@ -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)
if (m_caster->GetTypeId() != TYPEID_UNIT || !((Creature*)m_caster)->isSummon())
return;
uint32 spell_heal;
switch(m_caster->GetEntry())
{
Unit* owner = m_originalCaster->GetOwner();
uint32 spell_heal;
uint32 spell_charges = 59907;
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;
}
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);
}
}
}
}
}
}
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;
+5 -5
View File
@@ -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);
}
}
-9
View File
@@ -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;
-3
View File
@@ -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