Exemplo n.º 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);
        }
Exemplo n.º 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);
        }
Exemplo n.º 3
0
            private static void OnClearMemorizedSpellSlot(void *pCreatureStats, byte nMultiClass, byte nSpellLevel, byte nSpellSlot)
            {
                CNWSCreatureStats creatureStats = CNWSCreatureStats.FromPointer(pCreatureStats);

                OnSpellSlotClear eventData = ProcessEvent(new OnSpellSlotClear
                {
                    Creature   = creatureStats.m_pBaseCreature.ToNwObject <NwCreature>() !,
                    ClassIndex = nMultiClass,
                    SpellLevel = nSpellLevel,
                    SlotIndex  = nSpellSlot,
                });
Exemplo n.º 4
0
        private int GetLevelByClass(CNWSCreatureStats stats, uint classType)
        {
            for (int i = 0; i < stats.m_nNumMultiClasses; i++)
            {
                CNWSCreatureStats_ClassInfo classInfo = stats.m_ClassInfo[i];
                if (classInfo.m_nClass == classType)
                {
                    return(classInfo.m_nLevel);
                }
            }

            return(0);
        }
Exemplo n.º 5
0
            private static int OnGetEffectImmunity(void *pStats, byte nType, void *pVerses, int bConsiderFeats)
            {
                CNWSCreatureStats creatureStats = CNWSCreatureStats.FromPointer(pStats);

                if (creatureStats == null)
                {
                    return(Hook.CallOriginal(pStats, nType, pVerses, bConsiderFeats));
                }

                OnCheckEffectImmunity eventData = ProcessEvent(new OnCheckEffectImmunity
                {
                    Creature     = creatureStats.m_pBaseCreature.ToNwObject <NwCreature>() !,
                    ImmunityType = (ImmunityType)nType,
                });
Exemplo n.º 6
0
            private static int OnSetMemorizedSpellSlot(void *pCreatureStats, byte nMultiClass, byte nSpellSlot,
                                                       uint nSpellId, byte nDomainLevel, byte nMetaType, int bFromClient)
            {
                CNWSCreatureStats creatureStats = CNWSCreatureStats.FromPointer(pCreatureStats);

                OnSpellSlotMemorize eventData = ProcessEvent(new OnSpellSlotMemorize
                {
                    Creature   = creatureStats.m_pBaseCreature.ToNwObject <NwCreature>() !,
                    ClassIndex = nMultiClass,
                    SlotIndex  = nSpellSlot,
                    Spell      = NwSpell.FromSpellId((int)nSpellId) !,
                    Domain     = (Domain)nDomainLevel,
                    MetaMagic  = (MetaMagic)nMetaType,
                    FromClient = bFromClient.ToBool(),
                });
Exemplo n.º 7
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());
        }
Exemplo n.º 8
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());
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
0
        private int OnGetUseMonkAttackTables(void *pStats, int bForceUnarmed)
        {
            CNWSCreatureStats stats    = CNWSCreatureStats.FromPointer(pStats);
            CNWSCreature      creature = stats.m_pBaseCreature;

            int monkLevels = GetLevelByClass(stats, (uint)ClassType.Monk);

            if (monkLevels < 1 || !creature.GetUseMonkAbilities().ToBool())
            {
                return(false.ToInt());
            }

            CNWSItem mainWeapon = creature.m_pInventory.GetItemInSlot((uint)EquipmentSlot.RightHand);

            if (mainWeapon == null)
            {
                return(true.ToInt());
            }

            if (bForceUnarmed.ToBool())
            {
                return(false.ToInt());
            }

            uint mainWeaponType = mainWeapon.m_nBaseItem;

            if (mainWeaponType != (uint)BaseItem.Kama && !monkWeaponSet.Contains(mainWeapon.m_nBaseItem))
            {
                return(false.ToInt());
            }

            CNWSItem secondWeapon = creature.m_pInventory.GetItemInSlot((uint)EquipmentSlot.LeftHand);

            if (secondWeapon == null)
            {
                return(true.ToInt());
            }

            uint secondWeaponType = secondWeapon.m_nBaseItem;

            return((secondWeaponType is (uint)BaseItem.Kama or(uint) BaseItem.Torch || monkWeaponSet.Contains(secondWeaponType)).ToInt());
        }
Exemplo n.º 11
0
        private bool IsWeaponLight(CNWSCreatureStats stats, CNWSItem weapon, bool finesse)
        {
            if (IsUnarmedWeapon(weapon))
            {
                return(true);
            }

            CNWSCreature creature = stats.m_pBaseCreature;

            if (creature == null)
            {
                return(false);
            }

            int creatureSize = creature.m_nCreatureSize;

            if (creatureSize is < (int)CreatureSize.Tiny or > (int)CreatureSize.Huge)
            {
                return(false);
            }

            if (finesse)
            {
                const byte defaultSize = (byte)CreatureSize.Huge + 1;
                byte       size        = weaponFinesseSizeMap.GetValueOrDefault(weapon.m_nBaseItem, defaultSize);

                if (creatureSize >= size)
                {
                    return(true);
                }
            }

            int rel = stats.m_pBaseCreature.GetRelativeWeaponSize(weapon);

            if (finesse && creatureSize < (int)CreatureSize.Small)
            {
                return(rel <= 0);
            }

            return(rel < 0);
        }
Exemplo n.º 12
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));
        }
Exemplo n.º 13
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));
        }
Exemplo n.º 14
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));
        }
Exemplo n.º 15
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);
        }
Exemplo n.º 16
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);
        }
Exemplo n.º 17
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);
        }