Example #1
0
        /// <summary>
        /// Calculates morale changed. This one is stripped down for AI for performance reasons.
        /// </summary>
        private void Cheer()
        {
            _timerToEnableCheering = MBCommon.TimeType.Mission.GetTime() + MBRandom.RandomInt(4, 7);
            _canCheer = false;

            if (_config.AI.DisplayAnnouncement)
            {
                Helpers.Announce("{=lord_cheered}" + _strings.Lord.Cheered
                                 .Replace("$NAME$", _agent.Name)
                                 .Replace("$HISHERUPPER$", _agent.IsFemale ? "Her" : "His")
                                 .Replace("$HISHERLOWER$", _agent.IsFemale ? "her" : "his"),
                                 _agent.Character,
                                 new Dictionary <string, TextObject> {
                    { "NAME", new TextObject(_agent.Name) },
                    { "HISHERUPPER", new TextObject(_agent.IsFemale ? "Her" : "His") },
                    { "HISHERLOWER", new TextObject(_agent.IsFemale ? "her" : "his") }
                }
                                 );
            }

            int mCap = _config.AI.MaximumMoralePerAgent;

            _moraleChange = (int)Math.Round((_leadership / 15f).Clamp(mCap * -1, mCap));

            if (_config.Cheering.PreventNegativeMorale)
            {
                _moraleChange.Clamp(0, 100);
            }

            var friendlyAgentsList = _agentsInArea.Where(x => x.Team.IsFriendOf(_agent.Team));
            var enemyAgentsList    = _agentsInArea.Where(x => x.Team.IsEnemyOf(_agent.Team));

            var totalFriendlyMoraleApplied = 0;
            var totalEnemyMoraleApplied    = 0;

            foreach (var a in friendlyAgentsList)
            {
                _common.ApplyCheerEffects(a, _moraleChange);
                totalFriendlyMoraleApplied += _common.ApplyMoraleChange(a, _moraleChange, noNegativeMorale: _config.Cheering.PreventNegativeMorale);
            }

            if (_leadership >= _config.Cheering.EnemyMoraleLeadershipThreshold)
            {
                foreach (var a in enemyAgentsList)
                {
                    totalEnemyMoraleApplied += _common.ApplyMoraleChange(a, _moraleChange, true);
                    _common.ApplyCheerEffects(a, _moraleChange, false);
                    a.MakeVoice(SkinVoiceManager.VoiceType.Victory, SkinVoiceManager.CombatVoiceNetworkPredictionType.NoPrediction);
                }
            }

            _cheerAmount--;
        }
        /// <summary>
        /// Calculates morale changed, effect radius, a list of agents to be affected. Handles morale report and applies XP increase.
        /// </summary>
        private async Task DoInCombatCheer()
        {
            if (_cheerAmount < 1)
            {
                Helpers.Say("{=failed}" + _strings.Failed);
                return;
            }
            if (Agent.Main == null)
            {
                return;
            }
            if (Agent.Main.Team == null)
            {
                return;
            }

            var leadership = Agent.Main.Character?.GetSkillValue(DefaultSkills.Leadership) ?? 0;

            var playerPower = 0f;
            var enemyPower  = 0f;
            var mCap        = _config.Cheering.MaximumMoralePerAgent;
            var aCap        = _config.Cheering.MaximumAdvantageMorale;

            try {
                foreach (var team in Mission.Current.Teams)
                {
                    foreach (var f in team.Formations)
                    {
                        if (f.Team.Side == Agent.Main.Team.Side)
                        {
                            playerPower += f.GetFormationPower();
                        }
                        else
                        {
                            enemyPower += f.GetFormationPower();
                        }
                    }
                }
            } catch { }

            float advantageBonus = ((playerPower - enemyPower) / 20).Clamp(aCap * -1, aCap);

            _moraleChange = (int)Math.Round(((leadership / 18) + advantageBonus).Clamp(mCap * -1, mCap));
            _effectRadius = (leadership / 2).Clamp(25, 200);

            try {
                var agentsList = Mission.GetAgentsInRange(Agent.Main.Position.AsVec2, _effectRadius)
                                 .Where(x => x != null)
                                 .Where(x => x.IsMount == false)
                                 .Where(x => x.Character != null)
                                 .Where(x => x.Health > 0)
                                 .Where(x => x.IsMainAgent == false);

                var friendlyAgentsList = agentsList.Where(x => x != null && x.IsFriendOf(Agent.Main)).ToList();
                var enemyAgentsList    = agentsList.Where(x => x != null && x.IsEnemyOf(Agent.Main)).ToList();

                var totalFriendlyMoraleApplied = 0;
                var totalEnemyMoraleApplied    = 0;
                _common.ApplyCheerEffects(Agent.Main, _moraleChange);
                await Task.Delay(TimeSpan.FromSeconds(0.65));

                foreach (var a in friendlyAgentsList)
                {
                    _common.ApplyCheerEffects(a, _moraleChange);
                    await Task.Delay(_rng.Next(0, 9));

                    totalFriendlyMoraleApplied += _common.ApplyMoraleChange(a, _moraleChange, noNegativeMorale: _config.Cheering.PreventNegativeMorale);
                }

                if (leadership >= _config.Cheering.EnemyMoraleLeadershipThreshold)
                {
                    foreach (var a in enemyAgentsList)
                    {
                        totalEnemyMoraleApplied += _common.ApplyMoraleChange(a, _moraleChange, true);
                        _common.ApplyCheerEffects(a, _moraleChange, false);
                        a.MakeVoice(SkinVoiceManager.VoiceType.Victory, SkinVoiceManager.CombatVoiceNetworkPredictionType.NoPrediction);
                    }
                }


                if (!(Campaign.Current is null))
                {
                    var calcResult = CalculateXpDividerAndMaxXP(leadership);

                    var xpToGrant = ((totalFriendlyMoraleApplied + (totalEnemyMoraleApplied * -1)) / calcResult[0])
                                    .Clamp(0, calcResult[1] * 400);

                    var mainHero = Hero.All.Where(x => x.StringId == Agent.Main.Character.StringId).FirstOrDefault();
                    // always grant some xp
                    if (xpToGrant == 0)
                    {
                        xpToGrant = 1;
                    }
                    mainHero.AddSkillXp(DefaultSkills.Leadership, xpToGrant);
                }

                _cheerAmount--;

                if (_config.Cheering.ReportMoraleChange)
                {
                    if (totalFriendlyMoraleApplied > 0)
                    {
                        Helpers.Say("{=friendly_positivemorale}" + _strings.Friendly.PositiveMorale
                                    .Replace("$AGENTMORALE$", _moraleChange.ToString())
                                    .Replace("$TOTALMORALE$", totalFriendlyMoraleApplied.ToString()),
                                    new Dictionary <string, TextObject> {
                            { "AGENTMORALE", new TextObject(_moraleChange) },
                            { "TOTALMORALE", new TextObject(totalFriendlyMoraleApplied) }
                        }
                                    );
                        if (leadership >= _config.Cheering.EnemyMoraleLeadershipThreshold && totalEnemyMoraleApplied > 0)
                        {
                            Helpers.Say("{=enemy_negativemorale}" + _strings.Enemy.NegativeMorale
                                        .Replace("$AGENTMORALE$", (_moraleChange / 2).ToString())
                                        .Replace("$TOTALMORALE$", totalEnemyMoraleApplied.ToString()),
                                        new Dictionary <string, TextObject> {
                                { "AGENTMORALE", new TextObject(_moraleChange / 2) },
                                { "TOTALMORALE", new TextObject(totalEnemyMoraleApplied) }
                            }
                                        );
                        }
                    }
                    else if (totalFriendlyMoraleApplied < 0)
                    {
                        Helpers.Say("{=friendly_negativemorale}" + _strings.Friendly.NegativeMorale
                                    .Replace("$AGENTMORALE$", _moraleChange.ToString())
                                    .Replace("$TOTALMORALE$", totalFriendlyMoraleApplied.ToString()),
                                    new Dictionary <string, TextObject> {
                            { "AGENTMORALE", new TextObject(_moraleChange) },
                            { "TOTALMORALE", new TextObject(totalFriendlyMoraleApplied) }
                        }
                                    );
                        if (leadership >= _config.Cheering.EnemyMoraleLeadershipThreshold && totalEnemyMoraleApplied > 0)
                        {
                            Helpers.Say("{=friendly_positivemorale}" + _strings.Enemy.PositiveMorale
                                        .Replace("$TOTALMORALE$", totalEnemyMoraleApplied.ToString()),
                                        new Dictionary <string, TextObject> {
                                { "TOTALMORALE", new TextObject(totalEnemyMoraleApplied) }
                            }
                                        );
                        }
                    }
                    else if (totalEnemyMoraleApplied > 0)
                    {
                        Helpers.Say("{=enemymoraleeffect}" + _strings.EnemyMoraleEffect
                                    .Replace("$AGENTMORALE$", (_moraleChange / 2).ToString())
                                    .Replace("$TOTALMORALE$", totalEnemyMoraleApplied.ToString()),
                                    new Dictionary <string, TextObject> {
                            { "AGENTMORALE", new TextObject(_moraleChange / 2) },
                            { "TOTALMORALE", new TextObject(totalEnemyMoraleApplied) }
                        }
                                    );
                    }
                    else
                    {
                        Helpers.Say("{=noeffect}" + _strings.NoEffect);
                        _cheerAmount++;
                    }
                }
                else
                {
                    if (totalFriendlyMoraleApplied == 0 && totalEnemyMoraleApplied == 0)
                    {
                        _cheerAmount++;
                    }
                }
            } catch (Exception ex) {
                if (_config.Cheering.DebugMode)
                {
                    Helpers.Log(ex.Message);
                    Clipboard.SetText(ex.Message + "\n" + ex.StackTrace);
                }
            }
        }