aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp25
-rw-r--r--src/server/game/Achievements/AchievementMgr.h9
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp15
-rw-r--r--src/server/game/Scripting/ScriptMgr.h23
5 files changed, 68 insertions, 6 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 13229faf4e9..f5f6d25b723 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -202,6 +202,14 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
return false;
}
return true;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT:
+ if (!ScriptId)
+ {
+ sLog.outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT (%u) does not have ScriptName set, ignored.",
+ criteria->ID, criteria->requiredType, dataType);
+ return false;
+ }
+ return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY:
if (difficulty.difficulty >= MAX_DIFFICULTY)
{
@@ -305,6 +313,8 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
if (!target)
return false;
return target->getGender() == gender.gender;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT:
+ return sScriptMgr.OnCriteriaCheck(source, target);
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY:
return source->GetMap()->GetSpawnMode() == difficulty.difficulty;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT:
@@ -2119,12 +2129,21 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
continue;
}
- AchievementCriteriaData data(fields[1].GetUInt32(),fields[2].GetUInt32(),fields[3].GetUInt32());
+ uint32 dataType = fields[1].GetUInt32();
+ const char* scriptName = fields[4].GetString();
+ uint32 scriptId = 0;
+ if (scriptName)
+ {
+ if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
+ sLog.outErrorDb("Table `achievement_criteria_data` has ScriptName set for non-scripted data type (Entry: %u, type %u), useless data.", criteria_id, dataType);
+ else
+ scriptId = objmgr.GetScriptId(scriptName);
+ }
+
+ AchievementCriteriaData data(dataType, fields[2].GetUInt32(), fields[3].GetUInt32(), scriptId);
if (!data.IsValid(criteria))
- {
continue;
- }
// this will allocate empty data set storage
AchievementCriteriaDataSet& dataSet = m_criteriaDataMap[criteria_id];
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index b2d24098052..301028e3e7b 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -53,7 +53,7 @@ enum AchievementCriteriaDataType
ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8, // minvalue value provided with achievement update must be not less that limit
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9, // minlevel minlevel of target
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10,// gender 0=male; 1=female
- ACHIEVEMENT_CRITERIA_DATA_TYPE_REUSE = 11,// TO BE REUSED
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11,// scripted requirement
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12,// difficulty normal/heroic difficulty for current event map
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13,// count "with less than %u people in the zone"
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14,// team HORDE(67), ALLIANCE(469)
@@ -123,7 +123,7 @@ struct AchievementCriteriaData
{
uint32 gender;
} gender;
- // ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED = 11 (no data)
+ // ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11 (no data)
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12
struct
{
@@ -169,17 +169,20 @@ struct AchievementCriteriaData
uint32 value2;
} raw;
};
+ uint32 ScriptId;
AchievementCriteriaData() : dataType(ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE)
{
raw.value1 = 0;
raw.value2 = 0;
+ ScriptId = 0;
}
- AchievementCriteriaData(uint32 _dataType, uint32 _value1, uint32 _value2) : dataType(AchievementCriteriaDataType(_dataType))
+ AchievementCriteriaData(uint32 _dataType, uint32 _value1, uint32 _value2, uint32 _scriptId) : dataType(AchievementCriteriaDataType(_dataType))
{
raw.value1 = _value1;
raw.value2 = _value2;
+ ScriptId = _scriptId;
}
bool IsValid(AchievementCriteriaEntry const* criteria);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 5bc83ee4e5f..530a1d5201e 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -8732,6 +8732,8 @@ void ObjectMgr::LoadScriptNames()
{
m_scriptNames.push_back("");
QueryResult_AutoPtr result = WorldDatabase.Query(
+ "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
+ "UNION "
"SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
"UNION "
"SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index b43e601b433..dc405c53e53 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -1053,6 +1053,15 @@ void ScriptMgr::OnShutdown()
FOREACH_SCRIPT(WorldScript)->OnShutdown();
}
+bool ScriptMgr::OnCriteriaCheck(AchievementCriteriaData const* data, Player* source, Unit* target)
+{
+ ASSERT(source);
+ // target can be NULL
+
+ GET_SCRIPT_RET(AchievementCriteriaScript, data->ScriptId, tmpscript, false);
+ return tmpscript->OnCheck(source, target);
+}
+
void SpellHandlerScript::RegisterSelf()
{
ScriptMgr::ScriptRegistry<SpellHandlerScript>::AddScript(this);
@@ -1158,6 +1167,11 @@ void TransportScript::RegisterSelf()
ScriptMgr::ScriptRegistry<TransportScript>::AddScript(this);
}
+void AchievementCriteriaScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<AchievementCriteriaScript>::AddScript(this);
+}
+
template<class TScript>
void ScriptMgr::ScriptRegistry<TScript>::AddScript(TScript* const script)
{
@@ -1255,6 +1269,7 @@ template class ScriptMgr::ScriptRegistry<ConditionScript>;
template class ScriptMgr::ScriptRegistry<VehicleScript>;
template class ScriptMgr::ScriptRegistry<DynamicObjectScript>;
template class ScriptMgr::ScriptRegistry<TransportScript>;
+template class ScriptMgr::ScriptRegistry<AchievementCriteriaScript>;
// Undefine utility macros.
#undef GET_SCRIPT_RET
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 375c339c109..c27a169880c 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -753,6 +753,25 @@ class TransportScript : public ScriptObject, public UpdatableScript<Transport>
virtual void OnRelocate(Transport* transport, uint32 mapId, float x, float y, float z) { }
};
+class AchievementCriteriaScript : public ScriptObject
+{
+ protected:
+
+ AchievementCriteriaScript(const char* name)
+ : ScriptObject(name)
+ {
+ }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Called when additional criteria is checked
+ virtual bool OnCheck(Player* source, Unit* target) = 0;
+};
+
// Placed here due to ScriptRegistry::AddScript dependency.
#define sScriptMgr (*ACE_Singleton<ScriptMgr, ACE_Null_Mutex>::instance())
@@ -921,6 +940,10 @@ class ScriptMgr
void OnTransportUpdate(Transport* transport, uint32 diff);
void OnRelocate(Transport* transport, uint32 mapId, float x, float y, float z);
+ public: /* AchievementCriteriaScript */
+
+ bool OnCriteriaCheck(AchievementCriteriaData const* data, Player* source, Unit* target);
+
public: /* ScriptRegistry */
// This is the global static registry of scripts.