Skip to content

Commit

Permalink
update choice nodes for learn and unlearn
Browse files Browse the repository at this point in the history
  • Loading branch information
hatersgit committed Oct 30, 2023
1 parent 6cb0d2b commit 39828ee
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 45 deletions.
36 changes: 27 additions & 9 deletions modules/mod-Forge/src/ForgeCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct ForgeCharacterTalent
uint32 SpellId;
uint32 TabId;
uint8 CurrentRank;
uint8 type;
};

struct ForgeTalentPrereq
Expand Down Expand Up @@ -559,12 +560,23 @@ class ForgeCache : public DatabaseScript

for (auto& tabIdKvp : spec->Talents)
for (auto& tabTypeKvp : tabIdKvp.second)
UpdateChacterTalentInternal(acct, charId, trans, spec->Id, tabTypeKvp.second->SpellId, tabTypeKvp.second->TabId, tabTypeKvp.second->CurrentRank);
if (tabTypeKvp.second->type == NodeType::CHOICE)
UpdateChacterChoiceNodeInternal(trans, acct, charId, spec->Id, tabTypeKvp.second->TabId, tabTypeKvp.second->SpellId, spec->ChoiceNodesChosen.at(tabTypeKvp.second->SpellId));
else
UpdateChacterTalentInternal(acct, charId, trans, spec->Id, tabTypeKvp.second->SpellId, tabTypeKvp.second->TabId, tabTypeKvp.second->CurrentRank);


CharacterDatabase.CommitTransaction(trans);
}

void UpdateChacterChoiceNodeInternal(CharacterDatabaseTransaction trans, uint32 account, uint32 guid, uint32 specId, uint32 tabId, uint32 choiceNodeId, uint32 choiceNodeSelection) {
if (TalentTabs[tabId]->TalentType != ACCOUNT_WIDE_TYPE)
trans->Append("INSERT INTO `forge_character_node_choices` (`guid`,`spec`,`tabId`,`node`,`choice`) VALUES ({},{},{},{},{}) ON DUPLICATE KEY UPDATE `choice` = {}",
guid, specId, choiceNodeId, tabId, choiceNodeSelection, choiceNodeSelection);
else
trans->Append("INSERT INTO `forge_character_node_choices` (`guid`,`spec`,`tabId`,`node`,`choice`) VALUES ({},{},{},{},{}) ON DUPLICATE KEY UPDATE `choice` = {}",
account, ACCOUNT_WIDE_KEY, choiceNodeId, tabId, choiceNodeSelection, choiceNodeSelection);
}

void UpdateCharacterSpecDetailsOnly(Player* player, ForgeCharacterSpec*& spec)
{
uint32 charId = player->GetGUID().GetCounter();
Expand All @@ -574,13 +586,6 @@ class ForgeCache : public DatabaseScript
CharacterDatabase.CommitTransaction(trans);
}

void UpdateChacterTalent(Player* player, uint32 spec, uint32 spellId, uint32 tabId, uint8 known)
{
auto trans = CharacterDatabase.BeginTransaction();
UpdateChacterTalentInternal(player->GetSession()->GetAccountId(), player->GetGUID().GetCounter(), trans, spec, spellId, tabId, known);
CharacterDatabase.CommitTransaction(trans);
}

void ApplyAccountBoundTalents(Player* player)
{
ForgeCharacterSpec* currentSpec;
Expand Down Expand Up @@ -871,6 +876,15 @@ class ForgeCache : public DatabaseScript

// choiceNodeId is the id of the node in forge_talents
std::unordered_map<uint32 /*nodeid*/, std::vector<uint32/*choice spell id*/>> _choiceNodes;
std::unordered_map<uint32 /*choice spell id*/, uint32 /*nodeid*/> _choiceNodesRev;

uint32 GetChoiceNodeFromSpell(uint32 spellId) {
auto out = _choiceNodesRev.find(spellId);
if (out != _choiceNodesRev.end())
return out->second;

return 0;
}

private:
std::unordered_map<ObjectGuid, uint32> CharacterActiveSpecs;
Expand Down Expand Up @@ -1278,6 +1292,7 @@ class ForgeCache : public DatabaseScript
QueryResult exclTalents = WorldDatabase.Query("SELECT * FROM forge_talent_choice_nodes");

_choiceNodes.clear();
_choiceNodesRev.clear();

if (!exclTalents)
return;
Expand All @@ -1294,6 +1309,7 @@ class ForgeCache : public DatabaseScript
choice->spellId = spellChoice;

_choiceNodes[choiceNodeId].push_back(spellChoice);
_choiceNodesRev[spellChoice] = choiceNodeId;

ForgeTalent* lt = TalentTabs[talentTabId]->Talents[choiceNodeId];
if (lt != nullptr)
Expand Down Expand Up @@ -1478,6 +1494,7 @@ class ForgeCache : public DatabaseScript
{
ForgeTalent* ft = TalentTabs[talent->TabId]->Talents[talent->SpellId];
ForgeCharacterSpec* spec = CharacterSpecs[characterGuid][specId];
talent->type = ft->nodeType;

spec->Talents[talent->TabId][talent->SpellId] = talent;
}
Expand All @@ -1489,6 +1506,7 @@ class ForgeCache : public DatabaseScript
for (auto& spec : CharacterSpecs[ch])
{
ForgeTalent* ft = TalentTabs[talent->TabId]->Talents[talent->SpellId];
talent->type = ft->nodeType;
spec.second->Talents[talent->TabId][talent->SpellId] = talent;
}
}
Expand Down
21 changes: 14 additions & 7 deletions modules/mod-Forge/src/ForgeCommonMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,24 +394,31 @@ std::string ForgeCommonMessage::DoBuildRanks(std::unordered_map<uint32, ForgeCha
{
int i = 0;
ForgeTalentTab* tab;
ForgeCharacterSpec* fs;


if (fc->TryGetTalentTab(player, tabId, tab))
if (fc->TryGetTalentTab(player, tabId, tab) && fc->TryGetCharacterActiveSpec(player, fs))
{
for(auto& sp : tab->Talents)
{
std::string delimiter = "*";

if (i == 0)
delimiter = "";

auto itt = spec.find(sp.first);

if (itt != spec.end())
if (itt->second->CurrentRank == 0 && !CanLearnTalent(player, tabId, sp.second->SpellId))
clientMsg = clientMsg + delimiter + std::to_string(sp.second->SpellId) + "~-1";
if (itt != spec.end()) {
if (itt->second->type == NodeType::CHOICE)
if (itt->second->CurrentRank == 0 || !CanLearnTalent(player, tabId, sp.second->SpellId))
clientMsg = clientMsg + delimiter + std::to_string(sp.second->SpellId) + "~-1";
else
clientMsg = clientMsg + delimiter + std::to_string(itt->second->SpellId) + "~" + std::to_string(fs->ChoiceNodesChosen.at(itt->second->SpellId));
else
clientMsg = clientMsg + delimiter + std::to_string(itt->second->SpellId) + "~" + std::to_string(itt->second->CurrentRank);
if (itt->second->CurrentRank == 0 && !CanLearnTalent(player, tabId, sp.second->SpellId))
clientMsg = clientMsg + delimiter + std::to_string(sp.second->SpellId) + "~-1";
else
clientMsg = clientMsg + delimiter + std::to_string(itt->second->SpellId) + "~" + std::to_string(itt->second->CurrentRank);
}
else if (!CanLearnTalent(player, tabId, sp.second->SpellId))
clientMsg = clientMsg + delimiter + std::to_string(sp.second->SpellId) + "~-1";
else
Expand Down
60 changes: 36 additions & 24 deletions modules/mod-Forge/src/TopicHandlers/LearnTalentHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ class LearnTalentHandler : public ForgeTopicHandler
std::vector<std::string> results;
boost::algorithm::split(results, iam.message, boost::is_any_of(";"));

if (results.empty() || results.size() != 2 || !fc->isNumber(results[0]) || !fc->isNumber(results[1]))
if (results.empty() || results.size() != 3 || !fc->isNumber(results[0]) || !fc->isNumber(results[1]) || !fc->isNumber(results[2]))
return;

uint32 tabId = static_cast<uint32>(std::stoul(results[0]));
uint32 spellId = static_cast<uint32>(std::stoul(results[1]));
uint32 nodeType = static_cast<uint32>(std::stoul(results[2]));

bool choiceNode = nodeType == NodeType::CHOICE;

ForgeTalentTab* tab;
ForgeCharacterSpec* spec;
CharacterPointType tabType;
Expand All @@ -52,7 +56,12 @@ class LearnTalentHandler : public ForgeTopicHandler
}

// check dependants, rank requirements
auto talItt = tab->Talents.find(spellId);
uint32 choiceId = fc->GetChoiceNodeFromSpell(spellId);
if (!choiceId && choiceNode) {
iam.player->SendForgeUIMsg(ForgeTopic::LEARN_TALENT_ERROR, "Attempt to unlearn unknown choice node talent: " + std::to_string(choiceId));
return;
}
auto talItt = choiceNode ? tab->Talents.find(choiceId) : tab->Talents.find(spellId);

if (talItt == tab->Talents.end())
{
Expand Down Expand Up @@ -184,18 +193,6 @@ class LearnTalentHandler : public ForgeTopicHandler
}
}

// TODO: FIX
//for (auto& exclu : ft->Choices)
//{
// auto typeItt = skillTabs.find(exclu);

// if (typeItt != skillTabs.end() && typeItt->second->CurrentRank > 0)
// {
// RequirementsNotMet(iam);
// return;
// }
//}

auto spellItter = skillTabs.find(ft->SpellId);
ForgeCharacterTalent* ct = new ForgeCharacterTalent();

Expand All @@ -204,6 +201,7 @@ class LearnTalentHandler : public ForgeTopicHandler
ct->CurrentRank = 0;
ct->SpellId = ft->SpellId;
ct->TabId = tabId;
ct->type = ft->nodeType;
spec->Talents[tabId][ft->SpellId] = ct;
}
else
Expand All @@ -223,25 +221,39 @@ class LearnTalentHandler : public ForgeTopicHandler

auto ranksItt = ft->Ranks.find(ct->CurrentRank);

if (ranksItt != ft->Ranks.end()) {
auto spellInfo = sSpellMgr->GetSpellInfo(ranksItt->second);
if (!spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE))
iam.player->removeSpell(ranksItt->second, SPEC_MASK_ALL, false);
if (!choiceNode)
if (ranksItt != ft->Ranks.end()) {
auto spellInfo = sSpellMgr->GetSpellInfo(ranksItt->second);
if (!spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE))
iam.player->removeSpell(ranksItt->second, SPEC_MASK_ALL, false);
else
iam.player->RemoveAura(ranksItt->second);
}
else
iam.player->RemoveAura(ranksItt->second);
}
for (auto s : ft->Choices)
iam.player->removeSpell(s->spellId, SPEC_MASK_ALL, false);

ct->CurrentRank++;

ranksItt = ft->Ranks.find(ct->CurrentRank);

if (ranksItt != ft->Ranks.end()) {
auto spellInfo = sSpellMgr->GetSpellInfo(ranksItt->second);
if (choiceNode) {
auto spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE))
iam.player->learnSpell(ranksItt->second);
iam.player->learnSpell(spellId);
else
iam.player->AddAura(ranksItt->second, iam.player);
iam.player->AddAura(spellId, iam.player);

spec->ChoiceNodesChosen[choiceId] = spellId;
}
else
if (ranksItt != ft->Ranks.end()) {
auto spellInfo = sSpellMgr->GetSpellInfo(ranksItt->second);
if (!spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE))
iam.player->learnSpell(ranksItt->second);
else
iam.player->AddAura(ranksItt->second, iam.player);
}

fc->UpdateCharPoints(iam.player, curPoints);
fc->UpdateCharacterSpec(iam.player, spec);
Expand Down
26 changes: 21 additions & 5 deletions modules/mod-Forge/src/TopicHandlers/UnlearnTalentHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,27 @@ class UnlearnTalentHandler : public ForgeTopicHandler
sfp->Sum += refund;
sfp->Max -= refund;

auto spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE))
iam.player->RemoveOwnedAura(tab->Talents[spellId]->Ranks[spellItt->second->CurrentRank]);
else
iam.player->removeSpell(tab->Talents[spellId]->Ranks[spellItt->second->CurrentRank], SPEC_MASK_ALL, false);
if (spellItt->second->type == NodeType::CHOICE) {
auto chosen = spec->ChoiceNodesChosen.find(spellId);

if (chosen == spec->ChoiceNodesChosen.end()) {
iam.player->SendForgeUIMsg(ForgeTopic::UNLEARN_TALENT_ERROR, "Attempted to forget unknown choice node talent.");
return;
}

auto spellInfo = sSpellMgr->GetSpellInfo(chosen->second);
if (spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE))
iam.player->RemoveOwnedAura(chosen->second);
else
iam.player->removeSpell(chosen->second, SPEC_MASK_ALL, false);
}
else {
auto spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE))
iam.player->RemoveOwnedAura(tab->Talents[spellId]->Ranks[spellItt->second->CurrentRank]);
else
iam.player->removeSpell(tab->Talents[spellId]->Ranks[spellItt->second->CurrentRank], SPEC_MASK_ALL, false);
}

iam.player->UpdateAllStats();
spellItt->second->CurrentRank = 0;
Expand Down

0 comments on commit 39828ee

Please sign in to comment.