private void AppendDamage(CharacterInfo sender, CharacterInfo receiver, ImpactInfo impactInfo, int parentDamage)
        {
            if (sender == null || receiver == null || impactInfo == null)
            {
                return;
            }
            int       skillLevel = 0;
            bool      isCritical = false;
            bool      isOrdinary = false;
            SkillInfo skillInfo  = sender.GetSkillStateInfo().GetSkillInfoById(impactInfo.m_SkillId);

            if (null != skillInfo)
            {
                skillLevel = skillInfo.SkillLevel;
                if (skillInfo.Category == SkillCategory.kAttack)
                {
                    isOrdinary = true;
                }
            }
            ElementDamageType element_type = (ElementDamageType)impactInfo.ConfigData.ElementType;

            if (ElementDamageType.DC_None == element_type)
            {
                element_type = sender.GetEquipmentStateInfo().WeaponDamageType;
            }
            int appendDamage = (int)(impactInfo.ConfigData.DamageRate * parentDamage + impactInfo.ConfigData.DamageValue);

            if (appendDamage <= 0)
            {
                return;
            }
            int curDamage = DamageCalculator.CalcImpactDamage(sender, receiver,
                                                              (SkillDamageType)impactInfo.ConfigData.DamageType,
                                                              element_type,
                                                              0,
                                                              appendDamage,
                                                              out isCritical);
            List <ImpactInfo> impactInfos = receiver.GetSkillStateInfo().GetAllImpact();

            for (int i = 0; i < impactInfos.Count; i++)
            {
                IImpactLogic logic = ImpactLogicManager.Instance.GetImpactLogic(impactInfos[i].ConfigData.ImpactLogicId);
                if (null != logic)
                {
                    curDamage = logic.RefixHpDamage(receiver, impactInfos[i].m_ImpactId, curDamage, sender.GetId(), ref isCritical, receiver.GetId());
                }
            }

            /*
             * foreach (ImpactInfo ii in receiver.GetSkillStateInfo().GetAllImpact()) {
             * IImpactLogic logic = ImpactLogicManager.Instance.GetImpactLogic(ii.ConfigData.ImpactLogicId);
             * if (null != logic) {
             *  curDamage = logic.RefixHpDamage(receiver, ii.m_ImpactId, curDamage, sender.GetId(), ref isCritical, receiver.GetId());
             * }
             * }*/
            OnCharacterDamage(sender, receiver, curDamage, isCritical, isOrdinary);
        }
        public bool CollectDataFromDBC(DBC_Row node)
        {
            m_ItemId            = DBCUtil.ExtractNumeric <int>(node, "ItemId", 0, true);
            m_ItemName          = DBCUtil.ExtractString(node, "ItemName", "", true);
            m_ItemTrueName      = DBCUtil.ExtractString(node, "ItemTrueName", "", true);
            m_ItemCategory      = DBCUtil.ExtractNumeric <int>(node, "ItemCategory", -1, false);
            m_ItemType          = DBCUtil.ExtractString(node, "ItemType", "", true);
            m_Description       = DBCUtil.ExtractString(node, "Description", "", false);
            m_Grade             = DBCUtil.ExtractNumeric <int>(node, "Grade", 0, false);
            m_ExperienceProvide = DBCUtil.ExtractNumeric <int>(node, "ExperienceProvide", 0, false);
            m_UseLogicId        = DBCUtil.ExtractNumeric <int>(node, "UseLogicId", 0, false);
            List <string> strList = DBCUtil.ExtractStringList(node, "UseResultData", "", false);

            if (strList.Count > 0)
            {
                m_UseResultData = strList.ToArray();
            }
            List <int> list = DBCUtil.ExtractNumericList <int>(node, "ActiveBuffOnLevel", 0, false);

            if (list.Count > 0)
            {
                m_ActiveBuffOnLevel = list.ToArray();
            }
            m_UseIconOnLevel  = DBCUtil.ExtractString(node, "UseIconOnLevel", "", false).Split('|');
            m_UseModelOnLevel = DBCUtil.ExtractString(node, "UseModelOnLevel", "", false).Split('|');
            list = DBCUtil.ExtractNumericList <int>(node, "AddBuffOnEquiping", 0, false);
            if (list.Count > 0)
            {
                m_AddBuffOnEquiping = list.ToArray();
            }
            list = DBCUtil.ExtractNumericList <int>(node, "AddSkillOnEquiping", 0, false);
            if (list.Count > 0)
            {
                m_AddSkillOnEquiping = list.ToArray();
            }
            m_ShowInShop = (0 != DBCUtil.ExtractNumeric <int>(node, "ShowInShop", 0, false));
            m_Model      = DBCUtil.ExtractString(node, "Model", "", false);
            m_UiModel    = DBCUtil.ExtractString(node, "UiModel", "", false);
            m_MaxStack   = DBCUtil.ExtractNumeric <int>(node, "MaxStackNum", 1, false);
            list         = DBCUtil.ExtractNumericList <int>(node, "ConsumeItems", 0, false);
            if (list.Count > 0)
            {
                m_ConsumeItems = list.ToArray();
            }
            else
            {
                m_ConsumeItems = new int[] { 0, 0, 0 };
            }
            m_ConsumeMoney    = DBCUtil.ExtractNumeric <int>(node, "ConsumeMoney", 0, false);
            m_PropertyRank    = DBCUtil.ExtractNumeric <int>(node, "PropertyRank", 0, true);
            m_AddExp          = DBCUtil.ExtractNumeric <int>(node, "AddExp", 0, false);
            m_AddMoney        = DBCUtil.ExtractNumeric <int>(node, "AddMoney", 0, false);
            m_AddBuff         = DBCUtil.ExtractNumeric <int>(node, "AddBuffer", 0, false);
            m_Introduce       = DBCUtil.ExtractString(node, "Introduce", "", false);
            m_ItemSkillFirst  = DBCUtil.ExtractNumeric <int>(node, "ItemSkillFirst", 0, false);
            m_ItemSkillSecond = DBCUtil.ExtractNumeric <int>(node, "ItemSkillSecond", 0, false);
            m_ItemSkillThird  = DBCUtil.ExtractNumeric <int>(node, "ItemSkillThird", 0, false);
            m_NormalIcon      = DBCUtil.ExtractString(node, "NormalIcon", "", false);
            m_BigIcon         = DBCUtil.ExtractString(node, "BigIcon", "", false);
            m_AttrData.CollectDataFromDBC(node);
            m_CanWear          = DBCUtil.ExtractNumeric <bool>(node, "CanWear", false, false);
            m_WearParts        = DBCUtil.ExtractNumeric <int>(node, "WearParts", -1, false);
            m_WearLevel        = DBCUtil.ExtractNumeric <int>(node, "WearLevel", 1, false);
            m_WearNodeAndName  = DBCUtil.ExtractString(node, "WearNodeAndName", "", false);
            m_CanUpgrade       = DBCUtil.ExtractNumeric <bool>(node, "CanUpgrade", false, false);
            m_CanDeve          = DBCUtil.ExtractNumeric <bool>(node, "CanDeve", false, false);
            m_AttachedProperty = DBCUtil.ExtractNumericList(node, "AttachedProperty", 0, false);
            m_TalentType       = DBCUtil.ExtractNumeric <int>(node, "TalentType", 1, false);
            m_TalentAttributes = DBCUtil.ExtractNumericList(node, "TalentAttributes", 0, false);
            m_ActiveAttributes = DBCUtil.ExtractNumericList(node, "ActiveAttributes", 0, false);
            m_CompoundItemId   = DBCUtil.ExtractNumericList(node, "CompoundItemId", 0, false);
            m_Inlay            = DBCUtil.ExtractString(node, "Inlay", "", false);
            m_Weight           = DBCUtil.ExtractNumeric <int>(node, "Weight", -1, false);
            m_SellingPrice     = DBCUtil.ExtractNumeric <int>(node, "SellingPrice", 0, false);
            m_SellGainGoldProb = DBCUtil.ExtractNumeric <float>(node, "SellGainGoldProb", 0f, false);
            m_SellGainGoldNum  = DBCUtil.ExtractNumeric <int>(node, "SellGainGoldNum", 0, false);
            m_DamageType       = (ElementDamageType)DBCUtil.ExtractNumeric <int>(node, "ElementType", 0, false);
            m_ItemSourceScene  = DBCUtil.ExtractNumericList <int>(node, "ItemSourceScene", int.MinValue, false);
            m_ItemSourceDesc   = DBCUtil.ExtractString(node, "ItemSourceDesc", "", false);
            m_ShowType         = DBCUtil.ExtractNumeric <int>(node, "ShowType", 0, false);
            m_SkeletonSource   = DBCUtil.ExtractString(node, "SkeletonSource", "", false);
            return(true);
        }
        public static int CalcImpactDamage(CharacterInfo sender,
                                           CharacterInfo receiver,
                                           SkillDamageType damageType,
                                           ElementDamageType elementType,
                                           float attackFactor,
                                           int damageFromConfig,
                                           out bool isCritical)
        {
            isCritical = false;
            if (null == sender || null == receiver)
            {
                return(damageFromConfig);
            }

            int   ad    = sender.GetActualProperty().AttackBase;
            int   adp   = receiver.GetActualProperty().ADefenceBase;
            int   mdp   = receiver.GetActualProperty().MDefenceBase;
            int   level = receiver.GetLevel();
            float fd    = sender.GetActualProperty().FireDamage;
            float fe    = receiver.GetActualProperty().FireERD;
            float id    = sender.GetActualProperty().IceDamage;
            float ie    = receiver.GetActualProperty().IceERD;
            float pd    = sender.GetActualProperty().PoisonDamage;
            float pe    = receiver.GetActualProperty().PoisonERD;
            float c     = sender.GetActualProperty().Critical;
            float cp    = sender.GetActualProperty().CriticalPow;
            float cbhp  = sender.GetActualProperty().CriticalBackHitPow;
            float ccp   = sender.GetActualProperty().CriticalCrackPow;
            float sd    = sender.GetMovementStateInfo().GetFaceDir();
            float rd    = receiver.GetMovementStateInfo().GetFaceDir();

            if (level <= 0)
            {
                return(damageFromConfig);
            }

            float baseDamage    = 0f;
            float elementDamage = 0f;
            float normalDamage  = 0f;
            float skillDamage   = 0f;
            float totalDamage   = damageFromConfig;

            /// base
            if (SkillDamageType.DC_Ad == damageType)
            {
                if (IsInvalid(adp, level))
                {
                    baseDamage = 0;
                }
                else
                {
                    baseDamage = ad * (1 - (adp / (float)level) / (float)(10 + Math.Abs(adp) / (float)level));
                }
            }
            else if (SkillDamageType.DC_Ap == damageType)
            {
                if (IsInvalid(mdp, level))
                {
                    baseDamage = 0;
                }
                else
                {
                    baseDamage = ad * (1 - (mdp / (float)level) / (float)(10 + Math.Abs(mdp) / (float)level));
                }
            }
            /// element
            if (ElementDamageType.DC_Fire == elementType)
            {
                if (IsInvalid(fe, level))
                {
                    elementDamage = 0;
                }
                else
                {
                    elementDamage = fd * (1 - (fe / (float)level) / (float)(10 + Math.Abs(fe) / (float)level));
                }
            }
            else if (ElementDamageType.DC_Ice == elementType)
            {
                if (IsInvalid(ie, level))
                {
                    elementDamage = 0;
                }
                else
                {
                    elementDamage = id * (1 - (ie / (float)level) / (float)(10 + Math.Abs(ie) / (float)level));
                }
            }
            else if (ElementDamageType.DC_Poison == elementType)
            {
                if (IsInvalid(pe, level))
                {
                    elementDamage = 0;
                }
                else
                {
                    elementDamage = pd * (1 - (pe / (float)level) / (float)(10 + Math.Abs(pe) / (float)level));
                }
            }
            /// normal
            normalDamage = (baseDamage + elementDamage) * attackFactor;
            /// skill
            if (IsInvalid(adp, level))
            {
                skillDamage = 0;
            }
            else
            {
                skillDamage = damageFromConfig * (1 - (adp / (float)level) / (float)(10 + Math.Abs(adp) / (float)level));
            }
            /// total
            totalDamage = normalDamage + skillDamage;
            /// critical
            int   num    = CrossEngineHelper.Random.Next(0, 100);
            float random = (float)(num * 0.01);

            if (random < c)
            {
                isCritical   = true;
                totalDamage *= cp;
            }
            /// check backhit
            if (IsBackHit(sd, rd))
            {
                totalDamage *= cbhp;
            }
            /// ckeck crack
            if (IsCrack(receiver))
            {
                totalDamage *= ccp;
            }

            return((int)totalDamage);
        }