aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp15
-rw-r--r--src/server/game/Conditions/ConditionMgr.h1
-rw-r--r--src/server/game/DataStores/DB2LoadInfo.h24
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp24
-rw-r--r--src/server/game/DataStores/DB2Stores.h2
-rw-r--r--src/server/game/DataStores/DB2Structure.h14
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp10
-rw-r--r--src/server/game/Entities/Creature/Creature.h3
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp10
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h3
-rw-r--r--src/server/game/Entities/Player/Player.cpp4
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp1
-rw-r--r--src/server/game/Spells/Spell.h1
-rw-r--r--src/server/game/Spells/SpellEffects.cpp16
14 files changed, 125 insertions, 3 deletions
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index f431db82c34..60018c25803 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -157,6 +157,7 @@ ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[COND
{ .Name = "Player Condition", .HasConditionValue1 = true, .HasConditionValue2 = false, .HasConditionValue3 = false, .HasConditionStringValue1 = false },
{ .Name = "Private Object", .HasConditionValue1 = false, .HasConditionValue2 = false, .HasConditionValue3 = false, .HasConditionStringValue1 = false },
{ .Name = "String ID", .HasConditionValue1 = false, .HasConditionValue2 = false, .HasConditionValue3 = false, .HasConditionStringValue1 = true },
+ { .Name = "Label", .HasConditionValue1 = true, .HasConditionValue2 = false, .HasConditionValue3 = false, .HasConditionStringValue1 = false },
};
ConditionSourceInfo::ConditionSourceInfo(WorldObject const* target0, WorldObject const* target1, WorldObject const* target2)
@@ -675,6 +676,14 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const
condMeets = go->HasStringId(ConditionStringValue1);
break;
}
+ case CONDITION_LABEL:
+ {
+ if (Creature const* creature = object->ToCreature())
+ condMeets = creature->HasLabel(ConditionValue1);
+ else if (GameObject const* go = object->ToGameObject())
+ condMeets = go->HasLabel(ConditionValue1);
+ break;
+ }
default:
break;
}
@@ -893,6 +902,9 @@ uint32 Condition::GetSearcherTypeMaskForCondition() const
case CONDITION_STRING_ID:
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT;
break;
+ case CONDITION_LABEL:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT;
+ break;
default:
ABORT_MSG("Condition::GetSearcherTypeMaskForCondition - missing condition handling!");
break;
@@ -2592,6 +2604,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) const
case CONDITION_GAMEMASTER:
case CONDITION_PRIVATE_OBJECT:
case CONDITION_STRING_ID:
+ case CONDITION_LABEL:
break;
case CONDITION_DIFFICULTY_ID:
if (!sDifficultyStore.LookupEntry(cond->ConditionValue1))
@@ -3882,7 +3895,7 @@ int32 GetUnitConditionVariable(Unit const* unit, Unit const* otherUnit, UnitCond
case UnitConditionVariable::IsMounted:
return unit->GetMountDisplayId() != 0;
case UnitConditionVariable::Label:
- break;
+ return unit->IsCreature() && unit->ToCreature()->HasLabel(value) ? value : 0;
case UnitConditionVariable::IsMySummon:
return otherUnit && (otherUnit->GetCharmerGUID() == unit->GetGUID() || otherUnit->GetCreatorGUID() == unit->GetGUID());
case UnitConditionVariable::IsSummoner:
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 98ba91e204b..ed7b83c94e5 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -117,6 +117,7 @@ enum ConditionTypes
CONDITION_PLAYER_CONDITION = 56, // PlayerConditionId 0 0 true if player satisfies PlayerCondition
CONDITION_PRIVATE_OBJECT = 57, // 0 0 0 true if entity is private object
CONDITION_STRING_ID = 58,
+ CONDITION_LABEL = 59, // Label 0 0 true if creature/gameobject has specified Label in CreatureLabel.db2/GameObjectLabel.db2
CONDITION_MAX
};
diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h
index d7306aabb70..27297ec5218 100644
--- a/src/server/game/DataStores/DB2LoadInfo.h
+++ b/src/server/game/DataStores/DB2LoadInfo.h
@@ -1461,6 +1461,18 @@ struct CreatureFamilyLoadInfo
static constexpr DB2LoadInfo Instance{ Fields, 11, &CreatureFamilyMeta::Instance, HOTFIX_SEL_CREATURE_FAMILY };
};
+struct CreatureLabelLoadInfo
+{
+ static constexpr DB2FieldMeta Fields[3] =
+ {
+ { false, FT_INT, "ID" },
+ { true, FT_INT, "LabelID" },
+ { false, FT_INT, "CreatureDifficultyID" },
+ };
+
+ static constexpr DB2LoadInfo Instance{ Fields, 3, &CreatureLabelMeta::Instance, HOTFIX_SEL_CREATURE_LABEL };
+};
+
struct CreatureModelDataLoadInfo
{
static constexpr DB2FieldMeta Fields[41] =
@@ -2025,6 +2037,18 @@ struct GameobjectDisplayInfoLoadInfo
static constexpr DB2LoadInfo Instance{ Fields, 15, &GameObjectDisplayInfoMeta::Instance, HOTFIX_SEL_GAMEOBJECT_DISPLAY_INFO };
};
+struct GameobjectLabelLoadInfo
+{
+ static constexpr DB2FieldMeta Fields[3] =
+ {
+ { false, FT_INT, "ID" },
+ { true, FT_INT, "LabelID" },
+ { false, FT_INT, "GameObjectID" },
+ };
+
+ static constexpr DB2LoadInfo Instance{ Fields, 3, &GameObjectLabelMeta::Instance, HOTFIX_SEL_GAMEOBJECT_LABEL };
+};
+
struct GameobjectsLoadInfo
{
static constexpr DB2FieldMeta Fields[25] =
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index c4087827424..dd2f9664503 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -122,6 +122,7 @@ DB2Storage<CorruptionEffectsEntry> sCorruptionEffectsStore("Corrupt
DB2Storage<CreatureDisplayInfoEntry> sCreatureDisplayInfoStore("CreatureDisplayInfo.db2", &CreatureDisplayInfoLoadInfo::Instance);
DB2Storage<CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore("CreatureDisplayInfoExtra.db2", &CreatureDisplayInfoExtraLoadInfo::Instance);
DB2Storage<CreatureFamilyEntry> sCreatureFamilyStore("CreatureFamily.db2", &CreatureFamilyLoadInfo::Instance);
+DB2Storage<CreatureLabelEntry> sCreatureLabelStore("CreatureLabel.db2", &CreatureLabelLoadInfo::Instance);
DB2Storage<CreatureModelDataEntry> sCreatureModelDataStore("CreatureModelData.db2", &CreatureModelDataLoadInfo::Instance);
DB2Storage<CreatureTypeEntry> sCreatureTypeStore("CreatureType.db2", &CreatureTypeLoadInfo::Instance);
DB2Storage<CriteriaEntry> sCriteriaStore("Criteria.db2", &CriteriaLoadInfo::Instance);
@@ -147,6 +148,7 @@ DB2Storage<FriendshipRepReactionEntry> sFriendshipRepReactionStore("Fri
DB2Storage<FriendshipReputationEntry> sFriendshipReputationStore("FriendshipReputation.db2", &FriendshipReputationLoadInfo::Instance);
DB2Storage<GameObjectArtKitEntry> sGameObjectArtKitStore("GameObjectArtKit.db2", &GameobjectArtKitLoadInfo::Instance);
DB2Storage<GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore("GameObjectDisplayInfo.db2", &GameobjectDisplayInfoLoadInfo::Instance);
+DB2Storage<GameObjectLabelEntry> sGameObjectLabelStore("GameObjectLabel.db2", &GameobjectLabelLoadInfo::Instance);
DB2Storage<GameObjectsEntry> sGameObjectsStore("GameObjects.db2", &GameobjectsLoadInfo::Instance);
DB2Storage<GarrAbilityEntry> sGarrAbilityStore("GarrAbility.db2", &GarrAbilityLoadInfo::Instance);
DB2Storage<GarrBuildingEntry> sGarrBuildingStore("GarrBuilding.db2", &GarrBuildingLoadInfo::Instance);
@@ -476,6 +478,7 @@ namespace
std::unordered_map<int32, ConditionalChrModelEntry const*> _conditionalChrModelsByChrModelId;
std::unordered_map<uint32 /*contentTuningId*/, std::vector<ConditionalContentTuningEntry const*>> _conditionalContentTuning;
std::unordered_set<std::pair<uint32, int32>> _contentTuningLabels;
+ std::unordered_map<uint32 /*creatureDifficultyId*/, std::vector<int32>> _creatureLabels;
std::unordered_multimap<uint32, CurrencyContainerEntry const*> _currencyContainers;
CurvePointsContainer _curvePoints;
EmotesTextSoundContainer _emoteTextSounds;
@@ -484,6 +487,7 @@ namespace
FactionTeamContainer _factionTeams;
std::unordered_map<uint32, std::set<FriendshipRepReactionEntry const*, DB2Manager::FriendshipRepReactionEntryComparator>> _friendshipRepReactions;
HeirloomItemsContainer _heirlooms;
+ std::unordered_map<uint32 /*gameobjectId*/, std::vector<int32>> _gameobjectLabels;
GlyphBindableSpellsContainer _glyphBindableSpells;
GlyphRequiredSpecsContainer _glyphRequiredSpecs;
ItemChildEquipmentContainer _itemChildEquipment;
@@ -736,6 +740,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
LOAD_DB2(sCreatureDisplayInfoStore);
LOAD_DB2(sCreatureDisplayInfoExtraStore);
LOAD_DB2(sCreatureFamilyStore);
+ LOAD_DB2(sCreatureLabelStore);
LOAD_DB2(sCreatureModelDataStore);
LOAD_DB2(sCreatureTypeStore);
LOAD_DB2(sCriteriaStore);
@@ -762,6 +767,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
LOAD_DB2(sGameObjectsStore);
LOAD_DB2(sGameObjectArtKitStore);
LOAD_DB2(sGameObjectDisplayInfoStore);
+ LOAD_DB2(sGameObjectLabelStore);
LOAD_DB2(sGarrAbilityStore);
LOAD_DB2(sGarrBuildingStore);
LOAD_DB2(sGarrBuildingPlotInstStore);
@@ -1256,6 +1262,9 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
for (ContentTuningXLabelEntry const* contentTuningXLabel : sContentTuningXLabelStore)
_contentTuningLabels.emplace(contentTuningXLabel->ContentTuningID, contentTuningXLabel->LabelID);
+ for (CreatureLabelEntry const* creatureLabel : sCreatureLabelStore)
+ _creatureLabels[creatureLabel->CreatureDifficultyID].push_back(creatureLabel->LabelID);
+
for (CurrencyContainerEntry const* currencyContainer : sCurrencyContainerStore)
_currencyContainers.emplace(currencyContainer->CurrencyTypesID, currencyContainer);
@@ -1297,6 +1306,9 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
std::swap(const_cast<GameObjectDisplayInfoEntry*>(gameObjectDisplayInfo)->GeoBoxMax.Z, const_cast<GameObjectDisplayInfoEntry*>(gameObjectDisplayInfo)->GeoBoxMin.Z);
}
+ for (GameObjectLabelEntry const* gameobjectLabel : sGameObjectLabelStore)
+ _creatureLabels[gameobjectLabel->GameObjectID].push_back(gameobjectLabel->LabelID);
+
for (HeirloomEntry const* heirloom : sHeirloomStore)
_heirlooms[heirloom->ItemID] = heirloom;
@@ -2240,6 +2252,12 @@ char const* DB2Manager::GetCreatureFamilyPetName(uint32 petfamily, LocaleConstan
return petFamily->Name[locale][0] != '\0' ? petFamily->Name[locale] : nullptr;
}
+std::span<int32 const> DB2Manager::GetCreatureLabels(uint32 creatureDifficultyId) const
+{
+ std::vector<int32> const* labels = Trinity::Containers::MapGetValuePtr(_creatureLabels, creatureDifficultyId);
+ return labels ? std::span<int32 const>(*labels) : std::span<int32 const>();
+}
+
CurrencyContainerEntry const* DB2Manager::GetCurrencyContainerForCurrencyQuantity(uint32 currencyId, int32 quantity) const
{
for (std::pair<uint32 const, CurrencyContainerEntry const*> const& p : Trinity::Containers::MapEqualRange(_currencyContainers, currencyId))
@@ -2567,6 +2585,12 @@ DB2Manager::FriendshipRepReactionSet const* DB2Manager::GetFriendshipRepReaction
return Trinity::Containers::MapGetValuePtr(_friendshipRepReactions, friendshipRepID);
}
+std::span<int32 const> DB2Manager::GetGameObjectLabels(uint32 gameobjectId) const
+{
+ std::vector<int32> const* labels = Trinity::Containers::MapGetValuePtr(_gameobjectLabels, gameobjectId);
+ return labels ? std::span<int32 const>(*labels) : std::span<int32 const>();
+}
+
uint32 DB2Manager::GetGlobalCurveId(GlobalCurve globalCurveType) const
{
for (GlobalCurveEntry const* globalCurveEntry : sGlobalCurveStore)
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index 19a45d46a69..0417e39b443 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -468,6 +468,7 @@ public:
Optional<ContentTuningLevels> GetContentTuningData(uint32 contentTuningId, uint32 redirectFlag, bool forItem = false) const;
bool HasContentTuningLabel(uint32 contentTuningId, int32 label) const;
static char const* GetCreatureFamilyPetName(uint32 petfamily, LocaleConstant locale);
+ std::span<int32 const> GetCreatureLabels(uint32 creatureDifficultyId) const;
CurrencyContainerEntry const* GetCurrencyContainerForCurrencyQuantity(uint32 currencyId, int32 quantity) const;
std::pair<float, float> GetCurveXAxisRange(uint32 curveId) const;
float GetCurveValueAt(uint32 curveId, float x) const;
@@ -476,6 +477,7 @@ public:
float EvaluateExpectedStat(ExpectedStatType stat, uint32 level, int32 expansion, uint32 contentTuningId, Classes unitClass, int32 mythicPlusMilestoneSeason) const;
std::vector<uint32> const* GetFactionTeamList(uint32 faction) const;
FriendshipRepReactionSet const* GetFriendshipRepReactions(uint32 friendshipRepID) const;
+ std::span<int32 const> GetGameObjectLabels(uint32 gameobjectId) const;
uint32 GetGlobalCurveId(GlobalCurve globalCurveType) const;
std::vector<uint32> const* GetGlyphBindableSpells(uint32 glyphPropertiesId) const;
std::vector<ChrSpecialization> const* GetGlyphRequiredSpecs(uint32 glyphPropertiesId) const;
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index 7ea04668e5c..533f8afcd61 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -1076,6 +1076,13 @@ struct CreatureFamilyEntry
std::array<int16, 2> SkillLine;
};
+struct CreatureLabelEntry
+{
+ uint32 ID;
+ int32 LabelID;
+ uint32 CreatureDifficultyID;
+};
+
struct CreatureModelDataEntry
{
uint32 ID;
@@ -1752,6 +1759,13 @@ struct GameObjectDisplayInfoEntry
uint16 Unknown1100;
};
+struct GameObjectLabelEntry
+{
+ uint32 ID;
+ int32 LabelID;
+ uint32 GameObjectID;
+};
+
struct GameObjectsEntry
{
LocalizedString Name;
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 0b8a3483b1f..0a5c0c88612 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -3320,6 +3320,16 @@ std::string Creature::GetNameForLocaleIdx(LocaleConstant locale) const
return GetName();
}
+bool Creature::HasLabel(int32 cretureLabel) const
+{
+ return advstd::ranges::contains(GetLabels(), cretureLabel);
+}
+
+std::span<int32 const> Creature::GetLabels() const
+{
+ return sDB2Manager.GetCreatureLabels(GetCreatureDifficulty()->CreatureDifficultyID);
+}
+
uint8 Creature::GetPetAutoSpellSize() const
{
return MAX_SPELL_CHARM;
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 02dbef80715..a7f6113aab6 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -279,6 +279,9 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
// override WorldObject function for proper name localization
std::string GetNameForLocaleIdx(LocaleConstant locale) const override;
+ bool HasLabel(int32 cretureLabel) const;
+ std::span<int32 const> GetLabels() const;
+
void setDeathState(DeathState s) override; // override virtual Unit::setDeathState
bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, bool allowDuplicate);
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index ce475f4424f..43812641cec 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -3602,6 +3602,16 @@ std::string GameObject::GetNameForLocaleIdx(LocaleConstant locale) const
return GetName();
}
+bool GameObject::HasLabel(int32 gameobjectLabel) const
+{
+ return advstd::ranges::contains(GetLabels(), gameobjectLabel);
+}
+
+std::span<int32 const> GameObject::GetLabels() const
+{
+ return sDB2Manager.GetGameObjectLabels(GetEntry());
+}
+
void GameObject::UpdatePackedRotation()
{
static const int32 PACK_YZ = 1 << 20;
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 07db9755d86..00cbe9bfecd 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -223,6 +223,9 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
// overwrite WorldObject function for proper name localization
std::string GetNameForLocaleIdx(LocaleConstant locale) const override;
+ bool HasLabel(int32 gameobjectLabel) const;
+ std::span<int32 const> GetLabels() const;
+
void SaveToDB();
void SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDifficulties);
bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, bool = true); // arg4 is unused, only present to match the signature on Creature
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 25f907599ec..c1e5da1041b 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -16666,6 +16666,9 @@ void Player::KilledMonster(Creature const* creature)
for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i)
if (cInfo->KillCredit[i])
KilledMonsterCredit(cInfo->KillCredit[i], ObjectGuid::Empty);
+
+ for (int32 label : creature->GetLabels())
+ UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_KILL_WITH_LABEL, label, 1, creature->GetGUID());
}
void Player::KilledMonsterCredit(uint32 entry, ObjectGuid guid /*= ObjectGuid::Empty*/)
@@ -17129,6 +17132,7 @@ bool Player::IsQuestObjectiveComplete(uint16 slot, Quest const* quest, QuestObje
case QUEST_OBJECTIVE_HAVE_CURRENCY:
case QUEST_OBJECTIVE_OBTAIN_CURRENCY:
case QUEST_OBJECTIVE_INCREASE_REPUTATION:
+ case QUEST_OBJECTIVE_KILL_WITH_LABEL:
if (GetQuestSlotObjectiveData(slot, objective) < objective.Amount)
return false;
break;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 32e6e07ec68..b42d5137fdf 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -5010,6 +5010,7 @@ void ObjectMgr::LoadQuests()
case QUEST_OBJECTIVE_MONEY:
case QUEST_OBJECTIVE_WINPVPPETBATTLES:
case QUEST_OBJECTIVE_PROGRESS_BAR:
+ case QUEST_OBJECTIVE_KILL_WITH_LABEL:
break;
default:
TC_LOG_ERROR("sql.sql", "Quest {} objective {} has unhandled type {}", qinfo->GetQuestId(), obj.ID, obj.Type);
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index ef421373259..3e85b39f501 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -372,6 +372,7 @@ class TC_GAME_API Spell
void EffectUnlockGuildVaultTab();
void EffectKillCreditPersonal();
void EffectKillCredit();
+ void EffectKillCreditLabel();
void EffectQuestFail();
void EffectQuestStart();
void EffectRedirectThreat();
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index c0af44a549a..7b17a52d53b 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -404,8 +404,8 @@ NonDefaultConstructible<SpellEffectHandlerFn> SpellEffectHandlers[TOTAL_SPELL_EF
&Spell::EffectNULL, //313 SPELL_EFFECT_CHANGE_ITEM_BONUSES_2
&Spell::EffectNULL, //314 SPELL_EFFECT_ADD_SOCKET_BONUS
&Spell::EffectNULL, //315 SPELL_EFFECT_LEARN_TRANSMOG_APPEARANCE_FROM_ITEM_MOD_APPEARANCE_GROUP
- &Spell::EffectNULL, //316 SPELL_EFFECT_KILL_CREDIT_LABEL_1
- &Spell::EffectNULL, //317 SPELL_EFFECT_KILL_CREDIT_LABEL_2
+ &Spell::EffectKillCreditLabel, //316 SPELL_EFFECT_KILL_CREDIT_LABEL_1
+ &Spell::EffectKillCreditLabel, //317 SPELL_EFFECT_KILL_CREDIT_LABEL_2
&Spell::EffectNULL, //318 SPELL_EFFECT_318
&Spell::EffectNULL, //319 SPELL_EFFECT_319
&Spell::EffectNULL, //320 SPELL_EFFECT_320
@@ -4767,6 +4767,18 @@ void Spell::EffectKillCredit()
unitTarget->ToPlayer()->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
}
+void Spell::EffectKillCreditLabel()
+{
+ if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
+ return;
+
+ Player* playerTarget = Object::ToPlayer(unitTarget);
+ if (!playerTarget)
+ return;
+
+ playerTarget->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_KILL_WITH_LABEL, effectInfo->MiscValue, std::max(1, effectInfo->MiscValueB));
+}
+
void Spell::EffectQuestFail()
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)