Skip to content

Commit

Permalink
add autolearn
Browse files Browse the repository at this point in the history
  • Loading branch information
hatersgit committed Dec 2, 2023
1 parent 07c7b3a commit 29069cc
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 143 deletions.
12 changes: 2 additions & 10 deletions modules/mod-Forge/sql/world/updates/20231106 starter talents.sql
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
drop table if exists `acore_world`.`forge_character_spec_strarter_talents`;
CREATE TABLE `acore_world`.`forge_character_spec_strarter_talents` (
`class` INT(10) UNSIGNED NOT NULL,
`tab` INT(10) UNSIGNED NOT NULL,
`spell` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`class`,`tab`,`spell`)
) COLLATE='utf8_general_ci' ENGINE=InnoDB;

drop table if exists `acore_world`.`forge_character_spec_spells`;
CREATE TABLE `acore_world`.`forge_character_spec_spells` (
`class` INT(10) UNSIGNED NOT NULL,
`tab` INT(10) UNSIGNED NOT NULL,
`race` INT(10) UNSIGNED NOT NULL,
`level` INT(10) UNSIGNED NOT NULL,
`spell` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`class`,`tab`,`spell`)
PRIMARY KEY (`class`, `race`,`spell`)
) COLLATE='utf8_general_ci' ENGINE=InnoDB;
46 changes: 6 additions & 40 deletions modules/mod-Forge/src/ForgeCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -891,8 +891,7 @@ class ForgeCache : public DatabaseScript
return 0;
}

std::unordered_map<uint8 /*level*/, std::unordered_map<uint8/*class*/, std::unordered_map<uint32 /*tabId*/, std::vector<uint32 /*spell*/>>>> _levelClassSpellMap;
std::unordered_map<uint32 /*class*/, std::unordered_map<uint32 /*tab*/, std::vector<uint32/*spellId*/>>> _specStarterTalents;
std::unordered_map<uint8 /*class*/, std::unordered_map<uint32 /*racemask*/, std::unordered_map<uint8/*level*/, std::vector<uint32 /*spell*/>>>> _levelClassSpellMap;

/* hater: cached tree meta data */
struct NodeMetaData {
Expand Down Expand Up @@ -938,14 +937,6 @@ class ForgeCache : public DatabaseScript
UpdateCharPoints(player, fcp);
}

void InitSpecForTabId(Player* player, uint32 tabId) {
ForgeCharacterSpec* spec;
if (TryGetCharacterActiveSpec(player, spec)) {
spec->Talents.clear();
auto starters = GetStarterTalents(player->getClass(), tabId);
}
}

private:
std::unordered_map<ObjectGuid, uint32> CharacterActiveSpecs;
std::unordered_map<std::string, uint32> CONFIG;
Expand Down Expand Up @@ -1013,7 +1004,6 @@ class ForgeCache : public DatabaseScript
AddTalentTrees();
AddTalentsToTrees();
AddLevelClassSpellMap();
AddSpecStarterTalents();
AddTalentPrereqs();
AddTalentChoiceNodes();
AddTalentRanks();
Expand Down Expand Up @@ -1728,46 +1718,22 @@ class ForgeCache : public DatabaseScript
{
_levelClassSpellMap.clear();

QueryResult mapQuery = WorldDatabase.Query("select `level`,`class`, `tab`, `spell` from `acore_world`.`forge_character_spec_spells` order by `level` asc, `class` asc, `tab` asc, `spell` asc");
QueryResult mapQuery = WorldDatabase.Query("select * from `acore_world`.`forge_character_spec_spells` order by `class` asc, `race` asc, `level` asc, `spell` asc");

if (!mapQuery)
return;

do
{
Field* mapFields = mapQuery->Fetch();
uint32 level = mapFields[0].Get<uint8>();
uint32 classId = mapFields[1].Get<uint32>();
uint32 spec = mapFields[2].Get<uint32>();
uint8 pClass = mapFields[0].Get<uint8>();
uint32 race = mapFields[1].Get<uint32>();
uint8 level = mapFields[2].Get<uint8>();
uint32 spell = mapFields[3].Get<uint32>();

_levelClassSpellMap[level][classId][spec].push_back(spell);
_levelClassSpellMap[pClass][race][level].push_back(spell);
} while (mapQuery->NextRow());
}

void AddSpecStarterTalents()
{
_specStarterTalents.clear();

QueryResult mapQuery = WorldDatabase.Query("select `class`, `tab`, `spell` from `acore_world`.`forge_character_spec_strarter_talents`");

if (!mapQuery)
return;

do
{
Field* mapFields = mapQuery->Fetch();
uint32 classId = mapFields[0].Get<uint32>();
uint32 spec = mapFields[1].Get<uint32>();
uint32 spell = mapFields[2].Get<uint32>();

_specStarterTalents[classId][spec].push_back(spell);
} while (mapQuery->NextRow());
}

std::vector<uint32> GetStarterTalents(uint32 pClass, uint32 tabId) {
return _specStarterTalents[pClass][tabId];
}
};

#define sForgeCache ForgeCache::instance()
126 changes: 43 additions & 83 deletions modules/mod-Forge/src/ForgePlayerMessageHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,7 @@ class ForgePlayerMessageHandler : public PlayerScript
if (!player)
return;

uint32 count = 1;

for (auto const& [accID, session] : sWorld->GetAllSessions())
{
Player* _player = session->GetPlayer();
if (!_player || _player == player)
{
continue;
}

// If Remote Address matches, remove the player from the world
//if (player->GetSession()->GetRemoteAddress() == _player->GetSession()->GetRemoteAddress() && ++count > 1)
//{
// player->GetSession()->KickPlayer();
//}
}

LearnSpellsForLevel(player);
fc->ApplyAccountBoundTalents(player);
}

Expand Down Expand Up @@ -102,85 +86,39 @@ class ForgePlayerMessageHandler : public PlayerScript
uint32 levelMod = fc->GetConfig("levelMod", 2);
uint8 levelDiff = currentLevel - oldlevel;

if (currentLevel == fc->GetConfig("MaxLevel", 80))
{
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::PRESTIGE_TREE, fc->GetConfig("PrestigePointsAtMaxLevel", 5));
}
//if (currentLevel == fc->GetConfig("MaxLevel", 80))
//{
// fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::PRESTIGE_TREE, fc->GetConfig("PrestigePointsAtMaxLevel", 5));
//}

if (currentLevel >= 10)
{
uint8 amount = levelDiff;
if (oldlevel < 10 && levelDiff > 1)
amount = levelDiff - (9 - oldlevel);
levelDiff -= (9 - oldlevel);

if (levelDiff < levelMod && currentLevel % levelMod == 0)
{
uint32 scrapEarned = fc->GetConfig("scrapsPerLevelMod", 1);
player->AddItem(FORGE_SCRAP, scrapEarned);
}
else if (levelDiff > 1 && levelDiff >= levelMod) // someone added levels, protect div by zero, dont allow 1 as its been evaluated. check if its enough levels
{
uint32 pointsMultiplier = levelDiff / levelMod;
uint32 scrapEarned = fc->GetConfig("scrapsPerLevelMod", 1) * pointsMultiplier;
player->AddItem(FORGE_SCRAP, scrapEarned);
}
if (levelDiff > 1) {
int div = levelDiff / 2;
int rem = levelDiff % 2;
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::TALENT_TREE, div);
if (rem)
div += 1;

fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::TALENT_TREE, amount);

ForgeCharacterPoint* pp = fc->GetCommonCharacterPoint(player, CharacterPointType::PRESTIGE_COUNT);

if (oldlevel < 10 && pp->Sum == 0)
{
auto points = fc->GetConfig("fogepointsAt10", 30);
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::FORGE_SKILL_TREE, points);
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::CLASS_TREE, div);
}

if (pp->Sum == 0)
{
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::FORGE_SKILL_TREE, amount * fc->GetConfig("InitialForgePointsPerLevel", 1));

if (currentLevel >= 20 && oldlevel < 20)
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::RACIAL_TREE, fc->GetConfig("MilestonePoints", 4));

if (currentLevel >= 40 && oldlevel < 40)
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::RACIAL_TREE, fc->GetConfig("MilestonePoints", 4));

if (currentLevel >= 60 && oldlevel < 60)
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::RACIAL_TREE, fc->GetConfig("MilestonePoints", 4));

if (currentLevel == 80)
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::RACIAL_TREE, fc->GetConfig("MilestonePoints", 4));
else {
if (currentLevel % 2)
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::TALENT_TREE, amount);
else
fc->AddCharacterPointsToAllSpecs(player, CharacterPointType::CLASS_TREE, amount);
}

cm->SendActiveSpecInfo(player);
cm->SendTalentTreeLayout(player);
cm->SendTalents(player);
}

if (currentLevel == 80)
{
for (auto charTabType : fc->TALENT_POINT_TYPES)
{
if (ACCOUNT_WIDE_TYPE != charTabType)
continue;

std::list<ForgeTalentTab*> tabs;
if (fc->TryGetForgeTalentTabs(player, charTabType, tabs))
for (auto* tab : tabs)
{
auto talItt = spec->Talents.find(tab->Id);

for (auto spell : tab->Talents)
{
for (auto rank : spell.second->Ranks)
player->removeSpell(rank.second, SPEC_MASK_ALL, false);
}
}
}

cm->SendTalents(player);
}

fc->UpdateCharacterSpec(player, spec);
LearnSpellsForLevel(player);
}
}

Expand Down Expand Up @@ -259,7 +197,29 @@ class ForgePlayerMessageHandler : public PlayerScript
TopicRouter* Router;
ForgeCache* fc;
ForgeCommonMessage* cm;
uint32 FORGE_SCRAP = 90000;

void LearnSpellsForLevel(Player* player) {
if (player->HasUnitState(UNIT_STATE_DIED))
player->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);

auto pClass = fc->_levelClassSpellMap.find(player->getClass());
if (pClass != fc->_levelClassSpellMap.end()) {
for (auto race : pClass->second) {
if (player->getRaceMask() & race.first) {
for (auto level : race.second) {
if (level.first <= player->getLevel()) {
for (auto spell : level.second) {
if (player->HasSpell(spell))
continue;

player->learnSpell(spell);
}
}
}
}
}
}
}
};

// Add all scripts in one
Expand Down
11 changes: 1 addition & 10 deletions src/server/game/Spells/SpellEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5032,16 +5032,7 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex)

bool knockbackImmune = false;

Unit::AuraApplicationMap& auraMap = unitTarget->GetAppliedAuras();
for (Unit::AuraApplicationMap::iterator iter = auraMap.begin(); iter != auraMap.end();)
{
AuraApplication* aurApp = iter->second;
Aura* aura = aurApp->GetBase();
if (aura->HasEffectType(SPELL_AURA_KNOCKBACK_IMMUNITY))
knockbackImmune = true;
}

if (knockbackImmune)
if (unitTarget->HasAuraType(SPELL_AURA_KNOCKBACK_IMMUNITY))
return;

// Xinef: allow entry specific spells to skip those checks
Expand Down

0 comments on commit 29069cc

Please sign in to comment.