-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
360 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,4 +14,4 @@ | |
# 1 - Enabled | ||
# | ||
|
||
MyModule.Enable = 1 | ||
Attriboost.Enable = 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
UPDATE item_template | ||
SET | ||
name = "Book of Knowledge", | ||
description = "|cff00FF00Use: Increases a random attribute related to your class.|cffF7B500", | ||
BuyPrice = 0, | ||
SellPrice = 0, | ||
RequiredSkill = 0, | ||
RequiredSkillRank = 0, | ||
RequiredLevel = 1, | ||
ItemLevel = 1, | ||
Stackable = 200, | ||
spellid_1 = 18282, | ||
bonding = 1 | ||
WHERE entry = 16073; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
#include "Attriboost.h" | ||
|
||
#include "Chat.h" | ||
#include "Config.h" | ||
#include "Spell.h" | ||
|
||
void AttriboostPlayerScript::OnLogin(Player* player) | ||
{ | ||
if (!player) | ||
{ | ||
return; | ||
} | ||
|
||
if (!sConfigMgr->GetOption<bool>("Attriboost.Enable", false)) | ||
{ | ||
return; | ||
} | ||
|
||
auto attributes = GetAttriboosts(player->GetGUID().GetRawValue()); | ||
ApplyAttributes(player, attributes); | ||
} | ||
|
||
bool AttriboostPlayerScript::CanUseItem(Player* player, ItemTemplate const* proto, InventoryResult& /*result*/) | ||
{ | ||
if (!proto) | ||
{ | ||
return true; | ||
} | ||
|
||
if (proto->ItemId != ATTR_ITEM) | ||
{ | ||
return true; | ||
} | ||
|
||
if (!sConfigMgr->GetOption<bool>("Attriboost.Enable", false)) | ||
{ | ||
ChatHandler(player->GetSession()).SendSysMessage("This item is disabled."); | ||
return false; | ||
} | ||
|
||
auto attribute = GetRandomAttributeForClass(player); | ||
if (!attribute) | ||
{ | ||
LOG_WARN("module", "Failed to get random attribute for player '{}'.", player->GetName()); | ||
return false; | ||
} | ||
|
||
auto attributes = GetAttriboosts(player->GetGUID().GetRawValue()); | ||
AddAttribute(attributes, attribute); | ||
ApplyAttributes(player, attributes); | ||
|
||
auto attributeName = GetAttributeName(attribute); | ||
if (!attributeName.empty()) | ||
{ | ||
ChatHandler(player->GetSession()).SendSysMessage(Acore::StringFormatFmt("Increased {} by 1.", GetAttributeName(attribute))); | ||
} | ||
|
||
player->DestroyItemCount(ATTR_ITEM, 1, true); | ||
|
||
return true; | ||
} | ||
|
||
uint32 AttriboostPlayerScript::GetRandomAttributeForClass(Player* player) | ||
{ | ||
switch (player->getClass()) | ||
{ | ||
case CLASS_ROGUE: | ||
switch (urand(0, 2)) | ||
{ | ||
case 0: | ||
return ATTR_SPELL_STAMINA; | ||
case 1: | ||
return ATTR_SPELL_AGILITY; | ||
case 2: | ||
return ATTR_SPELL_STRENGTH; | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
std::string AttriboostPlayerScript::GetAttributeName(uint32 attribute) | ||
{ | ||
switch (attribute) | ||
{ | ||
case ATTR_SPELL_STAMINA: | ||
return "Stamina"; | ||
|
||
case ATTR_SPELL_STRENGTH: | ||
return "Strength"; | ||
|
||
case ATTR_SPELL_AGILITY: | ||
return "Agility"; | ||
|
||
case ATTR_SPELL_INTELLECT: | ||
return "Intellect"; | ||
|
||
case ATTR_SPELL_SPIRIT: | ||
return "Spirit"; | ||
} | ||
|
||
return std::string(); | ||
} | ||
|
||
Attriboosts* GetAttriboosts(uint64 guid) | ||
{ | ||
auto attri = attriboostsMap.find(guid); | ||
if (attri == attriboostsMap.end()) | ||
{ | ||
Attriboosts attriboosts; | ||
attriboosts.Stamina = 0; | ||
attriboosts.Strength = 0; | ||
attriboosts.Agility = 0; | ||
attriboosts.Intellect = 0; | ||
attriboosts.Spirit = 0; | ||
|
||
auto result = attriboostsMap.emplace(guid, attriboosts); | ||
attri = result.first; | ||
} | ||
|
||
return &attri->second; | ||
} | ||
|
||
void ClearAttriboosts() | ||
{ | ||
attriboostsMap.clear(); | ||
} | ||
|
||
void LoadAttriboosts() | ||
{ | ||
auto qResult = CharacterDatabase.Query("SELECT * FROM attriboost_attributes"); | ||
|
||
if (!qResult) | ||
{ | ||
LOG_ERROR("module", "Failed to load from 'attriboost_attributes' table."); | ||
return; | ||
} | ||
|
||
LOG_INFO("module", "Loading player attriboosts from 'attriboost_attributes'.."); | ||
|
||
int count = 0; | ||
|
||
do | ||
{ | ||
auto fields = qResult->Fetch(); | ||
|
||
uint64 guid = fields[0].Get<uint64>(); | ||
|
||
Attriboosts attriboosts; | ||
attriboosts.Stamina = fields[1].Get<uint64>(); | ||
attriboosts.Strength = fields[2].Get<uint64>(); | ||
attriboosts.Agility = fields[3].Get<uint64>(); | ||
attriboosts.Intellect = fields[4].Get<uint64>(); | ||
attriboosts.Spirit = fields[5].Get<uint64>(); | ||
|
||
attriboostsMap.emplace(guid, attriboosts); | ||
|
||
count++; | ||
} while (qResult->NextRow()); | ||
|
||
LOG_INFO("module", "Loaded '{}' player attriboosts.", count); | ||
} | ||
|
||
void SaveAttriboosts() | ||
{ | ||
for (auto it = attriboostsMap.begin(); it != attriboostsMap.end(); ++it) | ||
{ | ||
auto guid = it->first; | ||
|
||
auto stamina = it->second.Stamina; | ||
auto strength = it->second.Strength; | ||
auto agility = it->second.Agility; | ||
auto intellect = it->second.Intellect; | ||
auto spirit = it->second.Spirit; | ||
|
||
CharacterDatabase.Execute("INSERT INTO `attriboost_attributes` (guid, stamina, strength, agility, intellect, spirit) VALUES ({}, {}, {}, {}, {}, {}) ON DUPLICATE KEY UPDATE stamina={}, strength={}, agility={}, intellect={}, spirit={}", | ||
guid, | ||
stamina, strength, agility, intellect, spirit, | ||
stamina, strength, agility, intellect, spirit); | ||
} | ||
} | ||
|
||
void ApplyAttributes(Player* player, Attriboosts* attributes) | ||
{ | ||
if (attributes->Stamina > 0) | ||
{ | ||
auto stamina = player->GetAura(ATTR_SPELL_STAMINA); | ||
if (!stamina) | ||
{ | ||
stamina = player->AddAura(ATTR_SPELL_STAMINA, player); | ||
} | ||
stamina->SetStackAmount(attributes->Stamina); | ||
} | ||
|
||
if (attributes->Strength > 0) | ||
{ | ||
auto strength = player->GetAura(ATTR_SPELL_STRENGTH); | ||
if (!strength) | ||
{ | ||
strength = player->AddAura(ATTR_SPELL_STRENGTH, player); | ||
} | ||
strength->SetStackAmount(attributes->Strength); | ||
} | ||
|
||
if (attributes->Agility > 0) | ||
{ | ||
auto agility = player->GetAura(ATTR_SPELL_AGILITY); | ||
if (!agility) | ||
{ | ||
agility = player->AddAura(ATTR_SPELL_AGILITY, player); | ||
} | ||
agility->SetStackAmount(attributes->Agility); | ||
} | ||
|
||
if (attributes->Intellect > 0) | ||
{ | ||
auto intellect = player->GetAura(ATTR_SPELL_INTELLECT); | ||
if (!intellect) | ||
{ | ||
intellect = player->AddAura(ATTR_SPELL_INTELLECT, player); | ||
} | ||
intellect->SetStackAmount(attributes->Intellect); | ||
} | ||
|
||
if (attributes->Spirit > 0) | ||
{ | ||
auto spirit = player->GetAura(ATTR_SPELL_SPIRIT); | ||
if (!spirit) | ||
{ | ||
spirit = player->AddAura(ATTR_SPELL_SPIRIT, player); | ||
} | ||
spirit->SetStackAmount(attributes->Spirit); | ||
} | ||
} | ||
|
||
void AddAttribute(Attriboosts* attributes, uint32 attribute) | ||
{ | ||
switch (attribute) | ||
{ | ||
case ATTR_SPELL_STAMINA: | ||
attributes->Stamina += 1; | ||
break; | ||
|
||
case ATTR_SPELL_STRENGTH: | ||
attributes->Strength += 1; | ||
break; | ||
|
||
case ATTR_SPELL_AGILITY: | ||
attributes->Agility += 1; | ||
break; | ||
|
||
case ATTR_SPELL_INTELLECT: | ||
attributes->Intellect += 1; | ||
break; | ||
|
||
case ATTR_SPELL_SPIRIT: | ||
attributes->Spirit += 1; | ||
break; | ||
} | ||
} | ||
|
||
void AttriboostWorldScript::OnAfterConfigLoad(bool reload) | ||
{ | ||
if (reload) | ||
{ | ||
ClearAttriboosts(); | ||
} | ||
|
||
LoadAttriboosts(); | ||
} | ||
|
||
void AttriboostWorldScript::OnShutdownInitiate(ShutdownExitCode /*code*/, ShutdownMask /*mask*/) | ||
{ | ||
SaveAttriboosts(); | ||
} | ||
|
||
void SC_AddAttriboostScripts() | ||
{ | ||
new AttriboostWorldScript(); | ||
new AttriboostPlayerScript(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#ifndef MODULE_ATTRIBOOST_H | ||
#define MODULE_ATTRIBOOST_H | ||
|
||
#include "ScriptMgr.h" | ||
#include "Player.h" | ||
|
||
#include <unordered_map> | ||
|
||
enum AttriboostItems | ||
{ | ||
ATTR_ITEM = 16073 | ||
}; | ||
|
||
enum AttriboostStats | ||
{ | ||
ATTR_SPELL_STAMINA = 7477, | ||
ATTR_SPELL_AGILITY = 7471, | ||
ATTR_SPELL_INTELLECT = 7468, | ||
ATTR_SPELL_STRENGTH = 7464, | ||
ATTR_SPELL_SPIRIT = 7474 | ||
}; | ||
|
||
struct Attriboosts | ||
{ | ||
uint32 Stamina; | ||
uint32 Strength; | ||
uint32 Agility; | ||
uint32 Intellect; | ||
uint32 Spirit; | ||
}; | ||
|
||
std::unordered_map<uint64, Attriboosts> attriboostsMap; | ||
|
||
Attriboosts* GetAttriboosts(uint64 /*guid*/); | ||
void ClearAttriboosts(); | ||
void LoadAttriboosts(); | ||
void ApplyAttributes(Player* /*player*/, Attriboosts* /*attributes*/); | ||
void AddAttribute(Attriboosts* /*attributes*/, uint32 /*attribute*/); | ||
|
||
class AttriboostPlayerScript : public PlayerScript | ||
{ | ||
public: | ||
AttriboostPlayerScript() : PlayerScript("AttriboostPlayerScript") { } | ||
|
||
virtual void OnLogin(Player* /*player*/) override; | ||
virtual bool CanUseItem(Player* /*player*/, ItemTemplate const* /*proto*/, InventoryResult& /*result*/) override; | ||
|
||
uint32 GetRandomAttributeForClass(Player* /*player*/); | ||
std::string GetAttributeName(uint32 /*attribute*/); | ||
}; | ||
|
||
class AttriboostWorldScript : public WorldScript | ||
{ | ||
public: | ||
AttriboostWorldScript() : WorldScript("AttriboostWorldScript") { } | ||
|
||
virtual void OnAfterConfigLoad(bool /*reload*/) override; | ||
virtual void OnShutdownInitiate(ShutdownExitCode /*code*/, ShutdownMask /*mask*/) override; | ||
}; | ||
|
||
#endif // MODULE_ATTRIBOOST_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,7 @@ | ||
/* | ||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 | ||
*/ | ||
void SC_AddAttriboostScripts(); | ||
|
||
// From SC | ||
void AddMyPlayerScripts(); | ||
|
||
// Add all | ||
// cf. the naming convention https://github.com/azerothcore/azerothcore-wotlk/blob/master/doc/changelog/master.md#how-to-upgrade-4 | ||
// additionally replace all '-' in the module folder name with '_' here | ||
void Addskeleton_moduleScripts() | ||
void AddAttriboostScripts() | ||
{ | ||
AddMyPlayerScripts(); | ||
SC_AddAttriboostScripts(); | ||
} | ||
|
Oops, something went wrong.