aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.cpp52
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.h13
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp11
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp81
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp89
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.h5
6 files changed, 107 insertions, 144 deletions
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 04a787d88ec..550814ccf3f 100755
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -299,6 +299,7 @@ uint32 Condition::GetMaxAvailableConditionTargets()
case CONDITION_SOURCE_TYPE_SPELL:
case CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE:
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
+ case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT:
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
case CONDITION_SOURCE_TYPE_SMART_EVENT:
@@ -409,17 +410,34 @@ ConditionList ConditionMgr::GetConditionsForNotGroupedEntry(ConditionSourceType
return spellCond;
}
-ConditionList ConditionMgr::GetConditionsForVehicleSpell(uint32 creatureID, uint32 spellID)
+
+ConditionList ConditionMgr::GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId)
+{
+ ConditionList cond;
+ CreatureSpellConditionContainer::const_iterator itr = SpellClickEventConditionStore.find(creatureId);
+ if (itr != SpellClickEventConditionStore.end())
+ {
+ ConditionTypeContainer::const_iterator i = (*itr).second.find(spellId);
+ if (i != (*itr).second.end())
+ {
+ cond = (*i).second;
+ sLog->outDebug(LOG_FILTER_CONDITIONSYS, "GetConditionsForSpellClickEvent: found conditions for Vehicle entry %u spell %u", creatureId, spellId);
+ }
+ }
+ return cond;
+}
+
+ConditionList ConditionMgr::GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId)
{
ConditionList cond;
- VehicleSpellConditionContainer::const_iterator itr = VehicleSpellConditionStore.find(creatureID);
+ CreatureSpellConditionContainer::const_iterator itr = VehicleSpellConditionStore.find(creatureId);
if (itr != VehicleSpellConditionStore.end())
{
- ConditionTypeContainer::const_iterator i = (*itr).second.find(spellID);
+ ConditionTypeContainer::const_iterator i = (*itr).second.find(spellId);
if (i != (*itr).second.end())
{
cond = (*i).second;
- sLog->outDebug(LOG_FILTER_CONDITIONSYS, "GetConditionsForVehicleSpell: found conditions for Vehicle entry %u spell %u", creatureID, spellID);
+ sLog->outDebug(LOG_FILTER_CONDITIONSYS, "GetConditionsForVehicleSpell: found conditions for Vehicle entry %u spell %u", creatureId, spellId);
}
}
return cond;
@@ -1073,9 +1091,19 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
return false;
}
break;
- case CONDITION_SOURCE_TYPE_UNUSED_18:
- sLog->outErrorDb("Found SourceTypeOrReferenceId = CONDITION_SOURCE_TYPE_UNUSED_18 in `conditions` table - ignoring");
- return false;
+ case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT:
+ if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
+ {
+ sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup);
+ return false;
+ }
+
+ if (!sSpellMgr->GetSpellInfo(cond->SourceEntry))
+ {
+ sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
+ return false;
+ }
+ break;
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
case CONDITION_SOURCE_TYPE_SMART_EVENT:
@@ -1110,7 +1138,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
return false;
}
- if (cond->ConditionValue2 > 2)
+ if (cond->ConditionValue2 > EFFECT_2)
{
sLog->outErrorDb("Aura condition has non existing effect index (%u) (must be 0..2), skipped", cond->ConditionValue2);
return false;
@@ -1574,13 +1602,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_19 in `conditions` table - ignoring");
return false;
case CONDITION_UNUSED_20:
- sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_19 in `conditions` table - ignoring");
+ sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_20 in `conditions` table - ignoring");
return false;
case CONDITION_UNUSED_21:
- sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_19 in `conditions` table - ignoring");
+ sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_21 in `conditions` table - ignoring");
return false;
case CONDITION_UNUSED_24:
- sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_19 in `conditions` table - ignoring");
+ sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_24 in `conditions` table - ignoring");
return false;
default:
break;
@@ -1612,7 +1640,7 @@ void ConditionMgr::Clean()
ConditionStore.clear();
- for (VehicleSpellConditionContainer::iterator itr = VehicleSpellConditionStore.begin(); itr != VehicleSpellConditionStore.end(); ++itr)
+ for (CreatureSpellConditionContainer::iterator itr = VehicleSpellConditionStore.begin(); itr != VehicleSpellConditionStore.end(); ++itr)
{
for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
{
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 79a2122ae29..9911aa2a98a 100755
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -92,7 +92,7 @@ enum ConditionSourceType
CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION = 15,
CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE = 16,
CONDITION_SOURCE_TYPE_SPELL = 17,
- CONDITION_SOURCE_TYPE_UNUSED_18 = 18,
+ CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT = 18,
CONDITION_SOURCE_TYPE_QUEST_ACCEPT = 19,
CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK = 20,
CONDITION_SOURCE_TYPE_VEHICLE_SPELL = 21,
@@ -167,7 +167,7 @@ struct Condition
ConditionValue2 = 0;
ConditionValue3 = 0;
ReferenceId = 0;
- ErrorTextId = 0;
+ ErrorTextId = 0;
ScriptId = 0;
NegativeCondition = false;
}
@@ -180,7 +180,7 @@ struct Condition
typedef std::list<Condition*> ConditionList;
typedef std::map<uint32, ConditionList> ConditionTypeContainer;
typedef std::map<ConditionSourceType, ConditionTypeContainer> ConditionContainer;
-typedef std::map<uint32, ConditionTypeContainer> VehicleSpellConditionContainer;
+typedef std::map<uint32, ConditionTypeContainer> CreatureSpellConditionContainer;
typedef std::map<std::pair<int32, uint32 /*SAI source_type*/>, ConditionTypeContainer> SmartEventConditionContainer;
typedef std::map<uint32, ConditionList> ConditionReferenceContainer;//only used for references
@@ -202,8 +202,9 @@ class ConditionMgr
bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions);
bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry);
+ ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId);
ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType);
- ConditionList GetConditionsForVehicleSpell(uint32 creatureID, uint32 spellID);
+ ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId);
private:
bool isSourceTypeValid(Condition* cond);
@@ -228,6 +229,7 @@ class ConditionMgr
sourceType == CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU ||
sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION ||
+ sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT ||
sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL ||
sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
}
@@ -237,7 +239,8 @@ class ConditionMgr
ConditionContainer ConditionStore;
ConditionReferenceContainer ConditionReferenceStore;
- VehicleSpellConditionContainer VehicleSpellConditionStore;
+ CreatureSpellConditionContainer VehicleSpellConditionStore;
+ CreatureSpellConditionContainer SpellClickEventConditionStore;
SmartEventConditionContainer SmartEventConditionStore;
};
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 5503cd007ad..12387d2ca6c 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -22365,7 +22365,16 @@ void Player::UpdateForQuestWorldObjects()
SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(obj->GetEntry());
for (SpellClickInfoContainer::const_iterator _itr = clickPair.first; _itr != clickPair.second; ++_itr)
- if (_itr->second.questStart || _itr->second.questEnd)
+ {
+ //! This code doesn't look right, but it was logically converted to condition system to do the exact
+ //! same thing it did before. It definitely needs to be overlooked for intended functionality.
+ ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(obj->GetEntry(), _itr->second.spellId);
+ bool buildUpdateBlock = false;
+ for (ConditionList::const_iterator jtr = conds.begin(); jtr != conds.end() && !buildUpdateBlock; ++jtr)
+ if ((*jtr)->ConditionType == CONDITION_QUESTREWARDED || (*jtr)->ConditionType == CONDITION_QUESTTAKEN)
+ buildUpdateBlock = true;
+
+ if (buildUpdateBlock)
{
obj->BuildCreateUpdateBlockForPlayer(&udata, this);
break;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index d4a702bd3cf..6c566fe9ed8 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -55,6 +55,7 @@
#include "SpellInfo.h"
#include "MoveSplineInit.h"
#include "MoveSpline.h"
+#include "ConditionMgr.h"
#include <math.h>
@@ -16870,57 +16871,61 @@ void Unit::JumpTo(WorldObject* obj, float speedZ)
bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
{
- bool success = false;
uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->GetCreatureEntry() : GetEntry();
SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry);
for (SpellClickInfoContainer::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
{
- if (itr->second.IsFitToRequirements(clicker, this))
- {
- Unit* caster = (itr->second.castFlags & NPC_CLICK_CAST_CASTER_CLICKER) ? clicker : this;
- Unit* target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_CLICKER) ? clicker : this;
- uint64 origCasterGUID = (itr->second.castFlags & NPC_CLICK_CAST_ORIG_CASTER_OWNER) ? GetOwnerGUID() : clicker->GetGUID();
+ //! First check simple relations from clicker to clickee
+ if (!itr->second.IsFitToRequirements(clicker, this))
+ return false;
- SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(itr->second.spellId);
- // if (!spellEntry) should be checked at npc_spellclick load
+ //! Check database conditions
+ ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(spellClickEntry, itr->second.spellId);
+ ConditionSourceInfo info = ConditionSourceInfo(clicker, this);
+ if (!sConditionMgr->IsObjectMeetToConditions(info, conds))
+ return false;
- if (seatId > -1)
- {
- uint8 i = 0;
- bool valid = false;
- while (i < MAX_SPELL_EFFECTS && !valid)
- {
- if (spellEntry->Effects[i].ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE)
- {
- valid = true;
- break;
- }
- ++i;
- }
+ Unit* caster = (itr->second.castFlags & NPC_CLICK_CAST_CASTER_CLICKER) ? clicker : this;
+ Unit* target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_CLICKER) ? clicker : this;
+ uint64 origCasterGUID = (itr->second.castFlags & NPC_CLICK_CAST_ORIG_CASTER_OWNER) ? GetOwnerGUID() : clicker->GetGUID();
- if (!valid)
- {
- sLog->outErrorDb("Spell %u specified in npc_spellclick_spells is not a valid vehicle enter aura!", itr->second.spellId);
- return false;
- }
+ SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(itr->second.spellId);
+ // if (!spellEntry) should be checked at npc_spellclick load
- if (IsInMap(caster))
- caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, true, NULL, NULL, origCasterGUID);
- else // This can happen during Player::_LoadAuras
+ if (seatId > -1)
+ {
+ uint8 i = 0;
+ bool valid = false;
+ while (i < MAX_SPELL_EFFECTS && !valid)
+ {
+ if (spellEntry->Effects[i].ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE)
{
- int32 bp0 = seatId;
- Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, &bp0, NULL, origCasterGUID);
+ valid = true;
+ break;
}
+ ++i;
}
- else
+
+ if (!valid)
{
- if (IsInMap(caster))
- caster->CastSpell(target, spellEntry, true, NULL, NULL, origCasterGUID);
- else
- Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, NULL, NULL, origCasterGUID);
+ sLog->outErrorDb("Spell %u specified in npc_spellclick_spells is not a valid vehicle enter aura!", itr->second.spellId);
+ return false;
}
- success = true;
+ if (IsInMap(caster))
+ caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, true, NULL, NULL, origCasterGUID);
+ else // This can happen during Player::_LoadAuras
+ {
+ int32 bp0 = seatId;
+ Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, &bp0, NULL, origCasterGUID);
+ }
+ }
+ else
+ {
+ if (IsInMap(caster))
+ caster->CastSpell(target, spellEntry, true, NULL, NULL, origCasterGUID);
+ else
+ Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, NULL, NULL, origCasterGUID);
}
}
@@ -16928,7 +16933,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
if (creature && creature->IsAIEnabled)
creature->AI()->DoAction(EVENT_SPELLCLICK);
- return success;
+ return true;
}
void Unit::EnterVehicle(Unit* base, int8 seatId)
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index d9fc0d9e012..f50d4144b62 100755
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -194,30 +194,8 @@ LanguageDesc const* GetLanguageDescByID(uint32 lang)
bool SpellClickInfo::IsFitToRequirements(Unit const* clicker, Unit const* clickee) const
{
Player const* playerClicker = clicker->ToPlayer();
- if (playerClicker)
- {
- if (questStart)
- {
- // not in expected required quest state
- if ((!questStartCanActive || !playerClicker->IsActiveQuest(questStart)) && !playerClicker->GetQuestRewardStatus(questStart))
- return false;
- }
-
- if (questEnd)
- {
- // not in expected forbidden quest state
- if (playerClicker->GetQuestRewardStatus(questEnd))
- return false;
- }
- }
-
- if (auraRequired)
- if (!clicker->HasAura(auraRequired))
- return false;
-
- if (auraForbidden)
- if (clicker->HasAura(auraForbidden))
- return false;
+ if (!playerClicker)
+ return true;
Unit const* summoner = NULL;
// Check summoners for party
@@ -226,9 +204,6 @@ bool SpellClickInfo::IsFitToRequirements(Unit const* clicker, Unit const* clicke
if (!summoner)
summoner = clickee;
- if (!playerClicker)
- return true;
-
// This only applies to players
switch (userType)
{
@@ -7117,8 +7092,8 @@ void ObjectMgr::LoadNPCSpellClickSpells()
uint32 oldMSTime = getMSTime();
_spellClickInfoStore.clear();
- // 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");
+ // 0 1 2 3
+ QueryResult result = WorldDatabase.Query("SELECT npc_entry, spell_id, cast_flags, user_type FROM npc_spellclick_spells");
if (!result)
{
@@ -7149,66 +7124,14 @@ void ObjectMgr::LoadNPCSpellClickSpells()
continue;
}
- uint32 auraRequired = fields[6].GetUInt32();
- if (auraRequired)
- {
- SpellInfo const* aurReqInfo = sSpellMgr->GetSpellInfo(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)
- {
- SpellInfo const* aurForInfo = sSpellMgr->GetSpellInfo(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
- if (quest_start)
- {
- if (_questTemplates.find(quest_start) == _questTemplates.end())
- {
- sLog->outErrorDb("Table npc_spellclick_spells references unknown start quest %u. Skipping entry.", quest_start);
- continue;
- }
- }
-
- bool quest_start_active = fields[3].GetBool();
-
- uint32 quest_end = fields[4].GetUInt32();
- // quest might be 0 to enable spellclick active infinity after start quest
- if (quest_end)
- {
- if (_questTemplates.find(quest_end) == _questTemplates.end())
- {
- sLog->outErrorDb("Table npc_spellclick_spells references unknown end quest %u. Skipping entry.", quest_end);
- continue;
- }
- }
-
- uint8 userType = fields[8].GetUInt8();
+ uint8 userType = fields[3].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();
+ uint8 castFlags = fields[2].GetUInt8();
SpellClickInfo info;
info.spellId = spellid;
- info.questStart = quest_start;
- info.questStartCanActive = quest_start_active;
- info.questEnd = quest_end;
info.castFlags = castFlags;
- info.auraRequired = auraRequired;
- info.auraForbidden = auraForbidden;
info.userType = SpellClickUserTypes(userType);
_spellClickInfoStore.insert(SpellClickInfoContainer::value_type(npc_entry, info));
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index fc342bfb534..4224f1e2bfd 100755
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -337,12 +337,7 @@ std::string GetScriptCommandName(ScriptCommands command);
struct SpellClickInfo
{
uint32 spellId;
- uint32 questStart; // quest start (quest must be active or rewarded for spell apply)
- uint32 questEnd; // quest end (quest must not 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