示例#1
0
        private int OnGetRangedDamageBonus(void *pStats)
        {
            int damageBonus = getRangedDamageBonusHook.CallOriginal(pStats);

            CNWSCreatureStats stats  = CNWSCreatureStats.FromPointer(pStats);
            CNWSItem          weapon = stats.m_pBaseCreature.m_pInventory.GetItemInSlot((uint)EquipmentSlot.RightHand);

            if (weapon == null)
            {
                return(damageBonus);
            }

            uint baseItem             = weapon.m_nBaseItem;
            bool hasApplicableFeat    = false;
            bool applicableFeatExists = greaterWeaponSpecializationMap.TryGetValue(baseItem, out HashSet <ushort>?types);

            if (applicableFeatExists)
            {
                foreach (ushort feat in types !)
                {
                    hasApplicableFeat = stats.HasFeat(feat).ToBool();
                    if (hasApplicableFeat)
                    {
                        break;
                    }
                }
            }

            if (applicableFeatExists && hasApplicableFeat)
            {
                return(damageBonus + GreaterWeaponSpecializationDamageBonus);
            }

            return(damageBonus);
        }
示例#2
0
        private int OnGetDamageBonus(void *pStats, void *pCreature, int bOffHand)
        {
            int damageBonus = getDamageBonusHook.CallOriginal(pStats, pCreature, bOffHand);

            CNWSCreatureStats stats    = CNWSCreatureStats.FromPointer(pStats);
            CNWSCreature      creature = stats.m_pBaseCreature;
            bool     offHand           = bOffHand.ToBool();
            CNWSItem?weapon            = GetEquippedWeapon(creature, offHand);

            uint baseItem             = weapon != null ? weapon.m_nBaseItem : (uint)BaseItem.Gloves;
            bool hasApplicableFeat    = false;
            bool applicableFeatExists = greaterWeaponSpecializationMap.TryGetValue(baseItem, out HashSet <ushort>?types);

            if (applicableFeatExists)
            {
                foreach (ushort feat in types !)
                {
                    hasApplicableFeat = stats.HasFeat(feat).ToBool();
                    if (hasApplicableFeat)
                    {
                        break;
                    }
                }
            }

            if (applicableFeatExists && hasApplicableFeat)
            {
                damageBonus += GreaterWeaponSpecializationDamageBonus;
                if ((*NWNXLib.EnableCombatDebugging()).ToBool() && stats.m_bIsPC.ToBool())
                {
                    CNWSCombatAttackData currentAttack = creature.m_pcCombatRound.GetAttack(creature.m_pcCombatRound.m_nCurrentAttack);
                    StringBuilder        debugMessage  = new StringBuilder(currentAttack.m_sDamageDebugText.ToString());
                    debugMessage.Append(" + ");

                    if (currentAttack.m_nAttackResult == 3)
                    {
                        int criticalThreat = stats.GetCriticalHitMultiplier(bOffHand);
                        debugMessage.Append(GreaterWeaponSpecializationDamageBonus * criticalThreat);
                        debugMessage.Append(" (Greater Weapon Specialization Feat) (Critical x");
                        debugMessage.Append(criticalThreat);
                        debugMessage.Append(")");
                    }
                    else
                    {
                        debugMessage.Append(GreaterWeaponSpecializationDamageBonus);
                        debugMessage.Append(" (Greater Weapon Specialization Feat) ");
                    }

                    currentAttack.m_sDamageDebugText = debugMessage.ToString().ToExoString();
                }
            }

            return(damageBonus);
        }
示例#3
0
        private int OnGetWeaponFinesse(void *pStats, void *pWeapon)
        {
            if (pStats == null)
            {
                return(false.ToInt());
            }

            CNWSCreatureStats creatureStats = CNWSCreatureStats.FromPointer(pStats);

            if (!creatureStats.HasFeat((ushort)Feat.WeaponFinesse).ToBool())
            {
                return(0);
            }

            return(IsWeaponLight(creatureStats, CNWSItem.FromPointer(pWeapon), true).ToInt());
        }
示例#4
0
        private int OnGetEpicWeaponDevastatingCritical(void *pStats, void *pWeapon)
        {
            CNWSCreatureStats stats  = CNWSCreatureStats.FromPointer(pStats);
            CNWSItem          weapon = CNWSItem.FromPointer(pWeapon);
            uint weaponType          = weapon == null ? (uint)BaseItem.Gloves : CNWSItem.FromPointer(pWeapon).m_nBaseItem;

            bool hasApplicableFeat    = false;
            bool applicableFeatExists = epicWeaponDevastatingCriticalMap.TryGetValue(weaponType, out HashSet <ushort>?types);

            if (applicableFeatExists)
            {
                foreach (ushort feat in types !)
                {
                    hasApplicableFeat = stats.HasFeat(feat).ToBool();
                    if (hasApplicableFeat)
                    {
                        break;
                    }
                }
            }

            bool canUseFeat = applicableFeatExists && hasApplicableFeat || getEpicWeaponDevastatingCriticalHook.CallOriginal(pStats, pWeapon).ToBool();

            if (weapon != null && canUseFeat && OnDevastatingCriticalHit != null)
            {
                CNWSCreature         creature    = stats.m_pBaseCreature;
                CNWSCombatRound      combatRound = creature.m_pcCombatRound;
                CNWSCombatAttackData attackData  = combatRound.GetAttack(combatRound.m_nCurrentAttack);

                DevastatingCriticalData devastatingCriticalData = new DevastatingCriticalData
                {
                    Weapon = weapon.ToNwObject <NwItem>() !,
                    Target = creature.m_oidAttackTarget.ToNwObject <NwGameObject>() !,
                    Damage = attackData.GetTotalDamage(1),
                };

                OnDevastatingCriticalHit(devastatingCriticalData);
                if (devastatingCriticalData.Bypass)
                {
                    attackData.m_bKillingBlow = 0;
                    return(0);
                }
            }

            return(canUseFeat.ToInt());
        }
示例#5
0
        private int OnGetRangedAttackBonus(void *pStats, int bIncludeBase, int bTouchAttack)
        {
            int attackBonus = getRangedAttackBonusHook.CallOriginal(pStats, bIncludeBase, bTouchAttack);

            if (bTouchAttack.ToBool())
            {
                return(attackBonus);
            }

            CNWSCreatureStats stats  = CNWSCreatureStats.FromPointer(pStats);
            CNWSItem          weapon = stats.m_pBaseCreature.m_pInventory.GetItemInSlot((uint)EquipmentSlot.RightHand);

            if (weapon == null)
            {
                return(attackBonus);
            }

            uint baseItem             = weapon.m_nBaseItem;
            bool hasApplicableFeat    = false;
            bool applicableFeatExists = greaterWeaponFocusMap.TryGetValue(baseItem, out HashSet <ushort>?types);

            if (applicableFeatExists)
            {
                foreach (ushort feat in types !)
                {
                    hasApplicableFeat = stats.HasFeat(feat).ToBool();
                    if (hasApplicableFeat)
                    {
                        break;
                    }
                }
            }

            if (applicableFeatExists && hasApplicableFeat)
            {
                attackBonus += GreaterWeaponFocusAttackBonus;
            }

            if (EnableSlingGoodAimFeat && baseItem == (uint)BaseItem.Sling && stats.m_nRace != (ushort)RacialType.Halfling && stats.HasFeat((ushort)Feat.GoodAim).ToBool())
            {
                attackBonus += 1;
            }

            return(attackBonus);
        }
示例#6
0
        private int OnGetIsWeaponOfChoice(void *pStats, uint nBaseItem)
        {
            CNWSCreatureStats stats = CNWSCreatureStats.FromPointer(pStats);

            bool hasApplicableFeat    = false;
            bool applicableFeatExists = weaponOfChoiceMap.TryGetValue(nBaseItem, out HashSet <ushort>?types);

            if (applicableFeatExists)
            {
                foreach (ushort feat in types !)
                {
                    hasApplicableFeat = stats.HasFeat(feat).ToBool();
                    if (hasApplicableFeat)
                    {
                        break;
                    }
                }
            }

            return(applicableFeatExists && hasApplicableFeat ? 1 : getIsWeaponOfChoiceHook.CallOriginal(pStats, nBaseItem));
        }
示例#7
0
        private int OnGetWeaponImprovedCritical(void *pStats, void *pWeapon)
        {
            CNWSCreatureStats stats = CNWSCreatureStats.FromPointer(pStats);
            uint weaponType         = pWeapon == null ? (uint)BaseItem.Gloves : CNWSItem.FromPointer(pWeapon).m_nBaseItem;

            bool hasApplicableFeat    = false;
            bool applicableFeatExists = weaponImprovedCriticalMap.TryGetValue(weaponType, out HashSet <ushort>?types);

            if (applicableFeatExists)
            {
                foreach (ushort feat in types !)
                {
                    hasApplicableFeat = stats.HasFeat(feat).ToBool();
                    if (hasApplicableFeat)
                    {
                        break;
                    }
                }
            }

            return(applicableFeatExists && hasApplicableFeat ? 1 : getWeaponImprovedCriticalHook.CallOriginal(pStats, pWeapon));
        }
示例#8
0
        private int OnGetEpicWeaponFocus(void *pStats, void *pWeapon)
        {
            CNWSCreatureStats stats = CNWSCreatureStats.FromPointer(pStats);
            uint weaponType         = pWeapon == null ? (uint)BaseItem.Gloves : CNWSItem.FromPointer(pWeapon).m_nBaseItem;

            bool hasApplicableFeat    = false;
            bool applicableFeatExists = epicWeaponFocusMap.TryGetValue(weaponType, out HashSet <ushort>?types);

            if (applicableFeatExists)
            {
                foreach (ushort feat in types !)
                {
                    hasApplicableFeat = stats.HasFeat(feat).ToBool() || feat == (ushort)Feat.EpicWeaponFocus_Creature && stats.HasFeat((ushort)Feat.EpicWeaponFocus_Unarmed).ToBool();
                    if (hasApplicableFeat)
                    {
                        break;
                    }
                }
            }

            return(applicableFeatExists && hasApplicableFeat ? 1 : getEpicWeaponFocusHook.CallOriginal(pStats, pWeapon));
        }
示例#9
0
        private int OnGetMeleeDamageBonus(void *pStats, int bOffHand, byte nCreatureWeaponIndex)
        {
            int damageBonus = getMeleeDamageBonusHook.CallOriginal(pStats, bOffHand, nCreatureWeaponIndex);

            CNWSCreatureStats stats    = CNWSCreatureStats.FromPointer(pStats);
            CNWSCreature      creature = stats.m_pBaseCreature;
            bool offHand = bOffHand.ToBool();

            CNWSItem?weapon = null;

            if (nCreatureWeaponIndex == 255)
            {
                weapon = GetEquippedWeapon(creature, offHand);
            }

            uint baseItem             = weapon != null ? weapon.m_nBaseItem : (uint)BaseItem.Gloves;
            bool hasApplicableFeat    = false;
            bool applicableFeatExists = greaterWeaponSpecializationMap.TryGetValue(baseItem, out HashSet <ushort>?types);

            if (applicableFeatExists)
            {
                foreach (ushort feat in types !)
                {
                    hasApplicableFeat = stats.HasFeat(feat).ToBool();
                    if (hasApplicableFeat)
                    {
                        break;
                    }
                }
            }

            if (applicableFeatExists && hasApplicableFeat)
            {
                return(damageBonus + GreaterWeaponSpecializationDamageBonus);
            }

            return(damageBonus);
        }
示例#10
0
        private int OnGetMeleeAttackBonus(void *pStats, int bOffHand, int bIncludeBase, int bTouchAttack)
        {
            int attackBonus = getMeleeAttackBonusHook.CallOriginal(pStats, bOffHand, bIncludeBase, bTouchAttack);

            if (bTouchAttack.ToBool())
            {
                return(attackBonus);
            }

            CNWSCreatureStats stats    = CNWSCreatureStats.FromPointer(pStats);
            CNWSCreature      creature = stats.m_pBaseCreature;
            bool offHand = bOffHand.ToBool();

            CNWSItem?weapon   = GetEquippedWeapon(creature, offHand);
            uint     baseItem = weapon != null ? weapon.m_nBaseItem : (uint)BaseItem.Gloves;

            bool hasApplicableFeat    = false;
            bool applicableFeatExists = greaterWeaponFocusMap.TryGetValue(baseItem, out HashSet <ushort>?types);

            if (applicableFeatExists)
            {
                foreach (ushort feat in types !)
                {
                    hasApplicableFeat = stats.HasFeat(feat).ToBool();
                    if (hasApplicableFeat)
                    {
                        break;
                    }
                }
            }

            if (applicableFeatExists && hasApplicableFeat)
            {
                return(attackBonus + GreaterWeaponFocusAttackBonus);
            }

            return(attackBonus);
        }
示例#11
0
        private int OnGetAttackModifierVersus(void *pStats, void *pCreature)
        {
            int attackMod = getAttackModifierVersusHook.CallOriginal(pStats, pCreature);

            CNWSCreatureStats stats       = CNWSCreatureStats.FromPointer(pStats);
            CNWSCreature      creature    = stats.m_pBaseCreature;
            CNWSCombatRound   combatRound = creature.m_pcCombatRound;

            if (combatRound == null)
            {
                return(attackMod);
            }

            CNWSItem weapon = combatRound.GetCurrentAttackWeapon(combatRound.GetWeaponAttackType());

            if (weapon == null)
            {
                return(attackMod);
            }

            uint baseItem             = weapon.m_nBaseItem;
            bool hasApplicableFeat    = false;
            bool applicableFeatExists = greaterWeaponFocusMap.TryGetValue(baseItem, out HashSet <ushort>?types);

            if (applicableFeatExists)
            {
                foreach (ushort feat in types !)
                {
                    hasApplicableFeat = stats.HasFeat(feat).ToBool();
                    if (hasApplicableFeat)
                    {
                        break;
                    }
                }
            }

            if (applicableFeatExists && hasApplicableFeat)
            {
                attackMod += GreaterWeaponFocusAttackBonus;

                if ((*NWNXLib.EnableCombatDebugging()).ToBool() && stats.m_bIsPC.ToBool())
                {
                    CNWSCombatAttackData currentAttack = combatRound.GetAttack(combatRound.m_nCurrentAttack);
                    StringBuilder        debugMessage  = new StringBuilder(currentAttack.m_sDamageDebugText.ToString());
                    debugMessage.Append(" + ");
                    debugMessage.Append(GreaterWeaponFocusAttackBonus);
                    debugMessage.Append(" (Greater Weapon Focus Feat)");

                    currentAttack.m_sDamageDebugText = debugMessage.ToString().ToExoString();
                }
            }

            if (EnableSlingGoodAimFeat && baseItem == (uint)BaseItem.Sling && stats.m_nRace != (ushort)RacialType.Halfling && stats.HasFeat((ushort)Feat.GoodAim).ToBool())
            {
                int goodAimModifier = NWNXLib.Rules().GetRulesetIntEntry("GOOD_AIM_MODIFIER".ToExoString(), 1);
                attackMod += goodAimModifier;

                if ((*NWNXLib.EnableCombatDebugging()).ToBool() && stats.m_bIsPC.ToBool())
                {
                    CNWSCombatAttackData currentAttack = combatRound.GetAttack(combatRound.m_nCurrentAttack);
                    StringBuilder        debugMessage  = new StringBuilder(currentAttack.m_sDamageDebugText.ToString());
                    debugMessage.Append(" + ");
                    debugMessage.Append(goodAimModifier);
                    debugMessage.Append(" (Good Aim Feat)");

                    currentAttack.m_sDamageDebugText = debugMessage.ToString().ToExoString();
                }
            }

            return(attackMod);
        }