diff --git a/modules/mod-Forge/sql/world/updates/20231106 starter talents.sql b/modules/mod-Forge/sql/world/updates/20231106 starter talents.sql index a29440b63e7f42..68d04b904c93de 100644 --- a/modules/mod-Forge/sql/world/updates/20231106 starter talents.sql +++ b/modules/mod-Forge/sql/world/updates/20231106 starter talents.sql @@ -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; \ No newline at end of file diff --git a/modules/mod-Forge/src/ForgeCache.cpp b/modules/mod-Forge/src/ForgeCache.cpp index e78a4dcb7156fb..771018ebd86407 100644 --- a/modules/mod-Forge/src/ForgeCache.cpp +++ b/modules/mod-Forge/src/ForgeCache.cpp @@ -891,8 +891,7 @@ class ForgeCache : public DatabaseScript return 0; } - std::unordered_map>>> _levelClassSpellMap; - std::unordered_map>> _specStarterTalents; + std::unordered_map>>> _levelClassSpellMap; /* hater: cached tree meta data */ struct NodeMetaData { @@ -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 CharacterActiveSpecs; std::unordered_map CONFIG; @@ -1013,7 +1004,6 @@ class ForgeCache : public DatabaseScript AddTalentTrees(); AddTalentsToTrees(); AddLevelClassSpellMap(); - AddSpecStarterTalents(); AddTalentPrereqs(); AddTalentChoiceNodes(); AddTalentRanks(); @@ -1728,7 +1718,7 @@ 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; @@ -1736,38 +1726,14 @@ class ForgeCache : public DatabaseScript do { Field* mapFields = mapQuery->Fetch(); - uint32 level = mapFields[0].Get(); - uint32 classId = mapFields[1].Get(); - uint32 spec = mapFields[2].Get(); + uint8 pClass = mapFields[0].Get(); + uint32 race = mapFields[1].Get(); + uint8 level = mapFields[2].Get(); uint32 spell = mapFields[3].Get(); - _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 spec = mapFields[1].Get(); - uint32 spell = mapFields[2].Get(); - - _specStarterTalents[classId][spec].push_back(spell); - } while (mapQuery->NextRow()); - } - - std::vector GetStarterTalents(uint32 pClass, uint32 tabId) { - return _specStarterTalents[pClass][tabId]; - } }; #define sForgeCache ForgeCache::instance() diff --git a/modules/mod-Forge/src/ForgePlayerMessageHandler.cpp b/modules/mod-Forge/src/ForgePlayerMessageHandler.cpp index a7c35e8e09e82e..8b003c08f8e262 100644 --- a/modules/mod-Forge/src/ForgePlayerMessageHandler.cpp +++ b/modules/mod-Forge/src/ForgePlayerMessageHandler.cpp @@ -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); } @@ -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 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); } } @@ -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 diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 61804661fa43df..9bfc5d250efe40 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -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