Esempio n. 1
0
        public bool RewardHonor(Unit victim, uint groupsize, int honor = -1, bool pvptoken = false)
        {
            // do not reward honor in arenas, but enable onkill spellproc
            if (InArena())
            {
                if (!victim || victim == this || !victim.IsTypeId(TypeId.Player))
                {
                    return(false);
                }

                if (GetBGTeam() == victim.ToPlayer().GetBGTeam())
                {
                    return(false);
                }

                return(true);
            }

            // 'Inactive' this aura prevents the player from gaining honor points and BattlegroundTokenizer
            if (HasAura(BattlegroundConst.SpellAuraPlayerInactive))
            {
                return(false);
            }

            ObjectGuid victim_guid = ObjectGuid.Empty;
            uint       victim_rank = 0;

            // need call before fields update to have chance move yesterday data to appropriate fields before today data change.
            UpdateHonorFields();

            // do not reward honor in arenas, but return true to enable onkill spellproc
            if (InBattleground() && GetBattleground() && GetBattleground().IsArena())
            {
                return(true);
            }

            // Promote to float for calculations
            float honor_f = honor;

            if (honor_f <= 0)
            {
                if (!victim || victim == this || victim.HasAuraType(AuraType.NoPvpCredit))
                {
                    return(false);
                }

                victim_guid = victim.GetGUID();
                Player plrVictim = victim.ToPlayer();
                if (plrVictim)
                {
                    if (GetTeam() == plrVictim.GetTeam() && !Global.WorldMgr.IsFFAPvPRealm())
                    {
                        return(false);
                    }

                    byte k_level = (byte)GetLevel();
                    byte k_grey  = (byte)Formulas.GetGrayLevel(k_level);
                    byte v_level = (byte)victim.GetLevelForTarget(this);

                    if (v_level <= k_grey)
                    {
                        return(false);
                    }

                    // PLAYER_CHOSEN_TITLE VALUES DESCRIPTION
                    //  [0]      Just name
                    //  [1..14]  Alliance honor titles and player name
                    //  [15..28] Horde honor titles and player name
                    //  [29..38] Other title and player name
                    //  [39+]    Nothing
                    // this is all wrong, should be going off PvpTitle, not PlayerTitle
                    uint victim_title = plrVictim.m_playerData.PlayerTitle;
                    // Get Killer titles, CharTitlesEntry.bit_index
                    // Ranks:
                    //  title[1..14]  . rank[5..18]
                    //  title[15..28] . rank[5..18]
                    //  title[other]  . 0
                    if (victim_title == 0)
                    {
                        victim_guid.Clear();                        // Don't show HK: <rank> message, only log.
                    }
                    else if (victim_title < 15)
                    {
                        victim_rank = victim_title + 4;
                    }
                    else if (victim_title < 29)
                    {
                        victim_rank = victim_title - 14 + 4;
                    }
                    else
                    {
                        victim_guid.Clear();                        // Don't show HK: <rank> message, only log.
                    }
                    honor_f = (float)Math.Ceiling(Formulas.HKHonorAtLevelF(k_level) * (v_level - k_grey) / (k_level - k_grey));

                    // count the number of playerkills in one day
                    ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TodayHonorableKills), (ushort)1, true);
                    // and those in a lifetime
                    ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LifetimeHonorableKills), 1u, true);
                    UpdateCriteria(CriteriaTypes.EarnHonorableKill);
                    UpdateCriteria(CriteriaTypes.HkClass, (uint)victim.GetClass());
                    UpdateCriteria(CriteriaTypes.HkRace, (uint)victim.GetRace());
                    UpdateCriteria(CriteriaTypes.HonorableKillAtArea, GetAreaId());
                    UpdateCriteria(CriteriaTypes.HonorableKill, 1, 0, 0, victim);
                }
                else
                {
                    if (!victim.ToCreature().IsRacialLeader())
                    {
                        return(false);
                    }

                    honor_f     = 100.0f;                           // ??? need more info
                    victim_rank = 19;                               // HK: Leader
                }
            }

            if (victim != null)
            {
                if (groupsize > 1)
                {
                    honor_f /= groupsize;
                }

                // apply honor multiplier from aura (not stacking-get highest)
                MathFunctions.AddPct(ref honor_f, GetMaxPositiveAuraModifier(AuraType.ModHonorGainPct));
                honor_f += _restMgr.GetRestBonusFor(RestTypes.Honor, (uint)honor_f);
            }

            honor_f *= WorldConfig.GetFloatValue(WorldCfg.RateHonor);
            // Back to int now
            honor = (int)honor_f;
            // honor - for show honor points in log
            // victim_guid - for show victim name in log
            // victim_rank [1..4]  HK: <dishonored rank>
            // victim_rank [5..19] HK: <alliance\horde rank>
            // victim_rank [0, 20+] HK: <>
            PvPCredit data = new PvPCredit();

            data.Honor         = honor;
            data.OriginalHonor = honor;
            data.Target        = victim_guid;
            data.Rank          = victim_rank;

            SendPacket(data);

            AddHonorXP((uint)honor);

            if (InBattleground() && honor > 0)
            {
                Battleground bg = GetBattleground();
                if (bg != null)
                {
                    bg.UpdatePlayerScore(this, ScoreType.BonusHonor, (uint)honor, false); //false: prevent looping
                }
            }

            if (WorldConfig.GetBoolValue(WorldCfg.PvpTokenEnable) && pvptoken)
            {
                if (!victim || victim == this || victim.HasAuraType(AuraType.NoPvpCredit))
                {
                    return(true);
                }

                if (victim.IsTypeId(TypeId.Player))
                {
                    // Check if allowed to receive it in current map
                    int MapType = WorldConfig.GetIntValue(WorldCfg.PvpTokenMapType);
                    if ((MapType == 1 && !InBattleground() && !IsFFAPvP()) ||
                        (MapType == 2 && !IsFFAPvP()) ||
                        (MapType == 3 && !InBattleground()))
                    {
                        return(true);
                    }

                    uint itemId = WorldConfig.GetUIntValue(WorldCfg.PvpTokenId);
                    uint count  = WorldConfig.GetUIntValue(WorldCfg.PvpTokenCount);

                    if (AddItem(itemId, count))
                    {
                        SendSysMessage("You have been awarded a token for slaying another player.");
                    }
                }
            }

            return(true);
        }