diff --git a/modules/azerothshard/data/sql/archive/char/characters_xp_rate.sql b/modules/azerothshard/data/sql/db-characters/characters_xp_rate.sql
similarity index 83%
rename from modules/azerothshard/data/sql/archive/char/characters_xp_rate.sql
rename to modules/azerothshard/data/sql/db-characters/characters_xp_rate.sql
index 70458daeb8..2e7194b722 100644
--- a/modules/azerothshard/data/sql/archive/char/characters_xp_rate.sql
+++ b/modules/azerothshard/data/sql/db-characters/characters_xp_rate.sql
@@ -1,4 +1,3 @@
-DROP TABLE IF EXISTS `character_xp_rate`;
CREATE TABLE `character_xp_rate` (
`guid` int(10) UNSIGNED NOT NULL,
`xp_rate` float UNSIGNED NOT NULL DEFAULT '1',
diff --git a/modules/azerothshard/data/sql/db-world/azth_commands.sql b/modules/azerothshard/data/sql/db-world/azth_commands.sql
new file mode 100644
index 0000000000..410b4ebcd6
--- /dev/null
+++ b/modules/azerothshard/data/sql/db-world/azth_commands.sql
@@ -0,0 +1,9 @@
+-- Max Skill
+DELETE FROM command WHERE name = 'azth maxskill';
+INSERT INTO command VALUES('azth maxskill', 0, 'Max all skill of targeted player');
+DELETE FROM trinity_string WHERE entry = 90001;
+INSERT INTO trinity_string(entry, content_default) VALUES(90001, 'The target level must be level %u');
+
+-- xp rate
+DELETE FROM command WHERE name = 'azth xp';
+INSERT INTO command VALUES('azth xp', 0, 'Set a custom xp rate');
diff --git a/modules/azerothshard/data/sql/db-world/azth_world_quest_completer.sql b/modules/azerothshard/data/sql/db-world/azth_world_quest_completer.sql
new file mode 100644
index 0000000000..3fa654ede3
--- /dev/null
+++ b/modules/azerothshard/data/sql/db-world/azth_world_quest_completer.sql
@@ -0,0 +1,20 @@
+--
+-- CREATE STRUCTURE
+--
+
+DROP TABLE IF EXISTS `quest_bugged`;
+CREATE TABLE `quest_bugged` (
+ `ID` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
+ `bugged` BOOLEAN NOT NULL DEFAULT '1',
+ PRIMARY KEY (`ID`)
+);
+
+--
+-- ADD DATA
+--
+
+DELETE FROM `command` WHERE `name` = 'qc';
+INSERT INTO `command` (`name`, `security`, `help`) VALUES ('qc', 0, 'Syntax: .qc [Quest]');
+
+DELETE FROM `quest_bugged`;
+INSERT INTO `quest_bugged` (SELECT `ID`, 0 FROM `quest_template`);
diff --git a/modules/azerothshard/src/server/game/AzthPlayer.cpp b/modules/azerothshard/src/server/game/AzthPlayer.cpp
index cea0c58f18..5daba4011c 100644
--- a/modules/azerothshard/src/server/game/AzthPlayer.cpp
+++ b/modules/azerothshard/src/server/game/AzthPlayer.cpp
@@ -11,9 +11,9 @@
player = origin;
}
-// void AzthPlayer::SetPlayerQuestRate(float rate) {
-// playerQuestRate = rate;
-// }
+ void AzthPlayer::SetPlayerQuestRate(float rate) {
+ playerQuestRate = rate;
+ }
uint32 AzthPlayer::getArena1v1Info(uint8 type) {
return arena1v1Info[type];
@@ -22,11 +22,11 @@
void AzthPlayer::setArena1v1Info(uint8 type, uint32 value) {
arena1v1Info[type] = value;
}
-//
-// float AzthPlayer::GetPlayerQuestRate() {
-// return playerQuestRate;
-// }
-//
+
+ float AzthPlayer::GetPlayerQuestRate() {
+ return playerQuestRate;
+ }
+
// uint32 AzthPlayer::getOriginalTeam() {
// return player->TeamForRace(player->getRace());
// }
diff --git a/modules/azerothshard/src/server/game/AzthPlayer.h b/modules/azerothshard/src/server/game/AzthPlayer.h
index 8ed19a4f76..dace112a21 100644
--- a/modules/azerothshard/src/server/game/AzthPlayer.h
+++ b/modules/azerothshard/src/server/game/AzthPlayer.h
@@ -11,32 +11,32 @@
explicit AzthPlayer(Player *origin);
~AzthPlayer();
-// void SetPlayerQuestRate(float rate);
-//
-// /**
-// Get player quest rate. If player hasn't set it before, returns server configuration
-//
-// @returns Quest Rate. If player set his own, return it; if he hasn't it returns server default
-// */
-// float GetPlayerQuestRate();
-//
-// /**
-//
-// Get Player team considering CrossFactionGroups: If player is in a group returns group leader's team
-//
-// @param Unit race (Unused, kept for compatibility)
-// @returns Group leader team if player is in a group, -1 for default
-// */
-// bool setFactionForRace(uint8 race);
-// uint32 getOriginalTeam();
-//
+ void SetPlayerQuestRate(float rate);
+
+ /**
+ Get player quest rate. If player hasn't set it before, returns server configuration
+
+ @returns Quest Rate. If player set his own, return it; if he hasn't it returns server default
+ */
+ float GetPlayerQuestRate();
+
+ /**
+
+ Get Player team considering CrossFactionGroups: If player is in a group returns group leader's team
+
+ @param Unit race (Unused, kept for compatibility)
+ @returns Group leader team if player is in a group, -1 for default
+ */
+ bool setFactionForRace(uint8 race);
+ uint32 getOriginalTeam();
+
uint32 getArena1v1Info(uint8 type);
void setArena1v1Info(uint8 type, uint32 value);
-//
+
private:
Player *player;
uint32 arena1v1Info[7]; // ARENA_TEAM_END
-//
+
float playerQuestRate, maxQuestRate;
};
diff --git a/modules/azerothshard/src/server/game/AzthSharedDefines.h b/modules/azerothshard/src/server/game/AzthSharedDefines.h
index 4aebe94f85..df93cc5e3f 100644
--- a/modules/azerothshard/src/server/game/AzthSharedDefines.h
+++ b/modules/azerothshard/src/server/game/AzthSharedDefines.h
@@ -1,13 +1,13 @@
#ifndef SHAREDDEFINES_H
#define SHAREDDEFINES_H
-// enum AzthRbac {
-// RBAC_PERM_COMMAND_QUESTCOMPLETER = 1000,
-// RBAC_PERM_COMMAND_AZTH = 1001,
-// RBAC_PERM_COMMAND_AZTH_MAXSKILL = 1002,
-// RBAC_PERM_COMMAND_AZTH_XP = 1003,
-// RBAC_PERM_PVP_CUSTOM = 1004 // Arena Spectator ADDON commands
-// };
+ enum AzthRbac {
+ RBAC_PERM_COMMAND_QUESTCOMPLETER = 1000,
+ RBAC_PERM_COMMAND_AZTH = 1001,
+ RBAC_PERM_COMMAND_AZTH_MAXSKILL = 1002,
+ RBAC_PERM_COMMAND_AZTH_XP = 1003,
+ RBAC_PERM_PVP_CUSTOM = 1004 // Arena Spectator ADDON commands
+ };
#endif /* SHAREDDEFINES_H */
diff --git a/modules/azerothshard/src/server/game/CustomRates.cpp b/modules/azerothshard/src/server/game/CustomRates.cpp
index 6b27500867..8aa9669735 100644
--- a/modules/azerothshard/src/server/game/CustomRates.cpp
+++ b/modules/azerothshard/src/server/game/CustomRates.cpp
@@ -2,8 +2,9 @@
#include "Chat.h"
#include "Language.h"
#include "server/game/CustomRates.h"
+#include "Player.h"
-/* [TODO] fix and re-enable
+ // [TODO] fix and re-enable
float CustomRates::GetRateFromDB(const Player *player, CharacterDatabaseStatements statement) {
PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(statement);
stmt->setUInt32(0, player->GetGUID());
@@ -48,4 +49,3 @@ void CustomRates::SaveXpRateToDB(const Player *player, float rate) {
SaveRateToDB(player, rate, update, CHAR_UPD_INDIVIDUAL_XP_RATE, CHAR_INS_INDIVIDUAL_XP_RATE);
}
-*/
diff --git a/modules/azerothshard/src/server/game/CustomRates.h b/modules/azerothshard/src/server/game/CustomRates.h
index 290d302fa8..f2d9134f48 100644
--- a/modules/azerothshard/src/server/game/CustomRates.h
+++ b/modules/azerothshard/src/server/game/CustomRates.h
@@ -5,7 +5,7 @@
#include "Chat.h"
#include "Language.h"
-/* [TODO] fix and re-enable
+// [TODO] fix and re-enable
class CustomRates {
private:
static float GetRateFromDB(const Player *player, CharacterDatabaseStatements statement);
@@ -20,6 +20,5 @@ public:
static void SaveXpRateToDB(const Player *player, float rate);
};
-*/
#endif
diff --git a/modules/azerothshard/src/server/plugins/AzthPlgLoader.cpp b/modules/azerothshard/src/server/plugins/AzthPlgLoader.cpp
index 6520611bb3..973185fe0d 100644
--- a/modules/azerothshard/src/server/plugins/AzthPlgLoader.cpp
+++ b/modules/azerothshard/src/server/plugins/AzthPlgLoader.cpp
@@ -6,10 +6,10 @@
#define SCRIPTLOADER_CPP
/* This is where custom AzerothShard function scripts declarations should be added. */
-// void AddSC_azth_commandscript();
+void AddSC_azth_commandscript();
void AddSC_CrossFactionGroups();
void AddSC_azth_player_plg();
-// void AddSC_Custom_Rates();
+void AddSC_Custom_Rates();
// void AddSC_PWS_Transmogrification();
// void AddSC_CS_Transmogrification();
void AddSC_npc_1v1arena();
@@ -23,10 +23,10 @@ void AddAzthScripts()
{
sLog->outString("Loading AzerothShard Plugins...");
/* This is where custom AzerothShard scripts should be added. */
-// AddSC_azth_commandscript();
+ AddSC_azth_commandscript();
AddSC_CrossFactionGroups();
AddSC_azth_player_plg();
-// AddSC_Custom_Rates();
+ AddSC_Custom_Rates();
AddSC_npc_1v1arena();
AddSC_npc_lottery();
//AddSC_anticheat_commandscript();
diff --git a/modules/azerothshard/src/server/plugins/AzthRateScript.cpp b/modules/azerothshard/src/server/plugins/AzthRateScript.cpp
index abe1131c38..c33aacfd27 100644
--- a/modules/azerothshard/src/server/plugins/AzthRateScript.cpp
+++ b/modules/azerothshard/src/server/plugins/AzthRateScript.cpp
@@ -1,35 +1,36 @@
-// #include "ScriptMgr.h"
-// #include "Chat.h"
-// #include "Language.h"
-// #include "CustomRates.h"
+ #include "ScriptMgr.h"
+ #include "Chat.h"
+ #include "Language.h"
+ #include "CustomRates.h"
+#include "Player.h"
-// class AzthXPRatePlayerScripts : public PlayerScript {
-// public:
-//
-// AzthXPRatePlayerScripts() : PlayerScript("AzthXPRatePlayerScripts") {
-// }
-//
-// void OnDelete(ObjectGuid guid, uint32 accountId) {
-// CustomRates::DeleteRateFromDB(guid, CHAR_DEL_INDIVIDUAL_XP_RATE);
-// }
-//
-// void OnLogin(Player* player, bool /*firstLogin*/) {
-// float rate = CustomRates::GetXpRateFromDB(player);
-//
-// // player has custom xp rate set. Load it from DB. Otherwise use default set in AzthPlayer::AzthPlayer
-// if (rate != -1) {
-// player->azthPlayer->SetPlayerQuestRate(rate);
-//
-// if (sWorld->getBoolConfig(CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SHOW_ON_LOGIN)) {
-// if (rate == 0)
-// ChatHandler(player->GetSession()).SendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your quest XP rate was set to 0. You won't gain any XP from quest completation.");
-// else
-// ChatHandler(player->GetSession()).PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your quest XP rate was set to %.2f.", rate);
-// }
-// }
-// }
-// };
-//
-// void AddSC_Custom_Rates() {
-// new AzthXPRatePlayerScripts();
-// }
+ class AzthXPRatePlayerScripts : public PlayerScript {
+ public:
+
+ AzthXPRatePlayerScripts() : PlayerScript("AzthXPRatePlayerScripts") {
+ }
+
+ void OnDelete(uint64 guid) {
+ CustomRates::DeleteRateFromDB(guid, CHAR_DEL_INDIVIDUAL_XP_RATE);
+ }
+
+ void OnLogin(Player* player) {
+ float rate = CustomRates::GetXpRateFromDB(player);
+
+ // player has custom xp rate set. Load it from DB. Otherwise use default set in AzthPlayer::AzthPlayer
+ if (rate != -1) {
+ player->azthPlayer->SetPlayerQuestRate(rate);
+
+ if (sWorld->getBoolConfig(CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SHOW_ON_LOGIN)) {
+ if (rate == 0)
+ ChatHandler(player->GetSession()).SendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your quest XP rate was set to 0. You won't gain any XP from quest completation.");
+ else
+ ChatHandler(player->GetSession()).PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your quest XP rate was set to %.2f.", rate);
+ }
+ }
+ }
+ };
+
+ void AddSC_Custom_Rates() {
+ new AzthXPRatePlayerScripts();
+ }
diff --git a/modules/azerothshard/src/server/plugins/cs_azth_custom.cpp b/modules/azerothshard/src/server/plugins/cs_azth_custom.cpp
index 8205798e2d..0efb1271bb 100644
--- a/modules/azerothshard/src/server/plugins/cs_azth_custom.cpp
+++ b/modules/azerothshard/src/server/plugins/cs_azth_custom.cpp
@@ -15,347 +15,346 @@
* with this program. If not, see .
*/
-// #include "Chat.h"
-// #include "ScriptMgr.h"
-// #include "AccountMgr.h"
-// #include "ArenaTeamMgr.h"
-// #include "CellImpl.h"
-// #include "GridNotifiers.h"
-// #include "Group.h"
-// #include "Language.h"
-// #include "Opcodes.h"
-// #include "Player.h"
-// #include "Pet.h"
-// #include "ReputationMgr.h"
-// #include "server/game/CustomRates.h"
-// #include "server/game/AzthSharedDefines.h"
-//
-// class azth_commandscript : public CommandScript {
-// public:
-//
-// azth_commandscript() : CommandScript("azth_commandscript") {
-// }
-//
-// std::vector GetCommands() const override {
-// static std::vector lookupAzthCommands = {
-// { "maxskill", AzthRbac::RBAC_PERM_COMMAND_AZTH_MAXSKILL, true, &handleAzthMaxSkill, ""},
-// { "xp", AzthRbac::RBAC_PERM_COMMAND_AZTH_XP, false, &handleAzthXP, ""},
-// };
-//
-// static std::vector commandTable = {
-// { "azth", AzthRbac::RBAC_PERM_COMMAND_AZTH, true, NULL, "", lookupAzthCommands},
-// { "qc", AzthRbac::RBAC_PERM_COMMAND_QUESTCOMPLETER, true, &HandleQuestCompleterCommand, ""},
-// };
-// return commandTable;
-// }
-//
-// // Based on HandleQuestComplete method of cs_quest.cpp
-//
-// static bool HandleQuestCompleterCompHelper(Player* player, uint32 entry, ChatHandler* handler, char const* args, uint8 checked) {
-// if (!player) {
-// handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
-// handler->SetSentErrorMessage(true);
-// return false;
-// }
-//
-// Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
-//
-// // If player doesn't have the quest
-// if (!quest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE) {
-// handler->PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
-// handler->SetSentErrorMessage(true);
-// return false;
-// }
-//
-// // Add quest items for quests that require items
-// for (uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x) {
-// uint32 id = quest->RequiredItemId[x];
-// uint32 count = quest->RequiredItemCount[x];
-// if (!id || !count)
-// continue;
-//
-// uint32 curItemCount = player->GetItemCount(id, true);
-//
-// ItemPosCountVec dest;
-// uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, id, count - curItemCount);
-// if (msg == EQUIP_ERR_OK) {
-// Item* item = player->StoreNewItem(dest, id, true);
-// player->SendNewItem(item, count - curItemCount, true, false);
-// }
-// }
-//
-// // All creature/GO slain/cast (not required, but otherwise it will display "Creature slain 0/10")
-// for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) {
-// int32 creature = quest->RequiredNpcOrGo[i];
-// uint32 creatureCount = quest->RequiredNpcOrGoCount[i];
-//
-// if (creature > 0) {
-// if (CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature))
-// for (uint16 z = 0; z < creatureCount; ++z)
-// player->KilledMonster(creatureInfo, ObjectGuid::Empty);
-// } else if (creature < 0)
-// for (uint16 z = 0; z < creatureCount; ++z)
-// player->KillCreditGO(creature);
-// }
-//
-// // If the quest requires reputation to complete
-// if (uint32 repFaction = quest->GetRepObjectiveFaction()) {
-// uint32 repValue = quest->GetRepObjectiveValue();
-// uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
-// if (curRep < repValue)
-// if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction))
-// player->GetReputationMgr().SetReputation(factionEntry, repValue);
-// }
-//
-// // If the quest requires a SECOND reputation to complete
-// if (uint32 repFaction = quest->GetRepObjectiveFaction2()) {
-// uint32 repValue2 = quest->GetRepObjectiveValue2();
-// uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
-// if (curRep < repValue2)
-// if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction))
-// player->GetReputationMgr().SetReputation(factionEntry, repValue2);
-// }
-//
-// // If the quest requires money
-// int32 ReqOrRewMoney = quest->GetRewOrReqMoney();
-// if (ReqOrRewMoney < 0)
-// player->ModifyMoney(-ReqOrRewMoney);
-//
-// if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled
-// {
-// // prepare Quest Tracker datas
-// PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_GM_COMPLETE);
-// stmt->setUInt32(0, quest->GetQuestId());
-// stmt->setUInt32(1, player->GetGUID().GetCounter());
-//
-// // add to Quest Tracker
-// CharacterDatabase.Execute(stmt);
-// }
-//
-// player->CompleteQuest(entry);
-//
-// // if bugged field is set on 2
-// // then reward the quest too
-// if (checked == 2) {
-// Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
-//
-// // If player doesn't have the quest
-// if (!quest || player->GetQuestStatus(entry) != QUEST_STATUS_COMPLETE) {
-// handler->PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
-// handler->SetSentErrorMessage(true);
-// return false;
-// }
-//
-// player->RewardQuest(quest, 0, player);
-// }
-//
-// return true;
-// }
-//
-// // Based on TrueWoW code
-//
-// static bool HandleQuestCompleterCommand(ChatHandler* handler, char const* args) {
-// char* cId = handler->extractKeyFromLink((char*) args, "Hquest");
-// if (!cId) {
-// handler->PSendSysMessage("Syntax: .qc $quest\n\nControlla se la $quest è buggata.");
-// handler->SetSentErrorMessage(true);
-// return false;
-// }
-//
-// uint32 entry = atol(cId);
-// Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
-// if (!quest || quest == 0) {
-// handler->PSendSysMessage("Please enter a quest link.");
-// handler->SetSentErrorMessage(true);
-// return false;
-// } else {
-// uint32 checked = 0;
-// PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_QUESTCOMPLETER);
-// stmt->setUInt32(0, entry);
-// PreparedQueryResult resultCheck = WorldDatabase.Query(stmt);
-//
-// if (!resultCheck) {
-// handler->PSendSysMessage("Errore: quest non trovata.");
-// handler->SetSentErrorMessage(true);
-// return false;
-// }
-//
-// std::string questTitle = quest->GetTitle();
-//
-// checked = (*resultCheck)[0].GetUInt8();
-//
-// if (checked >= 1) {
-// std::string name;
-// const char* playerName = handler->GetSession() ? handler->GetSession()->GetPlayer()->GetName().c_str() : NULL;
-//
-// if (playerName) {
-// name = playerName;
-// normalizePlayerName(name);
-//
-// Player* player = ObjectAccessor::FindPlayerByName(name);
-// if (player->GetQuestStatus(entry) != QUEST_STATUS_INCOMPLETE) {
-// handler->PSendSysMessage("[%s] è buggata!", questTitle.c_str());
-// return true;
-// } else {
-// HandleQuestCompleterCompHelper(player, entry, handler, args, checked);
-// handler->PSendSysMessage("[%s] è buggata ed è stata completata!", questTitle.c_str());
-// return true;
-// }
-// } else {
-// handler->PSendSysMessage("[%s] è buggata!", questTitle.c_str());
-// return true;
-// }
-// } else {
-// handler->PSendSysMessage("[%s] non risulta essere buggata, se ritieni che lo sia ti preghiamo di segnalarcelo utilizzando il bugtracker.", questTitle.c_str());
-// return true;
-// }
-// }
-// }
-//
-// static bool handleAzthMaxSkill(ChatHandler* handler, const char* args) {
-//
-// Player* target = handler->getSelectedPlayerOrSelf();
-// if (!target) {
-// handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
-// handler->SetSentErrorMessage(true);
-// return false;
-// }
-// if (target->getLevel() < 80) {
-// handler->PSendSysMessage(LANG_LEVEL_MINREQUIRED, 80);
-// handler->SetSentErrorMessage(true);
-// return false;
-// }
-//
-// enum SkillSpells {
-// ONE_HAND_AXES = 196,
-// TWO_HAND_AXES = 197,
-// ONE_HAND_MACES = 198,
-// TWO_HAND_MACES = 199,
-// POLEARMS = 200,
-// ONE_HAND_SWORDS = 201,
-// TWO_HAND_SWORDS = 202,
-// STAVES = 227,
-// BOWS = 264,
-// GUNS = 266,
-// DAGGERS = 1180,
-// WANDS = 5009,
-// CROSSBOWS = 5011,
-// FIST_WEAPONS = 15590
-// };
-// static const SkillSpells spells[] = {ONE_HAND_AXES, TWO_HAND_AXES, ONE_HAND_MACES,
-// TWO_HAND_MACES, POLEARMS, ONE_HAND_SWORDS, TWO_HAND_SWORDS, STAVES, BOWS,
-// GUNS, DAGGERS, WANDS, CROSSBOWS, FIST_WEAPONS};
-//
-// std::list learnList;
-// for (SkillSpells spell : spells) {
-// switch (target->getClass()) {
-// case CLASS_WARRIOR:
-// if (spell != WANDS)
-// learnList.push_back(spell);
-// break;
-// case CLASS_DEATH_KNIGHT:
-// case CLASS_PALADIN:
-// if (spell != STAVES && spell != BOWS && spell != GUNS && spell != DAGGERS &&
-// spell != WANDS && spell != CROSSBOWS && spell != FIST_WEAPONS)
-// learnList.push_back(spell);
-// break;
-// case CLASS_HUNTER:
-// if (spell != ONE_HAND_MACES && spell != TWO_HAND_MACES && spell != WANDS)
-// learnList.push_back(spell);
-// break;
-// case CLASS_ROGUE:
-// if (spell != TWO_HAND_AXES && spell != TWO_HAND_MACES && spell != POLEARMS &&
-// spell != TWO_HAND_SWORDS && spell != STAVES && spell != WANDS)
-// learnList.push_back(spell);
-// break;
-// case CLASS_PRIEST:
-// if (spell == WANDS || spell == ONE_HAND_MACES || spell == STAVES ||
-// spell == DAGGERS)
-// learnList.push_back(spell);
-// break;
-// case CLASS_SHAMAN:
-// if (spell != ONE_HAND_SWORDS && spell != TWO_HAND_SWORDS && spell != POLEARMS &&
-// spell != BOWS && spell != GUNS && spell != WANDS && spell != CROSSBOWS)
-// learnList.push_back(spell);
-// break;
-// case CLASS_WARLOCK:
-// case CLASS_MAGE:
-// if (spell == WANDS || spell == ONE_HAND_SWORDS || spell == STAVES ||
-// spell == DAGGERS)
-// learnList.push_back(spell);
-// break;
-// case CLASS_DRUID:
-// if (spell != ONE_HAND_SWORDS && spell != TWO_HAND_SWORDS &&
-// spell != BOWS && spell != GUNS && spell != WANDS && spell != CROSSBOWS &&
-// spell != ONE_HAND_AXES && spell != TWO_HAND_AXES)
-// learnList.push_back(spell);
-// break;
-// default:
-// break;
-// }
-// }
-//
-// for (SkillSpells spell : learnList) {
-// if (!target->HasSpell(spell))
-// target->LearnSpell(spell, false);
-// }
-//
-// target->UpdateSkillsToMaxSkillsForLevel();
-// return true;
-// }
-//
-// static bool handleAzthXP(ChatHandler* handler, const char* args) {
-// Player *me = handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL;
-// Player *target = handler->getSelectedPlayer();
-// Player *player = NULL;
-//
-// if (!me || !me->GetSession())
-// return false;
-//
-// // first, check if I can use the command
-// if (me->GetSession()->GetSecurity() < (int) sWorld->getIntConfig(CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY)) {
-// handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
-// handler->SetSentErrorMessage(true);
-// return false;
-// }
-//
-// // If no arguments provided, show current custom XP rate
-// if (!*args) {
-// handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your current XP rate is %.2f.", me->azthPlayer->GetPlayerQuestRate());
-// return true;
-// }
-//
-// float rate = atof((char *) args);
-// float maxRate = sWorld->getFloatConfig(CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE);
-// if (rate < 0 || rate > maxRate) {
-// handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Invalid rate specified, must be in interval [0, %.2f].", maxRate);
-// handler->SetSentErrorMessage(true);
-// return false;
-// }
-//
-// // Without target; Set my XP rate
-// if (!target || !target->GetSession())
-// player = me;
-// else {
-// // Have a target AND my security level is higher than target's (I am a GM, he is a player); Set target XP rate
-// if (me->GetSession()->GetSecurity() > target->GetSession()->GetSecurity())
-// player = target;
-// else
-// player = me;
-// }
-//
-// CustomRates::SaveXpRateToDB(player, rate);
-//
-// player->azthPlayer->SetPlayerQuestRate(rate);
-//
-// if (me->azthPlayer->GetPlayerQuestRate() == 0.0f)
-// handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Quest XP Rate set to 0. You won't gain any experience from now on.");
-// else
-// handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Quest XP Rate set to %.2f.", me->azthPlayer->GetPlayerQuestRate());
-// return true;
-// }
-// };
-//
-// void AddSC_azth_commandscript() {
-// new azth_commandscript();
-// }
+ #include "Chat.h"
+ #include "ScriptMgr.h"
+ #include "AccountMgr.h"
+ #include "ArenaTeamMgr.h"
+ #include "CellImpl.h"
+ #include "GridNotifiers.h"
+ #include "Group.h"
+ #include "Language.h"
+ #include "Opcodes.h"
+ #include "Player.h"
+ #include "Pet.h"
+ #include "ReputationMgr.h"
+ #include "server/game/CustomRates.h"
+ #include "server/game/AzthSharedDefines.h"
+
+ class azth_commandscript : public CommandScript {
+ public:
+
+ azth_commandscript() : CommandScript("azth_commandscript") {}
+
+ ChatCommand* GetCommands() const {
+ static ChatCommand lookupAzthCommands[] = {
+ { "maxskill", SEC_PLAYER, true, &handleAzthMaxSkill, ""},
+ { "xp", SEC_PLAYER, false, &handleAzthXP, ""},
+ };
+
+ static ChatCommand commandTable[] = {
+ { "azth", SEC_PLAYER, true, NULL, "", lookupAzthCommands},
+ { "qc", SEC_PLAYER, true, &HandleQuestCompleterCommand, ""},
+ };
+ return commandTable;
+ }
+
+ // Based on HandleQuestComplete method of cs_quest.cpp
+
+ static bool HandleQuestCompleterCompHelper(Player* player, uint32 entry, ChatHandler* handler, char const* args, uint8 checked) {
+ if (!player) {
+ handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
+
+ // If player doesn't have the quest
+ if (!quest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE) {
+ handler->PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Add quest items for quests that require items
+ for (uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x) {
+ uint32 id = quest->RequiredItemId[x];
+ uint32 count = quest->RequiredItemCount[x];
+ if (!id || !count)
+ continue;
+
+ uint32 curItemCount = player->GetItemCount(id, true);
+
+ ItemPosCountVec dest;
+ uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, id, count - curItemCount);
+ if (msg == EQUIP_ERR_OK) {
+ Item* item = player->StoreNewItem(dest, id, true);
+ player->SendNewItem(item, count - curItemCount, true, false);
+ }
+ }
+
+ // All creature/GO slain/cast (not required, but otherwise it will display "Creature slain 0/10")
+ for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) {
+ int32 creature = quest->RequiredNpcOrGo[i];
+ uint32 creatureCount = quest->RequiredNpcOrGoCount[i];
+
+ if (creature > 0) {
+ if (CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature))
+ for (uint16 z = 0; z < creatureCount; ++z)
+ player->KilledMonster(creatureInfo, NULL);
+ } else if (creature < 0)
+ for (uint16 z = 0; z < creatureCount; ++z)
+ player->KillCreditGO(creature);
+ }
+
+ // If the quest requires reputation to complete
+ if (uint32 repFaction = quest->GetRepObjectiveFaction()) {
+ uint32 repValue = quest->GetRepObjectiveValue();
+ uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
+ if (curRep < repValue)
+ if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction))
+ player->GetReputationMgr().SetReputation(factionEntry, repValue);
+ }
+
+ // If the quest requires a SECOND reputation to complete
+ if (uint32 repFaction = quest->GetRepObjectiveFaction2()) {
+ uint32 repValue2 = quest->GetRepObjectiveValue2();
+ uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
+ if (curRep < repValue2)
+ if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction))
+ player->GetReputationMgr().SetReputation(factionEntry, repValue2);
+ }
+
+ // If the quest requires money
+ int32 ReqOrRewMoney = quest->GetRewOrReqMoney();
+ if (ReqOrRewMoney < 0)
+ player->ModifyMoney(-ReqOrRewMoney);
+
+ if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled
+ {
+ // prepare Quest Tracker datas
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_GM_COMPLETE);
+ stmt->setUInt32(0, quest->GetQuestId());
+ stmt->setUInt32(1, GUID_LOPART(player->GetGUID())); // DA VERIFICARE ----- ATTENTION ----- original was stmt->setUInt32(1, player->GetGUID()->GetCounter());
+
+ // add to Quest Tracker
+ CharacterDatabase.Execute(stmt);
+ }
+
+ player->CompleteQuest(entry);
+
+ // if bugged field is set on 2
+ // then reward the quest too
+ if (checked == 2) {
+ Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
+
+ // If player doesn't have the quest
+ if (!quest || player->GetQuestStatus(entry) != QUEST_STATUS_COMPLETE) {
+ handler->PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ player->RewardQuest(quest, 0, player);
+ }
+
+ return true;
+ }
+
+ // Based on TrueWoW code
+
+ static bool HandleQuestCompleterCommand(ChatHandler* handler, char const* args) {
+ char* cId = handler->extractKeyFromLink((char*) args, "Hquest");
+ if (!cId) {
+ handler->PSendSysMessage("Syntax: .qc $quest\n\nControlla se la $quest è buggata.");
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 entry = atol(cId);
+ Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
+ if (!quest || quest == 0) {
+ handler->PSendSysMessage("Please enter a quest link.");
+ handler->SetSentErrorMessage(true);
+ return false;
+ } else {
+ uint32 checked = 0;
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_QUESTCOMPLETER);
+ stmt->setUInt32(0, entry);
+ PreparedQueryResult resultCheck = WorldDatabase.Query(stmt);
+
+ if (!resultCheck) {
+ handler->PSendSysMessage("Errore: quest non trovata.");
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ std::string questTitle = quest->GetTitle();
+
+ checked = (*resultCheck)[0].GetUInt8();
+
+ if (checked >= 1) {
+ std::string name;
+ const char* playerName = handler->GetSession() ? handler->GetSession()->GetPlayer()->GetName().c_str() : NULL;
+
+ if (playerName) {
+ name = playerName;
+ normalizePlayerName(name);
+
+ Player* player = ObjectAccessor::FindPlayerByName(name);
+ if (player->GetQuestStatus(entry) != QUEST_STATUS_INCOMPLETE) {
+ handler->PSendSysMessage("[%s] è buggata!", questTitle.c_str());
+ return true;
+ } else {
+ HandleQuestCompleterCompHelper(player, entry, handler, args, checked);
+ handler->PSendSysMessage("[%s] è buggata ed è stata completata!", questTitle.c_str());
+ return true;
+ }
+ } else {
+ handler->PSendSysMessage("[%s] è buggata!", questTitle.c_str());
+ return true;
+ }
+ } else {
+ handler->PSendSysMessage("[%s] non risulta essere buggata, se ritieni che lo sia ti preghiamo di segnalarcelo utilizzando il bugtracker.", questTitle.c_str());
+ return true;
+ }
+ }
+ }
+
+ static bool handleAzthMaxSkill(ChatHandler* handler, const char* args) {
+
+ Player* target = handler->getSelectedPlayerOrSelf();
+ if (!target) {
+ handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ if (target->getLevel() < 80) {
+ handler->PSendSysMessage(LANG_LEVEL_MINREQUIRED, 80);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ enum SkillSpells {
+ ONE_HAND_AXES = 196,
+ TWO_HAND_AXES = 197,
+ ONE_HAND_MACES = 198,
+ TWO_HAND_MACES = 199,
+ POLEARMS = 200,
+ ONE_HAND_SWORDS = 201,
+ TWO_HAND_SWORDS = 202,
+ STAVES = 227,
+ BOWS = 264,
+ GUNS = 266,
+ DAGGERS = 1180,
+ WANDS = 5009,
+ CROSSBOWS = 5011,
+ FIST_WEAPONS = 15590
+ };
+ static const SkillSpells spells[] = {ONE_HAND_AXES, TWO_HAND_AXES, ONE_HAND_MACES,
+ TWO_HAND_MACES, POLEARMS, ONE_HAND_SWORDS, TWO_HAND_SWORDS, STAVES, BOWS,
+ GUNS, DAGGERS, WANDS, CROSSBOWS, FIST_WEAPONS};
+
+ std::list learnList;
+ for (SkillSpells spell : spells) {
+ switch (target->getClass()) {
+ case CLASS_WARRIOR:
+ if (spell != WANDS)
+ learnList.push_back(spell);
+ break;
+ case CLASS_DEATH_KNIGHT:
+ case CLASS_PALADIN:
+ if (spell != STAVES && spell != BOWS && spell != GUNS && spell != DAGGERS &&
+ spell != WANDS && spell != CROSSBOWS && spell != FIST_WEAPONS)
+ learnList.push_back(spell);
+ break;
+ case CLASS_HUNTER:
+ if (spell != ONE_HAND_MACES && spell != TWO_HAND_MACES && spell != WANDS)
+ learnList.push_back(spell);
+ break;
+ case CLASS_ROGUE:
+ if (spell != TWO_HAND_AXES && spell != TWO_HAND_MACES && spell != POLEARMS &&
+ spell != TWO_HAND_SWORDS && spell != STAVES && spell != WANDS)
+ learnList.push_back(spell);
+ break;
+ case CLASS_PRIEST:
+ if (spell == WANDS || spell == ONE_HAND_MACES || spell == STAVES ||
+ spell == DAGGERS)
+ learnList.push_back(spell);
+ break;
+ case CLASS_SHAMAN:
+ if (spell != ONE_HAND_SWORDS && spell != TWO_HAND_SWORDS && spell != POLEARMS &&
+ spell != BOWS && spell != GUNS && spell != WANDS && spell != CROSSBOWS)
+ learnList.push_back(spell);
+ break;
+ case CLASS_WARLOCK:
+ case CLASS_MAGE:
+ if (spell == WANDS || spell == ONE_HAND_SWORDS || spell == STAVES ||
+ spell == DAGGERS)
+ learnList.push_back(spell);
+ break;
+ case CLASS_DRUID:
+ if (spell != ONE_HAND_SWORDS && spell != TWO_HAND_SWORDS &&
+ spell != BOWS && spell != GUNS && spell != WANDS && spell != CROSSBOWS &&
+ spell != ONE_HAND_AXES && spell != TWO_HAND_AXES)
+ learnList.push_back(spell);
+ break;
+ default:
+ break;
+ }
+ }
+
+ for (SkillSpells spell : learnList) {
+ if (!target->HasSpell(spell))
+ target->learnSpell(spell);
+ }
+
+ target->UpdateSkillsToMaxSkillsForLevel();
+ return true;
+ }
+
+ static bool handleAzthXP(ChatHandler* handler, const char* args) {
+ Player *me = handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL;
+ Player *target = handler->getSelectedPlayer();
+ Player *player = NULL;
+
+ if (!me || !me->GetSession())
+ return false;
+
+ // first, check if I can use the command
+ if (me->GetSession()->GetSecurity() < (int) sWorld->getIntConfig(CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY)) {
+ handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ // If no arguments provided, show current custom XP rate
+ if (!*args) {
+ handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your current XP rate is %.2f.", me->azthPlayer->GetPlayerQuestRate());
+ return true;
+ }
+
+ float rate = atof((char *) args);
+ float maxRate = sWorld->getFloatConfig(CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE);
+ if (rate < 0 || rate > maxRate) {
+ handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Invalid rate specified, must be in interval [0, %.2f].", maxRate);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Without target; Set my XP rate
+ if (!target || !target->GetSession())
+ player = me;
+ else {
+ // Have a target AND my security level is higher than target's (I am a GM, he is a player); Set target XP rate
+ if (me->GetSession()->GetSecurity() > target->GetSession()->GetSecurity())
+ player = target;
+ else
+ player = me;
+ }
+
+ CustomRates::SaveXpRateToDB(player, rate);
+
+ player->azthPlayer->SetPlayerQuestRate(rate);
+
+ if (me->azthPlayer->GetPlayerQuestRate() == 0.0f)
+ handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Quest XP Rate set to 0. You won't gain any experience from now on.");
+ else
+ handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Quest XP Rate set to %.2f.", me->azthPlayer->GetPlayerQuestRate());
+ return true;
+ }
+ };
+
+ void AddSC_azth_commandscript() {
+ new azth_commandscript();
+ }
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 0d6806eecc..b30e92cd16 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -339,7 +339,8 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID,
}
data << uint32(quest->GetRewOrReqMoney());
- data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST));
+ //[AZTH]
+ data << uint32(quest->XPValue(_session->GetPlayer()) * _session->GetPlayer()->azthPlayer->GetPlayerQuestRate());
}
// rewarded honor points. Multiply with 10 to satisfy client
@@ -430,7 +431,8 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, b
}
data << uint32(quest->GetRewOrReqMoney());
- data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST));
+ //[AZTH]
+ data << uint32(quest->XPValue(_session->GetPlayer()) * _session->GetPlayer()->azthPlayer->GetPlayerQuestRate());
// rewarded honor points. Multiply with 10 to satisfy client
data << uint32(10 * quest->CalculateHonorGain(_session->GetPlayer()->GetQuestLevel(quest)));
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 4d898fe5ad..cd1b1fa30b 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -15598,7 +15598,8 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
bool rewarded = IsQuestRewarded(quest_id) && !quest->IsDFQuest();
// Not give XP in case already completed once repeatable quest
- uint32 XP = rewarded ? 0 : uint32(quest->XPValue(this)*sWorld->getRate(RATE_XP_QUEST));
+ // [AZTH]
+ uint32 XP = rewarded && !quest->IsDFQuest() ? 0 : uint32(quest->XPValue(this) * azthPlayer->GetPlayerQuestRate());
// handle SPELL_AURA_MOD_XP_QUEST_PCT auras
Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT);
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index bbb05210f8..1814d39015 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1226,6 +1226,14 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT] = sConfigMgr->GetIntDefault("Anticheat.MaxReportsForDailyReport", 70);
//[AZTH]
+ // [AZTH]
+ m_int_configs[CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY] = sConfigMgr->GetIntDefault("Player.customXP.security", 0);
+ m_float_configs[CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE] = sConfigMgr->GetFloatDefault("Player.customXP.maxValue", 1);
+ m_bool_configs[CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SHOW_ON_LOGIN] = sConfigMgr->GetBoolDefault("Player.customXP.showOnLogin", false);
+ m_int_configs[CONFIG_EXTERNAL_MAIL] = sConfigMgr->GetIntDefault("ExternalMail", 0);
+ m_int_configs[CONFIG_EXTERNAL_MAIL_INTERVAL] = sConfigMgr->GetIntDefault("ExternalMailInterval", 1);
+ // [/AZTH]
+
// DBC_ItemAttributes
m_bool_configs[CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES] = sConfigMgr->GetBoolDefault("DBC.EnforceItemAttributes", true);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 9cadecc0b5..39d73fba10 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -156,9 +156,11 @@ enum WorldBoolConfigs
CONFIG_DONT_CACHE_RANDOM_MOVEMENT_PATHS, // pussywizard
CONFIG_QUEST_IGNORE_AUTO_ACCEPT,
CONFIG_QUEST_IGNORE_AUTO_COMPLETE,
+ CONFIG_QUEST_ENABLE_QUEST_TRACKER, // [AZTH]
CONFIG_WARDEN_ENABLED,
CONFIG_ANTICHEAT_ENABLE, //[AZTH]
CONFIG_EXTERNAL_MAIL, //[AZTH]
+ CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SHOW_ON_LOGIN, //[AZTH]
BOOL_CONFIG_VALUE_COUNT
};
@@ -174,6 +176,7 @@ enum WorldFloatConfigs
CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS,
CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS,
CONFIG_CHANCE_OF_GM_SURVEY,
+ CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE, //[AZTH]
FLOAT_CONFIG_VALUE_COUNT
};
@@ -325,6 +328,7 @@ enum WorldIntConfigs
CONFIG_ANTICHEAT_REPORTS_INGAME_NOTIFICATION, //[AZTH]
CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT, //[AZTH]
CONFIG_ANTICHEAT_DETECTIONS_ENABLED, //[AZTH]
+ CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY, //[AZTH]
INT_CONFIG_VALUE_COUNT
};
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index c0f8a63e8f..66cfe197a2 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -565,4 +565,11 @@ void CharacterDatabaseConnection::DoPrepareStatements()
// Deserter tracker
PrepareStatement(CHAR_INS_DESERTER_TRACK, "INSERT INTO battleground_deserters (guid, type, datetime) VALUES (?, ?, NOW())", CONNECTION_ASYNC);
+
+ // [AZTH] Custom XP rate
+ PrepareStatement(CHAR_INS_INDIVIDUAL_XP_RATE, "INSERT INTO character_xp_rate (guid, xp_rate) VALUES (?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_INDIVIDUAL_XP_RATE, "DELETE FROM character_xp_rate WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_INDIVIDUAL_XP_RATE, "SELECT xp_rate FROM character_xp_rate WHERE guid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_UPD_INDIVIDUAL_XP_RATE, "UPDATE character_xp_rate SET xp_rate = ? WHERE guid = ?", CONNECTION_ASYNC);
+ // [/AZTH]
}
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 1ee0d38dc9..19ab2f84a8 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -501,6 +501,15 @@ enum CharacterDatabaseStatements
CHAR_SEL_PVPSTATS_FACTIONS_OVERALL,
CHAR_INS_DESERTER_TRACK,
+
+ CHAR_UPD_QUEST_TRACK_GM_COMPLETE,
+
+ // [AZTH]
+ CHAR_INS_INDIVIDUAL_XP_RATE,
+ CHAR_DEL_INDIVIDUAL_XP_RATE,
+ CHAR_SEL_INDIVIDUAL_XP_RATE,
+ CHAR_UPD_INDIVIDUAL_XP_RATE,
+ // [/AZTH]
MAX_CHARACTERDATABASE_STATEMENTS
};
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp
index fda540c42e..f353c26782 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp
@@ -89,4 +89,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_INS_DISABLES, "INSERT INTO disables (entry, sourceType, flags, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_DISABLES, "SELECT entry FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_DISABLES, "DELETE FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_ASYNC);
+ // [AZTH]
+ PrepareStatement(WORLD_SEL_QUESTCOMPLETER, "SELECT bugged FROM quest_bugged WHERE ID = ?", CONNECTION_SYNCH);
+ // [/AZTH]
}
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h
index 340d2453a7..ab9211b39c 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.h
+++ b/src/server/shared/Database/Implementation/WorldDatabase.h
@@ -110,6 +110,9 @@ enum WorldDatabaseStatements
WORLD_SEL_DISABLES,
WORLD_INS_DISABLES,
WORLD_DEL_DISABLES,
+ // [AZTH]
+ WORLD_SEL_QUESTCOMPLETER,
+ // [/AZTH]
MAX_WORLDDATABASE_STATEMENTS
};
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 00330bf9a7..1cfd9e622d 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -3221,4 +3221,27 @@ Anticheat.MaxReportsForDailyReport = 30
PvPRank.Rate.ExtraHonor = 1
PvPRank.HKPerRank = 10,50,100,200,450,750,1300,2000,3500,6000,9500,15000,21000,30000
+###################################################################################################
+
+Azth.Rate.Arena1v1 = 0.2;
+
+###################################################################################################
+# CUSTOM PLAYER XP CONFIGS
+###################################################################################################
+# Player.customXP.security
+# Description: Needed security level to run ".azth xp" command
+# Default: 3
+#
+# Player.customXP.maxValue
+# Description: Maximum custom XP multiplier. Watch out: The xp gained is calculated this way: (XP * Rate.XP) * Player.customXP
+# Default: 1 (Default XP rate)
+#
+# Player.customXP.showOnLogin
+# Description: Show custom xp value on login
+# Default: 0 (Don't show message)
+
+Player.customXP.security = 0
+Player.customXP.maxValue = 1.5
+Player.customXP.showOnLogin = 1
+
###################################################################################################
\ No newline at end of file