Esempio n. 1
0
        private static void HandleGrenadeProficiency(NWPlayer oPC, NWObject target)
        {
            NWItem weapon = _.GetSpellCastItem();

            if (weapon.BaseItemType != BaseItem.Grenade)
            {
                return;
            }

            int   perkLevel = PerkService.GetCreaturePerkLevel(oPC, PerkType.GrenadeProficiency);
            int   chance    = 10 * perkLevel;
            float duration;

            switch (perkLevel)
            {
            case 1:
            case 2:
            case 3:
            case 4:
                duration = 6;
                break;

            case 5:
            case 6:
            case 7:
            case 8:
            case 9:
                duration = 9;
                break;

            default: return;
            }


            if (RandomService.D100(1) <= chance)
            {
                _.ApplyEffectToObject(DurationType.Temporary, AbilityService.EffectKnockdown(target, duration), target, duration);
            }
        }
Esempio n. 2
0
        private static void HandleGrenadeProficiency(NWPlayer oPC, NWObject target)
        {
            NWItem weapon = _.GetSpellCastItem();

            if (weapon.BaseItemType != BASE_ITEM_GRENADE)
            {
                return;
            }

            int   perkLevel = PerkService.GetPCPerkLevel(oPC, PerkType.GrenadeProficiency);
            int   chance    = 10 * perkLevel;
            float duration;

            switch (perkLevel)
            {
            case 1:
            case 2:
            case 3:
            case 4:
                duration = 6;
                break;

            case 5:
            case 6:
            case 7:
            case 8:
            case 9:
                duration = 9;
                break;

            default: return;
            }


            if (RandomService.D100(1) <= chance)
            {
                _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectKnockdown(), target, duration);
            }
        }
Esempio n. 3
0
        public static void HandlePlasmaCellPerk(NWPlayer player, NWObject target)
        {
            if (!player.IsPlayer)
            {
                return;
            }
            if (!_.GetHasFeat(Feat.PlasmaCell, player))
            {
                return;                                          // Check if player has the perk
            }
            if (player.RightHand.CustomItemType != CustomItemType.BlasterPistol &&
                player.RightHand.CustomItemType != CustomItemType.BlasterRifle)
            {
                return;                                                                 // Check if player has the right weapons
            }
            if (GetLocalBool(target, "TRANQUILIZER_EFFECT_FIRST_RUN") == true)
            {
                return;                                                                  // Check if Tranquilizer is on to avoid conflict
            }
            if (GetLocalBool(player, "PLASMA_CELL_TOGGLE_OFF") == true)
            {
                return;                                                          // Check if Plasma Cell toggle is on or off
            }
            if (GetLocalBool(target, "TRANQUILIZER_EFFECT_FIRST_RUN") == true)
            {
                return;
            }

            int perkLevel = PerkService.GetCreaturePerkLevel(player, PerkType.PlasmaCell);
            int chance;

            CustomEffectType[] damageTypes;
            switch (perkLevel)
            {
            case 1:
                chance      = 10;
                damageTypes = new[] { CustomEffectType.FireCell };
                break;

            case 2:
                chance      = 10;
                damageTypes = new[] { CustomEffectType.FireCell, CustomEffectType.ElectricCell };
                break;

            case 3:
                chance      = 20;
                damageTypes = new[] { CustomEffectType.FireCell, CustomEffectType.ElectricCell };
                break;

            case 4:
                chance      = 20;
                damageTypes = new[] { CustomEffectType.FireCell, CustomEffectType.ElectricCell, CustomEffectType.SonicCell };
                break;

            case 5:
                chance      = 30;
                damageTypes = new[] { CustomEffectType.FireCell, CustomEffectType.ElectricCell, CustomEffectType.SonicCell };
                break;

            case 6:
                chance      = 30;
                damageTypes = new[] { CustomEffectType.FireCell, CustomEffectType.ElectricCell, CustomEffectType.SonicCell, CustomEffectType.AcidCell };
                break;

            case 7:
                chance      = 40;
                damageTypes = new[] { CustomEffectType.FireCell, CustomEffectType.ElectricCell, CustomEffectType.SonicCell, CustomEffectType.AcidCell };
                break;

            case 8:
                chance      = 40;
                damageTypes = new[] { CustomEffectType.FireCell, CustomEffectType.ElectricCell, CustomEffectType.SonicCell, CustomEffectType.AcidCell, CustomEffectType.IceCell };
                break;

            case 9:
                chance      = 50;
                damageTypes = new[] { CustomEffectType.FireCell, CustomEffectType.ElectricCell, CustomEffectType.SonicCell, CustomEffectType.AcidCell, CustomEffectType.IceCell };
                break;

            case 10:
                chance      = 50;
                damageTypes = new[] { CustomEffectType.FireCell, CustomEffectType.ElectricCell, CustomEffectType.SonicCell, CustomEffectType.AcidCell, CustomEffectType.IceCell, CustomEffectType.DivineCell };
                break;

            default: return;
            }

            foreach (var effect in damageTypes)
            {
                if (RandomService.D100(1) <= chance)
                {
                    CustomEffectService.ApplyCustomEffect(player, target.Object, effect, RandomService.D6(1), perkLevel, null);
                }
            }
        }
Esempio n. 4
0
        private static void HandleEvadeOrDeflectBlasterFire()
        {
            DamageEventData data = NWNXDamage.GetDamageEventData();

            if (data.Total <= 0)
            {
                return;
            }
            NWCreature damager = data.Damager.Object;
            NWCreature target  = NWGameObject.OBJECT_SELF;

            NWItem damagerWeapon = _.GetLastWeaponUsed(damager);
            NWItem targetWeapon  = target.RightHand;

            int perkLevel;

            // Attacker isn't using a pistol or rifle. Return.
            if (damagerWeapon.CustomItemType != CustomItemType.BlasterPistol &&
                damagerWeapon.CustomItemType != CustomItemType.BlasterRifle)
            {
                return;
            }

            int    modifier;
            string action;

            // Check target's equipped weapon, armor and perk.
            if (target.Chest.CustomItemType == CustomItemType.LightArmor &&
                (targetWeapon.CustomItemType == CustomItemType.MartialArtWeapon ||
                 !target.RightHand.IsValid && !target.LeftHand.IsValid))
            {
                // Martial Arts (weapon or unarmed) uses the Evade Blaster Fire perk which is primarily DEX based.
                perkLevel = PerkService.GetCreaturePerkLevel(target.Object, PerkType.EvadeBlasterFire);
                modifier  = target.DexterityModifier;
                action    = "evade";
            }
            else if (target.Chest.CustomItemType == CustomItemType.ForceArmor &&
                     (targetWeapon.CustomItemType == CustomItemType.Lightsaber ||
                      targetWeapon.CustomItemType == CustomItemType.Saberstaff ||
                      targetWeapon.GetLocalInt("LIGHTSABER") == TRUE))
            {
                // Lightsabers (lightsaber or saberstaff) uses the Deflect Blaster Fire perk which is primarily CHA based.
                perkLevel = PerkService.GetCreaturePerkLevel(target.Object, PerkType.DeflectBlasterFire);
                modifier  = target.CharismaModifier;
                action    = "deflect";
            }
            else
            {
                return;
            }

            // Don't have the perk. Return.
            if (perkLevel <= 0)
            {
                return;
            }

            // Check attacker's DEX against the primary stat of the perk.
            int delta = modifier - damager.DexterityModifier;

            if (delta <= 0)
            {
                return;
            }

            // Has the delay between block/evade attempts past?
            DateTime cooldown       = DateTime.UtcNow;
            string   lastAttemptVar = target.GetLocalString("EVADE_OR_DEFLECT_BLASTER_FIRE_COOLDOWN");

            if (!string.IsNullOrWhiteSpace(lastAttemptVar))
            {
                cooldown = DateTime.Parse(lastAttemptVar);
            }

            // Cooldown hasn't expired yet. Not ready to attempt a deflect.
            if (cooldown >= DateTime.UtcNow)
            {
                return;
            }

            // Ready to attempt a deflect. Adjust chance based on the delta of attacker DEX versus primary stat of defender.
            int chanceToDeflect = 5 * delta;

            if (chanceToDeflect > 80)
            {
                chanceToDeflect = 80;
            }

            int delay; // Seconds delay between deflect attempts.

            switch (perkLevel)
            {
            case 1:
                delay = 18;
                break;

            case 2:
                delay = 12;
                break;

            case 3:
                delay = 6;
                break;

            default: throw new Exception("HandleEvadeOrDeflectBlasterFire -> Perk Level " + perkLevel + " unsupported.");
            }

            cooldown = DateTime.UtcNow.AddSeconds(delay);
            target.SetLocalString("EVADE_OR_DEFLECT_BLASTER_FIRE_COOLDOWN", cooldown.ToString(CultureInfo.InvariantCulture));

            int roll = RandomService.D100(1);

            if (roll <= chanceToDeflect)
            {
                target.SendMessage(ColorTokenService.Gray("You " + action + " a blaster shot."));
                data.AdjustAllByPercent(-1);
                NWNXDamage.SetDamageEventData(data);
            }
            else
            {
                target.SendMessage(ColorTokenService.Gray("You fail to " + action + " a blaster shot. (" + roll + " vs " + chanceToDeflect + ")"));
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Calculates ability resistance for an ability.
        /// The attacker and defender's skills, ability modifiers, and balance affinity will be
        /// used to make this determination.
        /// </summary>
        /// <param name="attacker">The creature using the ability.</param>
        /// <param name="defender">The creature being targeted by the ability.</param>
        /// <param name="skill">The skill used for this ability.</param>
        /// <param name="balanceType">The force balance type to use for this ability.</param>
        /// <param name="sendRollMessage">If true, the roll message will be sent. Otherwise it won't be.</param>
        /// <returns>Data regarding the ability resistance roll</returns>
        public static AbilityResistanceResult CalculateAbilityResistance(NWCreature attacker, NWCreature defender, SkillType skill, ForceBalanceType balanceType, bool sendRollMessage = true)
        {
            int abilityScoreType;

            switch (skill)
            {
            case SkillType.ForceAlter:
                abilityScoreType = ABILITY_INTELLIGENCE;
                break;

            case SkillType.ForceControl:
                abilityScoreType = ABILITY_WISDOM;
                break;

            case SkillType.ForceSense:
                abilityScoreType = ABILITY_CHARISMA;
                break;

            default:
                throw new ArgumentException("Invalid skill type called for " + nameof(CalculateAbilityResistance) + ", value '" + skill + "' not supported.");
            }


            AbilityResistanceResult result = new AbilityResistanceResult();

            int attackerSkill   = SkillService.GetPCSkillRank(attacker.Object, skill);
            int attackerAbility = _.GetAbilityModifier(abilityScoreType, attacker);

            int defenderSkill   = SkillService.GetPCSkillRank(defender.Object, skill);
            int defenderAbility = _.GetAbilityModifier(abilityScoreType, defender);

            // If the defender is equipped with a lightsaber, we check their lightsaber skill
            if (defender.RightHand.CustomItemType == CustomItemType.Lightsaber ||
                defender.LeftHand.CustomItemType == CustomItemType.Lightsaber)
            {
                int lightsaberSkill = SkillService.GetPCSkillRank(defender.Object, SkillType.Lightsaber);
                if (lightsaberSkill > defenderSkill)
                {
                    defenderSkill = lightsaberSkill;
                }
            }

            // If the defender's martial arts skill is greater than the current skill they're using, we'll use that instead.
            int defenderMASkill = SkillService.GetPCSkillRank(defender.Object, SkillType.MartialArts);

            if (defenderMASkill > defenderSkill)
            {
                defenderSkill = defenderMASkill;
            }

            int attackerAffinity = 0;
            int defenderAffinity = 0;

            // Only check affinity if ability has a force balance type.
            if (balanceType == ForceBalanceType.Dark || balanceType == ForceBalanceType.Light)
            {
                attackerAffinity = GetBalanceAffinity(attacker.Object, balanceType);
                defenderAffinity = GetBalanceAffinity(defender.Object, balanceType);
            }

            float attackerCR = attacker.IsPlayer ? 0f : attacker.ChallengeRating * 5f;
            float defenderCR = defender.IsPlayer ? 0f : defender.ChallengeRating * 5f;

            float attackerTotal = attackerSkill + attackerAbility + attackerAffinity + attackerCR;
            float defenderTotal = defenderSkill + defenderAbility + defenderAffinity + defenderCR;
            float divisor       = attackerTotal + defenderTotal + 1; // +1 to prevent division by zero.

            //Console.WriteLine("attackerCR = " + attackerCR);
            //Console.WriteLine("defenderCR = " + defenderCR);
            //Console.WriteLine("attackerSkill = " + attackerSkill);
            //Console.WriteLine("attackerAbility = " + attackerAbility);
            //Console.WriteLine("attackerAffinity = " + attackerAffinity);
            //Console.WriteLine("defenderSkill = " + defenderSkill);
            //Console.WriteLine("defenderAbility = " + defenderAbility);
            //Console.WriteLine("defenderAffinity = " + defenderAffinity);
            //Console.WriteLine("attackerTotal = " + attackerTotal);
            //Console.WriteLine("defenderTotal = " + defenderTotal);
            //Console.WriteLine("divisor = " + divisor);

            result.DC   = (int)(attackerTotal / divisor * 100);
            result.Roll = RandomService.D100(1);

            if (sendRollMessage)
            {
                string resisted = result.IsResisted ? ColorTokenService.Red(" [RESISTED " + Math.Abs(result.Delta) + "%]") : string.Empty;
                string message  = ColorTokenService.SavingThrow("Roll: " + result.Roll + " VS " + result.DC + " DC") + resisted;
                attacker.SendMessage(message);
                defender.SendMessage(message);
            }

            return(result);
        }
Esempio n. 6
0
        public static ForceResistanceResult CalculateResistanceRating(
            NWCreature caster,
            NWCreature target,
            ForceAbilityType forceAbility)
        {
            int accuracy = CalculateForceAccuracy(caster, target, forceAbility);
            ForceResistanceResult result = new ForceResistanceResult();

            // Do four checks to see if the attacker overcomes the defender's
            // resistance.  The more checks you succeed, the lower the resistance.
            int successes = 0;

            if (RandomService.D100(1) <= accuracy)
            {
                successes++;

                if (RandomService.D100(1) <= accuracy)
                {
                    successes++;

                    if (RandomService.D100(1) <= accuracy)
                    {
                        successes++;

                        if (RandomService.D100(1) <= accuracy)
                        {
                            successes++;
                        }
                    }
                }
            }

            switch (successes)
            {
            case 0:
                result.Amount = 0f;
                result.Type   = ResistanceType.Full;
                break;

            case 1:
                result.Amount = 0.125f;
                result.Type   = ResistanceType.Eighth;
                break;

            case 2:
                result.Amount = 0.25f;
                result.Type   = ResistanceType.Fourth;
                break;

            case 3:
                result.Amount = 0.5f;
                result.Type   = ResistanceType.Half;
                break;

            case 4:
                result.Amount = 1.0f;
                result.Type   = ResistanceType.Zero;
                break;
            }

            return(result);
        }