public void ApplyStatChanges(NWPlayer player, NWItem ignoreItem, bool isInitialization = false)
        {
            if (!player.IsPlayer)
            {
                return;
            }
            if (!player.IsInitializedAsPlayer)
            {
                return;
            }

            // Don't fire for ammo as it reapplies bonuses **just** removed from blasters.
            if (ignoreItem != null &&
                (ignoreItem.BaseItemType == BASE_ITEM_BOLT ||
                 ignoreItem.BaseItemType == BASE_ITEM_ARROW ||
                 ignoreItem.BaseItemType == BASE_ITEM_BULLET))
            {
                return;
            }

            Player             pcEntity    = _data.Get <Player>(player.GlobalID);
            List <PCSkill>     skills      = _data.Where <PCSkill>(x => x.PlayerID == player.GlobalID && x.Rank > 0).ToList();
            EffectiveItemStats itemBonuses = GetPlayerItemEffectiveStats(player, ignoreItem);

            float strBonus = 0.0f;
            float dexBonus = 0.0f;
            float conBonus = 0.0f;
            float intBonus = 0.0f;
            float wisBonus = 0.0f;
            float chaBonus = 0.0f;

            using (new Profiler("PlayerStatService::ApplyStatChanges::AttributeApplication"))
            {
                foreach (PCSkill pcSkill in skills)
                {
                    Skill           skill     = _data.Get <Skill>(pcSkill.SkillID);
                    CustomAttribute primary   = (CustomAttribute)skill.Primary;
                    CustomAttribute secondary = (CustomAttribute)skill.Secondary;
                    CustomAttribute tertiary  = (CustomAttribute)skill.Tertiary;

                    // Primary Bonuses
                    if (primary == CustomAttribute.STR)
                    {
                        strBonus += PrimaryIncrease * pcSkill.Rank;
                    }
                    else if (primary == CustomAttribute.DEX)
                    {
                        dexBonus += PrimaryIncrease * pcSkill.Rank;
                    }
                    else if (primary == CustomAttribute.CON)
                    {
                        conBonus += PrimaryIncrease * pcSkill.Rank;
                    }
                    else if (primary == CustomAttribute.INT)
                    {
                        intBonus += PrimaryIncrease * pcSkill.Rank;
                    }
                    else if (primary == CustomAttribute.WIS)
                    {
                        wisBonus += PrimaryIncrease * pcSkill.Rank;
                    }
                    else if (primary == CustomAttribute.CHA)
                    {
                        chaBonus += PrimaryIncrease * pcSkill.Rank;
                    }

                    // Secondary Bonuses
                    if (secondary == CustomAttribute.STR)
                    {
                        strBonus += SecondaryIncrease * pcSkill.Rank;
                    }
                    else if (secondary == CustomAttribute.DEX)
                    {
                        dexBonus += SecondaryIncrease * pcSkill.Rank;
                    }
                    else if (secondary == CustomAttribute.CON)
                    {
                        conBonus += SecondaryIncrease * pcSkill.Rank;
                    }
                    else if (secondary == CustomAttribute.INT)
                    {
                        intBonus += SecondaryIncrease * pcSkill.Rank;
                    }
                    else if (secondary == CustomAttribute.WIS)
                    {
                        wisBonus += SecondaryIncrease * pcSkill.Rank;
                    }
                    else if (secondary == CustomAttribute.CHA)
                    {
                        chaBonus += SecondaryIncrease * pcSkill.Rank;
                    }

                    // Tertiary Bonuses
                    if (tertiary == CustomAttribute.STR)
                    {
                        strBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                    else if (tertiary == CustomAttribute.DEX)
                    {
                        dexBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                    else if (tertiary == CustomAttribute.CON)
                    {
                        conBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                    else if (tertiary == CustomAttribute.INT)
                    {
                        intBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                    else if (tertiary == CustomAttribute.WIS)
                    {
                        wisBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                    else if (tertiary == CustomAttribute.CHA)
                    {
                        chaBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                }
            }


            // Check caps.
            if (strBonus > MaxAttributeBonus)
            {
                strBonus = MaxAttributeBonus;
            }
            if (dexBonus > MaxAttributeBonus)
            {
                dexBonus = MaxAttributeBonus;
            }
            if (conBonus > MaxAttributeBonus)
            {
                conBonus = MaxAttributeBonus;
            }
            if (intBonus > MaxAttributeBonus)
            {
                intBonus = MaxAttributeBonus;
            }
            if (wisBonus > MaxAttributeBonus)
            {
                wisBonus = MaxAttributeBonus;
            }
            if (chaBonus > MaxAttributeBonus)
            {
                chaBonus = MaxAttributeBonus;
            }

            // Apply item bonuses
            strBonus += itemBonuses.Strength;
            dexBonus += itemBonuses.Dexterity;
            conBonus += itemBonuses.Constitution;
            wisBonus += itemBonuses.Wisdom;
            intBonus += itemBonuses.Intelligence;
            chaBonus += itemBonuses.Charisma;

            // Check final caps
            if (strBonus > 100)
            {
                strBonus = 100;
            }
            if (dexBonus > 100)
            {
                dexBonus = 100;
            }
            if (conBonus > 100)
            {
                conBonus = 100;
            }
            if (intBonus > 100)
            {
                intBonus = 100;
            }
            if (wisBonus > 100)
            {
                wisBonus = 100;
            }
            if (chaBonus > 100)
            {
                chaBonus = 100;
            }

            // Apply attributes
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_STRENGTH, (int)strBonus + pcEntity.STRBase);
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_DEXTERITY, (int)dexBonus + pcEntity.DEXBase);
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_CONSTITUTION, (int)conBonus + pcEntity.CONBase);
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_INTELLIGENCE, (int)intBonus + pcEntity.INTBase);
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_WISDOM, (int)wisBonus + pcEntity.WISBase);
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_CHARISMA, (int)chaBonus + pcEntity.CHABase);

            // Apply AC

            using (new Profiler("PlayerStatService::ApplyStatChanges::CalcAC"))
            {
                int ac = EffectiveArmorClass(itemBonuses, player);
                _nwnxCreature.SetBaseAC(player, ac);
            }


            // Apply BAB

            using (new Profiler("PlayerStatService::ApplyStatChanges::CalcBAB"))
            {
                int bab = CalculateBAB(player, ignoreItem, itemBonuses);
                _nwnxCreature.SetBaseAttackBonus(player, bab);
            }

            // Apply HP

            using (new Profiler("PlayerStatService::ApplyStatChanges::CalcHP"))
            {
                int hp = EffectiveMaxHitPoints(player, itemBonuses);
                for (int level = 1; level <= 5; level++)
                {
                    hp--;
                    _nwnxCreature.SetMaxHitPointsByLevel(player, level, 1);
                }

                for (int level = 1; level <= 5; level++)
                {
                    if (hp > 255) // Levels can only contain a max of 255 HP
                    {
                        _nwnxCreature.SetMaxHitPointsByLevel(player, level, 255);
                        hp = hp - 255;
                    }
                    else // Remaining value gets set to the level. (<255 hp)
                    {
                        _nwnxCreature.SetMaxHitPointsByLevel(player, level, hp + 1);
                        break;
                    }
                }
            }



            if (player.CurrentHP > player.MaxHP)
            {
                int    amount = player.CurrentHP - player.MaxHP;
                Effect damage = _.EffectDamage(amount);
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, damage, player.Object);
            }

            // Apply FP
            using (new Profiler("PlayerStatService::ApplyStatChanges::CalcFP"))
            {
                pcEntity.MaxFP = EffectiveMaxFP(player, itemBonuses);

                if (isInitialization)
                {
                    pcEntity.CurrentFP = pcEntity.MaxFP;
                }

                _data.SubmitDataChange(pcEntity, DatabaseActionType.Update);
            }
        }
Example #2
0
        public void ApplyStatChanges(NWPlayer player, NWItem ignoreItem)
        {
            if (!player.IsPlayer)
            {
                return;
            }
            if (!player.IsInitializedAsPlayer)
            {
                return;
            }

            PlayerCharacter pcEntity = _db.PlayerCharacters.Single(x => x.PlayerID == player.GlobalID);
            List <PCSkill>  skills   = _db.PCSkills.Where(x => x.PlayerID == player.GlobalID && x.Skill.IsActive).ToList();
            float           strBonus = 0.0f;
            float           dexBonus = 0.0f;
            float           conBonus = 0.0f;
            float           intBonus = 0.0f;
            float           wisBonus = 0.0f;
            float           chaBonus = 0.0f;

            foreach (PCSkill pcSkill in skills)
            {
                Skill           skill     = pcSkill.Skill;
                CustomAttribute primary   = (CustomAttribute)skill.Primary;
                CustomAttribute secondary = (CustomAttribute)skill.Secondary;
                CustomAttribute tertiary  = (CustomAttribute)skill.Tertiary;

                // Primary Bonuses
                if (primary == CustomAttribute.STR)
                {
                    strBonus += PrimaryIncrease * pcSkill.Rank;
                }
                else if (primary == CustomAttribute.DEX)
                {
                    dexBonus += PrimaryIncrease * pcSkill.Rank;
                }
                else if (primary == CustomAttribute.CON)
                {
                    conBonus += PrimaryIncrease * pcSkill.Rank;
                }
                else if (primary == CustomAttribute.INT)
                {
                    intBonus += PrimaryIncrease * pcSkill.Rank;
                }
                else if (primary == CustomAttribute.WIS)
                {
                    wisBonus += PrimaryIncrease * pcSkill.Rank;
                }
                else if (primary == CustomAttribute.CHA)
                {
                    chaBonus += PrimaryIncrease * pcSkill.Rank;
                }

                // Secondary Bonuses
                if (secondary == CustomAttribute.STR)
                {
                    strBonus += SecondaryIncrease * pcSkill.Rank;
                }
                else if (secondary == CustomAttribute.DEX)
                {
                    dexBonus += SecondaryIncrease * pcSkill.Rank;
                }
                else if (secondary == CustomAttribute.CON)
                {
                    conBonus += SecondaryIncrease * pcSkill.Rank;
                }
                else if (secondary == CustomAttribute.INT)
                {
                    intBonus += SecondaryIncrease * pcSkill.Rank;
                }
                else if (secondary == CustomAttribute.WIS)
                {
                    wisBonus += SecondaryIncrease * pcSkill.Rank;
                }
                else if (secondary == CustomAttribute.CHA)
                {
                    chaBonus += SecondaryIncrease * pcSkill.Rank;
                }

                // Tertiary Bonuses
                if (tertiary == CustomAttribute.STR)
                {
                    strBonus += TertiaryIncrease * pcSkill.Rank;
                }
                else if (tertiary == CustomAttribute.DEX)
                {
                    dexBonus += TertiaryIncrease * pcSkill.Rank;
                }
                else if (tertiary == CustomAttribute.CON)
                {
                    conBonus += TertiaryIncrease * pcSkill.Rank;
                }
                else if (tertiary == CustomAttribute.INT)
                {
                    intBonus += TertiaryIncrease * pcSkill.Rank;
                }
                else if (tertiary == CustomAttribute.WIS)
                {
                    wisBonus += TertiaryIncrease * pcSkill.Rank;
                }
                else if (tertiary == CustomAttribute.CHA)
                {
                    chaBonus += TertiaryIncrease * pcSkill.Rank;
                }
            }

            // Check caps.
            if (strBonus > MaxAttributeBonus)
            {
                strBonus = MaxAttributeBonus;
            }
            if (dexBonus > MaxAttributeBonus)
            {
                dexBonus = MaxAttributeBonus;
            }
            if (conBonus > MaxAttributeBonus)
            {
                conBonus = MaxAttributeBonus;
            }
            if (intBonus > MaxAttributeBonus)
            {
                intBonus = MaxAttributeBonus;
            }
            if (wisBonus > MaxAttributeBonus)
            {
                wisBonus = MaxAttributeBonus;
            }
            if (chaBonus > MaxAttributeBonus)
            {
                chaBonus = MaxAttributeBonus;
            }

            if (pcEntity.BackgroundID == (int)BackgroundType.Archer || pcEntity.BackgroundID == (int)BackgroundType.Crossbowman)
            {
                dexBonus++;
                wisBonus++;
            }
            if (pcEntity.BackgroundID == (int)BackgroundType.Guard || pcEntity.BackgroundID == (int)BackgroundType.Berserker)
            {
                strBonus++;
                conBonus++;
            }

            if (pcEntity.BackgroundID == (int)BackgroundType.TwinBladeSpecialist)
            {
                dexBonus++;
                conBonus++;
            }

            if (pcEntity.BackgroundID == (int)BackgroundType.MartialArtist)
            {
                strBonus++;
                dexBonus++;
            }

            // Apply attributes
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_STRENGTH, (int)strBonus + pcEntity.STRBase);
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_DEXTERITY, (int)dexBonus + pcEntity.DEXBase);
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_CONSTITUTION, (int)conBonus + pcEntity.CONBase);
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_INTELLIGENCE, (int)intBonus + pcEntity.INTBase);
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_WISDOM, (int)wisBonus + pcEntity.WISBase);
            _nwnxCreature.SetRawAbilityScore(player, ABILITY_CHARISMA, (int)chaBonus + pcEntity.CHABase);

            // Apply AC
            int ac = CalculateItemAC(player, ignoreItem) + _customEffect.CalculateEffectAC(player);

            _nwnxCreature.SetBaseAC(player, ac);

            // Apply BAB
            int bab = CalculateBAB(player, ignoreItem);

            _nwnxCreature.SetBaseAttackBonus(player, bab);


            int equippedItemHPBonus   = 0;
            int equippedItemManaBonus = 0;

            for (int slot = 0; slot < NUM_INVENTORY_SLOTS; slot++)
            {
                NWItem item = NWItem.Wrap(_.GetItemInSlot(slot, player.Object));
                if (item.Equals(ignoreItem))
                {
                    continue;
                }

                equippedItemHPBonus   += item.HPBonus;
                equippedItemManaBonus += item.ManaBonus;
            }

            // Apply HP
            int hp = 30 + player.ConstitutionModifier * 5;

            hp += _perk.GetPCPerkLevel(player, PerkType.Health) * 5;
            hp += equippedItemHPBonus;
            if (pcEntity.BackgroundID == (int)BackgroundType.Knight)
            {
                hp += 10;
            }

            if (hp > 255)
            {
                hp = 255;
            }
            if (hp < 20)
            {
                hp = 20;
            }
            _nwnxCreature.SetMaxHitPointsByLevel(player, 1, hp);
            if (player.CurrentHP > player.MaxHP)
            {
                int    amount = player.CurrentHP - player.MaxHP;
                Effect damage = _.EffectDamage(amount);
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, damage, player.Object);
            }

            // Apply Mana
            int mana = 20;

            mana += (player.IntelligenceModifier + player.WisdomModifier + player.CharismaModifier) * 5;
            mana += _perk.GetPCPerkLevel(player, PerkType.Mana) * 5;
            mana += equippedItemManaBonus;
            if (pcEntity.BackgroundID == (int)BackgroundType.Wizard || pcEntity.BackgroundID == (int)BackgroundType.Cleric)
            {
                mana += 10;
            }

            if (mana < 0)
            {
                mana = 0;
            }
            pcEntity.MaxMana = mana;

            _db.SaveChanges();
        }