Example #1
0
        public static Damage EvaluateSkillDamage(string damageScalingTreeID, Damage damage, BaseCharacter character)
        {
            var dmgHasVariance = Rm_RPGHandler.Instance.Items.DamageHasVariance;
            var combatant      = character;
            var combatCalcTree = Rm_RPGHandler.Instance.Nodes.CombatNodeBank.NodeTrees.First(n => n.ID == damageScalingTreeID);

            NodeChain nodeChain = null;

            if (dmgHasVariance)
            {
                nodeChain = new NodeChain(combatCalcTree, typeof(CombatStartNode), "MIN_Physical")
                {
                    CombatantA = combatant,
                    IntValue   = damage.MinDamage
                };
                while (!nodeChain.Done)
                {
                    nodeChain.Evaluate();
                }
            }


            var nodeChainMax = new NodeChain(combatCalcTree, typeof(CombatStartNode), "MAX_Physical")
            {
                Combatant = combatant, IntValue = damage.MaxDamage
            };

            while (!nodeChainMax.Done)
            {
                nodeChainMax.Evaluate();
            }

            damage.MinDamage = dmgHasVariance ? nodeChain.IntValue : nodeChainMax.IntValue;
            damage.MaxDamage = nodeChainMax.IntValue;

            foreach (var element in Rm_RPGHandler.Instance.ASVT.ElementalDamageDefinitions)
            {
                var       eleDamage = damage.ElementalDamages.FirstOrDefault(e => e.ElementID == element.ID);
                NodeChain chain     = null;
                if (dmgHasVariance)
                {
                    chain = new NodeChain(combatCalcTree, typeof(CombatStartNode), "MIN_" + element.ID)
                    {
                        Combatant = combatant, IntValue = eleDamage.MinDamage
                    };
                    while (!chain.Done)
                    {
                        chain.Evaluate();
                    }
                }


                var chainMax = new NodeChain(combatCalcTree, typeof(CombatStartNode), "MAX_" + element.ID)
                {
                    Combatant = combatant, IntValue = eleDamage.MaxDamage
                };
                while (!chainMax.Done)
                {
                    chainMax.Evaluate();
                }

                eleDamage.MinDamage = dmgHasVariance ? chain.IntValue : chainMax.IntValue;
                eleDamage.MaxDamage = chainMax.IntValue;
            }

            return(damage);
        }
Example #2
0
        public DamageOutcome Evaluate(BaseCharacter attacker, BaseCharacter defender, Damage attackerDamage)
        {
            var damageDealt   = attackerDamage.DamageDealt;
            var doNotEval     = false;
            var evalWithDummy = false;

            if (attacker == null)
            {
                if (Rm_RPGHandler.Instance.Combat.SkipEvaluatingDmgWithNullAttack)
                {
                    doNotEval = true;
                }
                else
                {
                    attacker = new BaseCharacter();
                    attacker.Init();
                    evalWithDummy = true;
                }
            }

            if (!doNotEval && !evalWithDummy && (attacker.CharacterType == CharacterType.Player || defender.CharacterType == CharacterType.Player))
            {
                var participants = new[] { attacker, defender };
                if (participants.All(p => p != null) && participants.Any(p => p.CharacterType != CharacterType.Player))
                {
                    var player = participants.First(p => p.CharacterType == CharacterType.Player);
                    var other  = participants.First(p => p.CharacterType != CharacterType.Player);

                    var cc = other as CombatCharacter;
                    if (!cc.AttackedOnceByPlayer)
                    {
                        var repDef = Rm_RPGHandler.Instance.Repositories.Quests.AllReputations.FirstOrDefault(r => r.ID == cc.ReputationId);
                        if (repDef != null)
                        {
                            if (repDef.ValueLossForNPCAttack > 0)
                            {
                                var playerRep = GetObject.PlayerSave.QuestLog.AllReputations.FirstOrDefault(r => r.ReputationID == cc.ReputationId);
                                if (playerRep != null)
                                {
                                    playerRep.Value -= repDef.ValueLossForNPCAttack;
                                }
                            }
                        }
                        cc.AttackedOnceByPlayer = true;
                    }
                }
            }

            var combatCalcTree = Rm_RPGHandler.Instance.Nodes.DamageTakenTree;

            if (defender.CharacterType == CharacterType.Player)
            {
                var playerDifficulty = GetObject.PlayerSave.Difficulty;
                var difficultyDef    = Rm_RPGHandler.Instance.Player.Difficulties.FirstOrDefault(d => d.ID == playerDifficulty);
                if (difficultyDef != null)
                {
                    attackerDamage.ApplyMultiplier(difficultyDef.DamageMultiplier);
                }
            }

            if (!doNotEval)
            {
                var nodeChain = new NodeChain(combatCalcTree, typeof(CombatStartNode), "DamageTaken")
                {
                    Attacker    = attacker,
                    Defender    = defender,
                    Damage      = attackerDamage,
                    DamageDealt = damageDealt
                };

                AttackOutcome?outcome = null;
                while (!nodeChain.Done)
                {
                    nodeChain.Evaluate();

                    if (nodeChain.CurrentNode is MissedHitNode)
                    {
                        outcome = AttackOutcome.Missed;
                    }
                    else if (nodeChain.CurrentNode is EvadedHitNode)
                    {
                        outcome = AttackOutcome.Evaded;
                    }
                }

                if (outcome != null && (outcome != AttackOutcome.Success || outcome != AttackOutcome.Critical))
                {
                    return(new DamageOutcome(null, outcome.Value));
                }
                else
                {
                    return(new DamageOutcome(attackerDamage, damageDealt, nodeChain.Damage.IsCritical ? AttackOutcome.Critical : AttackOutcome.Success));
                }
            }
            else
            {
                return(new DamageOutcome(attackerDamage, attackerDamage.DamageDealt, AttackOutcome.Success));
            }
        }