aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMeji <alvaromegias_46@hotmail.com>2021-12-04 14:42:54 +0100
committerGitHub <noreply@github.com>2021-12-04 14:42:54 +0100
commit0d0f9784a92245879c1e98b011dc112b1b8bb76b (patch)
tree5e409b1f15cdc0c8264dc2951b7397238cd5f3c6
parent04a6c55a1165524024db8ca357fcc5a70bc54245 (diff)
Core/Conditions: Added CONDITION_SOURCE_TYPE_TRAINER_SPELL (#27321)
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp76
-rw-r--r--src/server/game/Conditions/ConditionMgr.h5
-rw-r--r--src/server/game/Entities/Creature/Trainer.cpp9
-rw-r--r--src/server/game/Entities/Creature/Trainer.h2
4 files changed, 77 insertions, 15 deletions
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 1c5c294d9c1..dcb67d0f631 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -80,7 +80,9 @@ char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX]
"Phase",
"Graveyard",
"AreaTrigger",
- "ConversationLine"
+ "ConversationLine",
+ "AreaTrigger Client Triggered",
+ "Trainer Spell"
};
ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[CONDITION_MAX] =
@@ -951,7 +953,8 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType)
sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT ||
sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR ||
sourceType == CONDITION_SOURCE_TYPE_PHASE ||
- sourceType == CONDITION_SOURCE_TYPE_AREATRIGGER);
+ sourceType == CONDITION_SOURCE_TYPE_AREATRIGGER ||
+ sourceType == CONDITION_SOURCE_TYPE_TRAINER_SPELL);
}
bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType)
@@ -1060,7 +1063,7 @@ bool ConditionMgr::IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32
ConditionsByEntryMap::const_iterator i = (*itr).second.find(itemId);
if (i != (*itr).second.end())
{
- TC_LOG_DEBUG("condition", "GetConditionsForNpcVendorEvent: found conditions for creature entry %u item %u", creatureId, itemId);
+ TC_LOG_DEBUG("condition", "GetConditionsForNpcVendor: found conditions for creature entry %u item %u", creatureId, itemId);
ConditionSourceInfo sourceInfo(player, vendor);
return IsObjectMeetToConditions(sourceInfo, i->second);
}
@@ -1073,6 +1076,21 @@ ConditionContainer const* ConditionMgr::GetConditionsForAreaTrigger(uint32 areaT
return Trinity::Containers::MapGetValuePtr(AreaTriggerConditionContainerStore, { areaTriggerId, isServerSide });
}
+bool ConditionMgr::IsObjectMeetingTrainerSpellConditions(uint32 trainerId, uint32 spellId, Player* player) const
+{
+ ConditionEntriesByCreatureIdMap::const_iterator itr = TrainerSpellConditionContainerStore.find(trainerId);
+ if (itr != TrainerSpellConditionContainerStore.end())
+ {
+ ConditionsByEntryMap::const_iterator i = (*itr).second.find(spellId);
+ if (i != (*itr).second.end())
+ {
+ TC_LOG_DEBUG("condition", "GetConditionsForTrainerSpell: found conditions for trainer id %u spell %u", trainerId, spellId);
+ return IsObjectMeetToConditions(player, i->second);
+ }
+ }
+ return true;
+}
+
ConditionMgr* ConditionMgr::instance()
{
static ConditionMgr instance;
@@ -1316,6 +1334,13 @@ void ConditionMgr::LoadConditions(bool isReload)
++count;
continue;
}
+ case CONDITION_SOURCE_TYPE_TRAINER_SPELL:
+ {
+ TrainerSpellConditionContainerStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
+ valid = true;
+ ++count;
+ continue;
+ }
default:
break;
}
@@ -1769,7 +1794,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cond->SourceEntry, DIFFICULTY_NONE);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table does not exist in `Spell.db2`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1836,7 +1861,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const
SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cond->SourceEntry, DIFFICULTY_NONE);
if (!spellProto)
{
- TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table does not exist in `Spell.db2`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1851,26 +1876,26 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
if (!sSpellMgr->GetSpellInfo(cond->SourceEntry, DIFFICULTY_NONE))
{
- TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table does not exist in `Spell.db2`, ignoring.", cond->ToString().c_str());
return false;
}
break;
case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT:
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
if (!sSpellMgr->GetSpellInfo(cond->SourceEntry, DIFFICULTY_NONE))
{
- TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table does not exist in `Spell.db2`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1878,7 +1903,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const
{
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(cond->SourceEntry);
@@ -1893,7 +1918,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const
{
if (!sMapStore.LookupEntry(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in Map.dbc, ignoring.", cond->ToString().c_str());
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in Map.db2, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1902,7 +1927,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const
{
if (cond->SourceEntry && !sAreaTableStore.LookupEntry(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in AreaTable.dbc, ignoring.", cond->ToString().c_str());
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in AreaTable.db2, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1944,6 +1969,20 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const
return false;
}
break;
+ case CONDITION_SOURCE_TYPE_TRAINER_SPELL:
+ {
+ if (!sObjectMgr->GetTrainer(cond->SourceGroup))
+ {
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `trainer`, ignoring.", cond->ToString().c_str());
+ return false;
+ }
+ if (!sSpellMgr->GetSpellInfo(cond->SourceEntry, DIFFICULTY_NONE))
+ {
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table does not exist in `Spell.db2`, ignoring.", cond->ToString().c_str());
+ return false;
+ }
+ break;
+ }
default:
TC_LOG_ERROR("sql.sql", "%s Invalid ConditionSourceType in `condition` table, ignoring.", cond->ToString().c_str());
return false;
@@ -2517,6 +2556,19 @@ void ConditionMgr::Clean()
NpcVendorConditionContainerStore.clear();
+ for (ConditionEntriesByAreaTriggerIdMap::iterator itr = AreaTriggerConditionContainerStore.begin(); itr != AreaTriggerConditionContainerStore.end(); ++itr)
+ for (ConditionContainer::const_iterator i = itr->second.begin(); i != itr->second.end(); ++i)
+ delete *i;
+
+ AreaTriggerConditionContainerStore.clear();
+
+ for (ConditionEntriesByCreatureIdMap::iterator itr = TrainerSpellConditionContainerStore.begin(); itr != TrainerSpellConditionContainerStore.end(); ++itr)
+ for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
+ delete *i;
+
+ TrainerSpellConditionContainerStore.clear();
+
// this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
for (std::vector<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr)
delete *itr;
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index d4f3bf8a188..1085adef996 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -172,7 +172,8 @@ enum ConditionSourceType
CONDITION_SOURCE_TYPE_AREATRIGGER = 28,
CONDITION_SOURCE_TYPE_CONVERSATION_LINE = 29,
CONDITION_SOURCE_TYPE_AREATRIGGER_CLIENT_TRIGGERED = 30,
- CONDITION_SOURCE_TYPE_MAX = 31 // MAX
+ CONDITION_SOURCE_TYPE_TRAINER_SPELL = 31,
+ CONDITION_SOURCE_TYPE_MAX = 32 // MAX
};
enum RelationType
@@ -292,6 +293,7 @@ class TC_GAME_API ConditionMgr
bool IsObjectMeetingSmartEventConditions(int64 entryOrGuid, uint32 eventId, uint32 sourceType, Unit* unit, WorldObject* baseObject) const;
bool IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32 itemId, Player* player, Creature* vendor) const;
ConditionContainer const* GetConditionsForAreaTrigger(uint32 areaTriggerId, bool isServerSide) const;
+ bool IsObjectMeetingTrainerSpellConditions(uint32 trainerId, uint32 spellId, Player* player) const;
static uint32 GetPlayerConditionLfgValue(Player const* player, PlayerConditionLfgStatus status);
static bool IsPlayerMeetingCondition(Player const* player, PlayerConditionEntry const* condition);
@@ -328,6 +330,7 @@ class TC_GAME_API ConditionMgr
ConditionEntriesByCreatureIdMap NpcVendorConditionContainerStore;
SmartEventConditionContainer SmartEventConditionStore;
ConditionEntriesByAreaTriggerIdMap AreaTriggerConditionContainerStore;
+ ConditionEntriesByCreatureIdMap TrainerSpellConditionContainerStore;
};
#define sConditionMgr ConditionMgr::instance()
diff --git a/src/server/game/Entities/Creature/Trainer.cpp b/src/server/game/Entities/Creature/Trainer.cpp
index 2e72b87f7a4..dcdd28edb19 100644
--- a/src/server/game/Entities/Creature/Trainer.cpp
+++ b/src/server/game/Entities/Creature/Trainer.cpp
@@ -18,6 +18,7 @@
#include "Trainer.h"
#include "BattlePetMgr.h"
#include "Creature.h"
+#include "Log.h"
#include "NPCPackets.h"
#include "Player.h"
#include "SpellInfo.h"
@@ -36,7 +37,7 @@ namespace Trainer
_greeting[DEFAULT_LOCALE] = std::move(greeting);
}
- void Trainer::SendSpells(Creature const* npc, Player const* player, LocaleConstant locale) const
+ void Trainer::SendSpells(Creature const* npc, Player* player, LocaleConstant locale) const
{
float reputationDiscount = player->GetReputationPriceDiscount(npc);
@@ -51,6 +52,12 @@ namespace Trainer
if (!player->IsSpellFitByClassAndRace(trainerSpell.SpellId))
continue;
+ if (!sConditionMgr->IsObjectMeetingTrainerSpellConditions(_id, trainerSpell.SpellId, player))
+ {
+ TC_LOG_DEBUG("condition", "SendSpells: conditions not met for trainer id %u spell %u player '%s' (%s)", _id, trainerSpell.SpellId, player->GetName().c_str(), player->GetGUID().ToString().c_str());
+ continue;
+ }
+
trainerList.Spells.emplace_back();
WorldPackets::NPC::TrainerListSpell& trainerListSpell = trainerList.Spells.back();
trainerListSpell.SpellID = trainerSpell.SpellId;
diff --git a/src/server/game/Entities/Creature/Trainer.h b/src/server/game/Entities/Creature/Trainer.h
index 303abe4fd0e..76ca1d69898 100644
--- a/src/server/game/Entities/Creature/Trainer.h
+++ b/src/server/game/Entities/Creature/Trainer.h
@@ -67,7 +67,7 @@ namespace Trainer
public:
Trainer(uint32 id, Type type, std::string greeting, std::vector<Spell> spells);
- void SendSpells(Creature const* npc, Player const* player, LocaleConstant locale) const;
+ void SendSpells(Creature const* npc, Player* player, LocaleConstant locale) const;
void TeachSpell(Creature const* npc, Player* player, uint32 spellId) const;
private: