Esempio n. 1
0
        public void ActivateTalentGroup(ChrSpecializationRecord spec)
        {
            if (GetActiveTalentGroup() == spec.OrderIndex)
            {
                return;
            }

            if (IsNonMeleeSpellCast(false))
            {
                InterruptNonMeleeSpells(false);
            }

            SQLTransaction trans = new SQLTransaction();

            _SaveActions(trans);
            DB.Characters.CommitTransaction(trans);

            // TO-DO: We need more research to know what happens with warlock's reagent
            Pet pet = GetPet();

            if (pet)
            {
                RemovePet(pet, PetSaveMode.NotInSlot);
            }

            ClearAllReactives();
            UnsummonAllTotems();
            ExitVehicle();
            RemoveAllControlled();

            // remove single target auras at other targets
            var scAuras = GetSingleCastAuras();

            foreach (var aura in scAuras)
            {
                if (aura.GetUnitOwner() != this)
                {
                    aura.Remove();
                }
            }

            // Let client clear his current Actions
            SendActionButtons(2);
            foreach (var talentInfo in CliDB.TalentStorage.Values)
            {
                // unlearn only talents for character class
                // some spell learned by one class as normal spells or know at creation but another class learn it as talent,
                // to prevent unexpected lost normal learned spell skip another class talents
                if (talentInfo.ClassID != (int)GetClass())
                {
                    continue;
                }

                if (talentInfo.SpellID == 0)
                {
                    continue;
                }

                SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
                if (spellInfo == null)
                {
                    continue;
                }

                RemoveSpell(talentInfo.SpellID, true);

                // search for spells that the talent teaches and unlearn them
                foreach (SpellEffectInfo effect in spellInfo.GetEffects())
                {
                    if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell)
                    {
                        RemoveSpell(effect.TriggerSpell, true);
                    }
                }

                if (talentInfo.OverridesSpellID != 0)
                {
                    RemoveOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID);
                }
            }

            foreach (var talentInfo in CliDB.PvpTalentStorage.Values)
            {
                SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
                if (spellInfo == null)
                {
                    continue;
                }

                RemoveSpell(talentInfo.SpellID, true);

                // search for spells that the talent teaches and unlearn them
                foreach (SpellEffectInfo effect in spellInfo.GetEffects())
                {
                    if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell)
                    {
                        RemoveSpell(effect.TriggerSpell, true);
                    }
                }

                if (talentInfo.OverridesSpellID != 0)
                {
                    RemoveOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID);
                }
            }

            // Remove spec specific spells
            RemoveSpecializationSpells();

            foreach (uint glyphId in GetGlyphs(GetActiveTalentGroup()))
            {
                RemoveAurasDueToSpell(CliDB.GlyphPropertiesStorage.LookupByKey(glyphId).SpellID);
            }

            SetActiveTalentGroup(spec.OrderIndex);
            SetPrimarySpecialization(spec.Id);

            foreach (var talentInfo in CliDB.TalentStorage.Values)
            {
                // learn only talents for character class
                if (talentInfo.ClassID != (int)GetClass())
                {
                    continue;
                }

                if (talentInfo.SpellID == 0)
                {
                    continue;
                }

                if (HasTalent(talentInfo.Id, GetActiveTalentGroup()))
                {
                    LearnSpell(talentInfo.SpellID, false);      // add the talent to the PlayerSpellMap
                    if (talentInfo.OverridesSpellID != 0)
                    {
                        AddOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID);
                    }
                }
            }

            for (byte slot = 0; slot < PlayerConst.MaxPvpTalentSlots; ++slot)
            {
                PvpTalentRecord talentInfo = CliDB.PvpTalentStorage.LookupByKey(GetPvpTalentMap(GetActiveTalentGroup())[slot]);
                if (talentInfo == null)
                {
                    continue;
                }

                if (talentInfo.SpellID == 0)
                {
                    continue;
                }

                AddPvpTalent(talentInfo, GetActiveTalentGroup(), slot);
            }

            LearnSpecializationSpells();

            if (CanUseMastery())
            {
                for (uint i = 0; i < PlayerConst.MaxMasterySpells; ++i)
                {
                    uint mastery = spec.MasterySpellID[i];
                    if (mastery != 0)
                    {
                        LearnSpell(mastery, false);
                    }
                }
            }

            InitTalentForLevel();

            PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_ACTIONS_SPEC);

            stmt.AddValue(0, GetGUID().GetCounter());
            stmt.AddValue(1, GetActiveTalentGroup());

            WorldSession mySess = GetSession();

            mySess.GetQueryProcessor().AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(result =>
            {
                // in case player logs out before db response (player would be deleted in that case)
                Player thisPlayer = mySess.GetPlayer();
                if (thisPlayer != null)
                {
                    thisPlayer.LoadActions(result);
                }
            }));

            UpdateDisplayPower();
            PowerType pw = GetPowerType();

            if (pw != PowerType.Mana)
            {
                SetPower(PowerType.Mana, 0); // Mana must be 0 even if it isn't the active power type.
            }
            SetPower(pw, 0);
            UpdateItemSetAuras(false);

            // update visible transmog
            for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i)
            {
                Item equippedItem = GetItemByPos(InventorySlots.Bag0, i);
                if (equippedItem)
                {
                    SetVisibleItemSlot(i, equippedItem);
                }
            }

            foreach (uint glyphId in GetGlyphs(spec.OrderIndex))
            {
                CastSpell(this, CliDB.GlyphPropertiesStorage.LookupByKey(glyphId).SpellID, true);
            }

            ActiveGlyphs activeGlyphs = new ActiveGlyphs();

            foreach (uint glyphId in GetGlyphs(spec.OrderIndex))
            {
                List <uint> bindableSpells = Global.DB2Mgr.GetGlyphBindableSpells(glyphId);
                foreach (uint bindableSpell in bindableSpells)
                {
                    if (HasSpell(bindableSpell) && !m_overrideSpells.ContainsKey(bindableSpell))
                    {
                        activeGlyphs.Glyphs.Add(new GlyphBinding(bindableSpell, (ushort)glyphId));
                    }
                }
            }

            activeGlyphs.IsFullUpdate = true;
            SendPacket(activeGlyphs);

            Item item = GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth, ItemSearchLocation.Everywhere);

            if (item != null)
            {
                AzeriteItem azeriteItem = item.ToAzeriteItem();
                if (azeriteItem != null)
                {
                    if (azeriteItem.IsEquipped())
                    {
                        ApplyAllAzeriteEmpoweredItemMods(false);
                        ApplyAzeritePowers(azeriteItem, false);
                    }

                    azeriteItem.SetSelectedAzeriteEssences(spec.Id);

                    if (azeriteItem.IsEquipped())
                    {
                        ApplyAzeritePowers(azeriteItem, true);
                        ApplyAllAzeriteEmpoweredItemMods(true);
                    }

                    azeriteItem.SetState(ItemUpdateState.Changed, this);
                }
            }

            var shapeshiftAuras = GetAuraEffectsByType(AuraType.ModShapeshift);

            foreach (AuraEffect aurEff in shapeshiftAuras)
            {
                aurEff.HandleShapeshiftBoosts(this, false);
                aurEff.HandleShapeshiftBoosts(this, true);
            }
        }