Exemple #1
0
        /// <summary>
        /// Returns the amount to scale the XP for a fellow
        /// based on distance from the earner
        /// </summary>
        public double GetDistanceScalar(Player earner, Player fellow, XpType xpType)
        {
            if (earner == null || fellow == null)
                return 0.0f;

            if (xpType == XpType.Quest)
                return 1.0f;

            // https://asheron.fandom.com/wiki/Announcements_-_2004/01_-_Mirror,_Mirror#Rollout_Article

            // If they are indoors while you are outdoors, or vice-versa.
            if (earner.Location.Indoors != fellow.Location.Indoors)
                return 0.0f;

            // If you are both indoors but in different landblocks.
            if (earner.Location.Indoors && fellow.Location.Indoors && earner.Location.Landblock != fellow.Location.Landblock)
                return 0.0f;

            var dist = earner.Location.Distance2D(fellow.Location);

            if (dist >= MaxDistance * 2.0f)
                return 0.0f;

            if (dist <= MaxDistance)
                return 1.0f;

            var scalar = 1.0f - (dist - MaxDistance) / MaxDistance;

            return Math.Max(0.0f, scalar);
        }
Exemple #2
0
        /// <summary>
        /// Adds XP to a player's total XP, handles triggers (vitae, level up)
        /// </summary>
        private void UpdateXpAndLevel(long amount, XpType xpType)
        {
            // until we are max level we must make sure that we send
            var xpTable = DatManager.PortalDat.XpTable;

            var maxLevel   = GetMaxLevel();
            var maxLevelXp = xpTable.CharacterLevelXPList.Last();

            if (Level != maxLevel)
            {
                var addAmount = amount;

                var amountLeftToEnd = (long)maxLevelXp - TotalExperience ?? 0;
                if (amount > amountLeftToEnd)
                {
                    addAmount = amountLeftToEnd;
                }

                AvailableExperience += addAmount;
                TotalExperience     += addAmount;

                var xpTotalUpdate = new GameMessagePrivateUpdatePropertyInt64(this, PropertyInt64.TotalExperience, TotalExperience ?? 0);
                var xpAvailUpdate = new GameMessagePrivateUpdatePropertyInt64(this, PropertyInt64.AvailableExperience, AvailableExperience ?? 0);
                Session.Network.EnqueueSend(xpTotalUpdate, xpAvailUpdate);

                CheckForLevelup();
            }

            if (HasVitae && xpType != XpType.Allegiance)
            {
                UpdateXpVitae(amount);
            }
        }
Exemple #3
0
        /// <summary>
        /// Directly grants XP to the player, without the XP modifier
        /// </summary>
        /// <param name="amount">The amount of XP to grant to the player</param>
        /// <param name="xpType">The source of the XP being granted</param>
        /// <param name="shareable">If TRUE, this XP can be shared with fellowship members</param>
        public void GrantXP(long amount, XpType xpType, ShareType shareType = ShareType.All)
        {
            if (Fellowship != null && Fellowship.ShareXP && shareType.HasFlag(ShareType.Fellowship))
            {
                // this will divy up the XP, and re-call this function
                // with ShareType.Fellowship removed
                Fellowship.SplitXp((ulong)amount, xpType, shareType, this);
                return;
            }

            UpdateXpAndLevel(amount, xpType);

            // for passing XP up the allegiance chain,
            // this function is only called at the very beginning, to start the process.
            if (shareType.HasFlag(ShareType.Allegiance))
            {
                UpdateXpAllegiance(amount);
            }

            // only certain types of XP are granted to items
            if (xpType == XpType.Kill || xpType == XpType.Quest)
            {
                GrantItemXP(amount);
            }
        }
Exemple #4
0
        /// <summary>
        /// Directly grants XP to the player, without the XP modifier
        /// </summary>
        /// <param name="amount">The amount of XP to grant to the player</param>
        /// <param name="passup">The source of the XP being granted</param>
        /// <param name="shareable">If TRUE, this XP can be shared with fellowship members</param>
        public void GrantXP(long amount, XpType xpType, bool shareable = true)
        {
            if (shareable && Fellowship != null && Fellowship.ShareXP && Fellowship.ShareableMembers.ContainsKey(Guid.Full))
            {
                // this will divy up the XP, and re-call this function
                // with shareable = false
                Fellowship.SplitXp((ulong)amount, xpType, this);
                return;
            }

            UpdateXpAndLevel(amount);

            // for passing XP up the allegiance chain,
            // this function is only called at the very beginning, to start the process.
            if (xpType != XpType.Allegiance)
            {
                UpdateXpAllegiance(amount);
            }

            // only certain types of XP are granted to items
            if (xpType == XpType.Kill || xpType == XpType.Quest)
            {
                GrantItemXP(amount);
            }
        }
Exemple #5
0
        private void AddLuminance(long amount, XpType xpType)
        {
            var available = AvailableLuminance ?? 0;
            var maximum   = MaximumLuminance ?? 0;

            if (available == maximum)
            {
                return;
            }

            // this is similar to Player_Xp.UpdateXpAndLevel()

            var remaining = maximum - available;

            var addAmount = Math.Min(amount, remaining);

            AvailableLuminance = available + addAmount;

            if (xpType == XpType.Quest)
            {
                Session.Network.EnqueueSend(new GameMessageSystemChat($"You've earned {amount:N0} Luminance.", ChatMessageType.Broadcast));
            }

            UpdateLuminance();
        }
Exemple #6
0
        /// <summary>
        /// Returns the amount to scale the XP for a fellow
        /// based on distance from the leader
        /// </summary>
        private double GetDistanceScalar(Player earner, Player fellow, XpType xpType)
        {
            if (earner == null || fellow == null)
            {
                return(0.0f);
            }

            if (xpType == XpType.Quest)
            {
                return(1.0f);
            }

            var earnerPosition = earner.Location;
            var fellowPosition = fellow.Location;

            var dist = fellowPosition.Distance2D(earnerPosition);

            if (dist >= MaxDistance * 2.0f)
            {
                return(0.0f);
            }

            if (dist <= MaxDistance)
            {
                return(1.0f);
            }

            var scalar = 1 - (dist - MaxDistance) / MaxDistance;

            return(Math.Max(0.0f, scalar));
        }
Exemple #7
0
        /// <summary>
        /// Splits luminance amongst fellowship members, depending on XP type and fellow settings
        /// </summary>
        /// <param name="amount">The input amount of luminance</param>
        /// <param name="xpType">The type of lumaniance (quest luminance is handled differently)</param>
        /// <param name="player">The fellowship member who originated the luminance</param>
        public void SplitLuminance(ulong amount, XpType xpType, ShareType shareType, Player player)
        {
            // https://asheron.fandom.com/wiki/Announcements_-_2002/02_-_Fever_Dreams#Letter_to_the_Players_1

            shareType &= ~ShareType.Fellowship;

            if (xpType == XpType.Quest)
            {
                // quest luminance is not shared
                player.GrantLuminance((long)amount, XpType.Quest, shareType);
            }
            else
            {
                // pre-filter: evenly divide between luminance-eligible fellows
                var shareableMembers = GetFellowshipMembers().Values.Where(f => f.MaximumLuminance != null).ToList();

                if (shareableMembers.Count == 0)
                {
                    return;
                }

                var perAmount = (long)Math.Round((double)(amount / (ulong)shareableMembers.Count));

                // further filter to fellows in radar range
                var inRange = shareableMembers.Intersect(WithinRange(player, true)).ToList();

                foreach (var member in inRange)
                {
                    var fellowXpType = player == member ? xpType : XpType.Fellowship;

                    member.GrantLuminance(perAmount, fellowXpType, shareType);
                }
            }
        }
Exemple #8
0
        /// <summary>
        /// Splits XP amongst fellowship members, depending on XP type and fellow settings
        /// </summary>
        /// <param name="amount">The input amount of XP</param>
        /// <param name="xpType">The type of XP (quest XP is handled differently)</param>
        /// <param name="player">The fellowship member who originated the XP</param>
        public void SplitXp(ulong amount, XpType xpType, ShareType shareType, Player player)
        {
            // https://asheron.fandom.com/wiki/Announcements_-_2002/02_-_Fever_Dreams#Letter_to_the_Players_1

            var fellowshipMembers = GetFellowshipMembers();

            shareType &= ~ShareType.Fellowship;

            // quest turn-ins: flat share (retail default)
            if (xpType == XpType.Quest && !PropertyManager.GetBool("fellow_quest_bonus").Item)
            {
                var perAmount = (long)amount / fellowshipMembers.Count;

                foreach (var member in fellowshipMembers.Values)
                {
                    var fellowXpType = player == member ? XpType.Quest : XpType.Fellowship;

                    member.GrantXP(perAmount, fellowXpType, shareType);
                }
            }

            // divides XP evenly to all the sharable fellows within level range,
            // but with a significant boost to the amount of xp, based on # of fellowship members
            else if (EvenShare)
            {
                var totalAmount = (ulong)Math.Round(amount * GetMemberSharePercent());

                foreach (var member in fellowshipMembers.Values)
                {
                    var shareAmount = (ulong)Math.Round(totalAmount * GetDistanceScalar(player, member, xpType));

                    var fellowXpType = player == member ? xpType : XpType.Fellowship;

                    member.GrantXP((long)shareAmount, fellowXpType, shareType);
                }

                return;
            }

            // divides XP to all sharable fellows within level range
            // based on each fellowship member's level
            else
            {
                var levelXPSum = fellowshipMembers.Values.Select(p => p.GetXPToNextLevel(p.Level.Value)).Sum();

                foreach (var member in fellowshipMembers.Values)
                {
                    var levelXPScale = (double)member.GetXPToNextLevel(member.Level.Value) / levelXPSum;

                    var playerTotal = (ulong)Math.Round(amount * levelXPScale * GetDistanceScalar(player, member, xpType));

                    var fellowXpType = player == member ? xpType : XpType.Fellowship;

                    member.GrantXP((long)playerTotal, fellowXpType, shareType);
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// Applies luminance modifiers before adding luminance
        /// </summary>
        public void EarnLuminance(long amount, XpType xpType, ShareType shareType = ShareType.All)
        {
            // following the same model as Player_Xp

            var modifier = PropertyManager.GetDouble("luminance_modifier").Item;

            var m_amount = (long)Math.Round(amount * modifier);

            GrantLuminance(m_amount, xpType, shareType);
        }
Exemple #10
0
        /// <summary>
        /// Applies luminance modifiers before adding luminance
        /// </summary>
        public void EarnLuminance(long amount, XpType xpType, ShareType shareType = ShareType.All)
        {
            // following the same model as Player_Xp

            var modifier = PropertyManager.GetDouble("luminance_modifier").Item;

            // should this be passed upstream to fellowship?
            var enchantment = GetXPAndLuminanceModifier(xpType);

            var m_amount = (long)Math.Round(amount * enchantment * modifier);

            GrantLuminance(m_amount, xpType, shareType);
        }
Exemple #11
0
 /// <summary>
 /// Directly grants luminance to the player, without any additional luminance modifiers
 /// </summary>
 public void GrantLuminance(long amount, XpType xpType, ShareType shareType = ShareType.All)
 {
     if (Fellowship != null && Fellowship.ShareXP && shareType.HasFlag(ShareType.Fellowship))
     {
         // this will divy up the luminance, and re-call this function
         // with ShareType.Fellowship removed
         Fellowship.SplitLuminance((ulong)amount, xpType, shareType, this);
     }
     else
     {
         AddLuminance(amount, xpType);
     }
 }
Exemple #12
0
        /// <summary>
        /// Splits XP amongst fellowship members, depending on XP type and fellow settings
        /// </summary>
        /// <param name="amount">The input amount of XP</param>
        /// <param name="xpType">The type of XP (quest XP is handled differently)</param>
        /// <param name="player">The fellowship member who originated the XP</param>
        public void SplitXp(ulong amount, XpType xpType, Player player)
        {
            var shareableMembers = GetShareableMembers();

            // handle sharing quest XP with fellows
            if (xpType == XpType.Quest)
            {
                foreach (var member in shareableMembers.Values)
                {
                    var fellowXpType = player == member ? XpType.Quest : XpType.Fellowship;

                    member.GrantXP((long)amount, fellowXpType, false);
                }
            }

            // divides XP evenly to all the sharable fellows within level range,
            // but with a significant boost to the amount of xp, based on # of fellowship members
            else if (EvenShare)
            {
                var totalAmount = (ulong)Math.Round(amount * GetMemberSharePercent());

                foreach (var member in shareableMembers.Values)
                {
                    var shareAmount = (ulong)Math.Round(totalAmount * GetDistanceScalar(player, member));

                    var fellowXpType = player == member ? xpType : XpType.Fellowship;

                    member.GrantXP((long)shareAmount, fellowXpType, false);
                }

                return;
            }

            // divides XP to all sharable fellows within level range
            // based on each fellowship member's level
            else
            {
                var levelSum = shareableMembers.Values.Select(p => p.Level ?? 1).Sum();

                foreach (var member in shareableMembers.Values)
                {
                    var levelScale = (float)(member.Level ?? 1) / levelSum;

                    var playerTotal = (ulong)Math.Round(amount * levelScale * GetDistanceScalar(player, member));

                    var fellowXpType = player == member ? xpType : XpType.Fellowship;

                    member.GrantXP((long)playerTotal, fellowXpType, false);
                }
            }
        }
Exemple #13
0
        /// <summary>
        /// Returns the multiplier to XP and Luminance from Trinkets and Augmentations
        /// </summary>
        public float GetXPAndLuminanceModifier(XpType xpType)
        {
            var enchantmentBonus = EnchantmentManager.GetXPBonus();

            var augBonus = 0.0f;

            if (xpType == XpType.Kill && AugmentationBonusXp > 0)
            {
                augBonus = AugmentationBonusXp * 0.05f;
            }

            var modifier = 1.0f + enchantmentBonus + augBonus;

            //Console.WriteLine($"XPAndLuminanceModifier: {modifier}");

            return(modifier);
        }
Exemple #14
0
        private void AddLuminance(long amount, XpType xpType)
        {
            if (AvailableLuminance == MaximumLuminance)
            {
                return;
            }

            // this is similar to Player_Xp.UpdateXpAndLevel()

            var remaining = (MaximumLuminance - AvailableLuminance) ?? 0;

            var addAmount = Math.Min(amount, remaining);

            AvailableLuminance += addAmount;

            UpdateLuminance();
        }
Exemple #15
0
        /// <summary>
        /// A player earns XP through natural progression, ie. kills and quests completed
        /// </summary>
        /// <param name="amount">The amount of XP being added</param>
        /// <param name="xpType">The source of XP being added</param>
        /// <param name="shareable">True if this XP can be shared with Fellowship</param>
        public void EarnXP(long amount, XpType xpType, ShareType shareType = ShareType.All)
        {
            //Console.WriteLine($"{Name}.EarnXP({amount}, {sharable}, {fixedAmount})");

            // apply xp modifier
            var modifier    = PropertyManager.GetDouble("xp_modifier").Item;
            var enchantment = EnchantmentManager.GetXPMod();

            var m_amount = (long)Math.Round(amount * enchantment * modifier);

            if (m_amount < 0)
            {
                log.Warn($"{Name}.EarnXP({amount}, {shareType})");
                log.Warn($"modifier: {modifier}, enchantment: {enchantment}, m_amount: {m_amount}");
                return;
            }

            GrantXP(m_amount, xpType, shareType);
        }
Exemple #16
0
        private void AddLuminance(long amount, XpType xpType)
        {
            var available = AvailableLuminance ?? 0;
            var maximum   = MaximumLuminance ?? 0;

            if (available == maximum)
            {
                return;
            }

            // this is similar to Player_Xp.UpdateXpAndLevel()

            var remaining = maximum - available;

            var addAmount = Math.Min(amount, remaining);

            AvailableLuminance = available + addAmount;

            UpdateLuminance();
        }
Exemple #17
0
        /// <summary>
        /// A player earns XP through natural progression, ie. kills and quests completed
        /// </summary>
        /// <param name="amount">The amount of XP being added</param>
        /// <param name="xpType">The source of XP being added</param>
        /// <param name="shareable">True if this XP can be shared with Fellowship</param>
        public void EarnXP(long amount, XpType xpType, ShareType shareType = ShareType.All)
        {
            //Console.WriteLine($"{Name}.EarnXP({amount}, {sharable}, {fixedAmount})");

            // apply xp modifier
            var modifier = PropertyManager.GetDouble("xp_modifier").Item;

            // should this be passed upstream to fellowship / allegiance?
            var enchantment = GetXPAndLuminanceModifier(xpType);

            var m_amount = (long)Math.Round(amount * enchantment * modifier);

            if (m_amount < 0)
            {
                log.Warn($"{Name}.EarnXP({amount}, {shareType})");
                log.Warn($"modifier: {modifier}, enchantment: {enchantment}, m_amount: {m_amount}");
                return;
            }

            GrantXP(m_amount, xpType, shareType);
        }
Exemple #18
0
        /// <summary>
        /// Adds XP to a player's total XP, handles triggers (vitae, level up)
        /// </summary>
        private void UpdateXpAndLevel(long amount, XpType xpType)
        {
            // until we are max level we must make sure that we send
            var xpTable = DatManager.PortalDat.XpTable;

            var maxLevel   = GetMaxLevel();
            var maxLevelXp = 9223372036854775807UL; // max int64 number

            if (Level != maxLevel)
            {
                var addAmount = amount;

                var amountLeftToEnd = (long)maxLevelXp - TotalExperience ?? 0;
                if (amount > amountLeftToEnd)
                {
                    addAmount = amountLeftToEnd;
                }

                AvailableExperience += addAmount;
                TotalExperience     += addAmount;

                var xpTotalUpdate = new GameMessagePrivateUpdatePropertyInt64(this, PropertyInt64.TotalExperience, TotalExperience ?? 0);
                var xpAvailUpdate = new GameMessagePrivateUpdatePropertyInt64(this, PropertyInt64.AvailableExperience, AvailableExperience ?? 0);
                Session.Network.EnqueueSend(xpTotalUpdate, xpAvailUpdate);

                CheckForLevelup();
            }

            if (xpType == XpType.Quest)
            {
                Session.Network.EnqueueSend(new GameMessageSystemChat($"You've earned {amount:N0} experience.", ChatMessageType.Broadcast));
            }

            if (HasVitae && xpType != XpType.Allegiance)
            {
                UpdateXpVitae(amount);
            }
        }
Exemple #19
0
        /// <summary>
        /// Directly grants XP to the player, without the XP modifier
        /// </summary>
        /// <param name="amount">The amount of XP to grant to the player</param>
        /// <param name="xpType">The source of the XP being granted</param>
        /// <param name="shareable">If TRUE, this XP can be shared with fellowship members</param>
        public void GrantXP(long amount, XpType xpType, ShareType shareType = ShareType.All)
        {
            if (IsOlthoiPlayer)
            {
                if (HasVitae)
                {
                    UpdateXpVitae(amount);
                }

                return;
            }

            if (Fellowship != null && Fellowship.ShareXP && shareType.HasFlag(ShareType.Fellowship))
            {
                // this will divy up the XP, and re-call this function
                // with ShareType.Fellowship removed
                Fellowship.SplitXp((ulong)amount, xpType, shareType, this);
                return;
            }

            // Make sure UpdateXpAndLevel is done on this players thread
            EnqueueAction(new ActionEventDelegate(() => UpdateXpAndLevel(amount, xpType)));

            // for passing XP up the allegiance chain,
            // this function is only called at the very beginning, to start the process.
            if (shareType.HasFlag(ShareType.Allegiance))
            {
                UpdateXpAllegiance(amount);
            }

            // only certain types of XP are granted to items
            if (xpType == XpType.Kill || xpType == XpType.Quest)
            {
                GrantItemXP(amount);
            }
        }