Example #1
0
        public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args)
        {
            // Did the player pass in the 'end' argument? If so, we're ending the concentration effect.
            bool doEnd = args.Length > 0 && args[0] == "end";

            if (doEnd)
            {
                AbilityService.EndConcentrationEffect(user);
                user.SendMessage("You have ended your concentration ability.");
            }
            // Otherwise just notify them about what effect is currently active.
            else
            {
                var effect = AbilityService.GetActiveConcentrationEffect(user);
                if (effect.Type == PerkType.Unknown)
                {
                    user.SendMessage("No concentration ability is currently active.");
                }
                else
                {
                    var perk = PerkService.GetPerkByID((int)effect.Type);
                    user.SendMessage("Currently active concentration ability: " + perk.Name);
                }
            }
        }
Example #2
0
        private static void ProcessPerkFeats(NWCreature self)
        {
            // Bail early if any of the following is true:
            //      - Creature has a weapon skill queued.
            //      - Creature does not have a PerkFeat cache.
            //      - There are no perk feats in the cache.
            //      - Creature has no target.

            if (self.GetLocalInt("ACTIVE_WEAPON_SKILL") > 0)
            {
                return;
            }
            if (!self.Data.ContainsKey("PERK_FEATS"))
            {
                return;
            }

            Dictionary <int, AIPerkDetails> cache = self.Data["PERK_FEATS"];

            if (cache.Count <= 0)
            {
                return;
            }

            NWObject target = _.GetAttackTarget(self);

            if (!target.IsValid)
            {
                return;
            }

            // Pull back whatever concentration effect is currently active, if any.
            var concentration = AbilityService.GetActiveConcentrationEffect(self);

            // Exclude any concentration effects, if necessary, then randomize potential feats to use.
            var randomizedFeatIDs = concentration.Type == PerkType.Unknown
                ? cache.Values                                                                        // No concentration exclusions
                : cache.Values.Where(x => x.ExecutionType != PerkExecutionType.ConcentrationAbility); // Exclude concentration abilities

            randomizedFeatIDs = randomizedFeatIDs.OrderBy(o => RandomService.Random());

            foreach (var perkDetails in randomizedFeatIDs)
            {
                // Move to next feat if this creature cannot use this one.
                if (!AbilityService.CanUsePerkFeat(self, target, perkDetails.FeatID))
                {
                    continue;
                }

                self.AssignCommand(() =>
                {
                    _.ActionUseFeat(perkDetails.FeatID, target);
                });

                break;
            }
        }
Example #3
0
        public string CanCastSpell(NWCreature oPC, NWObject oTarget, int spellTier)
        {
            NWCreature targetCreature      = oTarget.Object;
            var        concentrationEffect = AbilityService.GetActiveConcentrationEffect(targetCreature);

            switch (spellTier)
            {
            case 1:
                if (!oTarget.IsCreature)
                {
                    return("This ability can only be used on living creatures.");
                }
                if (targetCreature.RacialType == (int)CustomRaceType.Robot)
                {
                    return("This ability cannot be used on droids.");
                }
                if (concentrationEffect.Type == PerkType.MindShield)
                {
                    return("Your target is immune to tranquilization effects.");
                }
                break;

            case 2:
                if (!oTarget.IsCreature)
                {
                    return("This ability can only be used on living creatures.");
                }
                if (targetCreature.RacialType == (int)CustomRaceType.Robot)
                {
                    return("This ability cannot be used on droids.");
                }
                if (concentrationEffect.Type == PerkType.MindShield)
                {
                    return("Your target is immune to tranquilization effects.");
                }
                break;

            case 3:
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(spellTier));
            }

            return(string.Empty);
        }
Example #4
0
        private void RunEffect(NWCreature creature, NWObject target)
        {
            var concentrationEffect = AbilityService.GetActiveConcentrationEffect(target.Object);

            if (concentrationEffect.Type == PerkType.MindShield)
            {
                creature.SendMessage("Your target is immune to tranquilization effects.");
                return;
            }

            AbilityResistanceResult result = CombatService.CalculateAbilityResistance(creature, target.Object, SkillType.ForceAlter, ForceBalanceType.Dark);

            // Tranquilization effect - Daze target(s). Occurs on succeeding the DC check.
            Effect successEffect = EffectDazed();

            successEffect = EffectLinkEffects(successEffect, EffectVisualEffect(VisualEffect.Vfx_Dur_Iounstone_Blue));
            successEffect = TagEffect(successEffect, "TRANQUILIZER_EFFECT");

            // AC & AB decrease effect - Occurs on failing the DC check.
            Effect failureEffect = EffectLinkEffects(EffectAttackDecrease(5), EffectACDecrease(5));



            if (!result.IsResisted)
            {
                creature.AssignCommand(() =>
                {
                    ApplyEffectToObject(DurationType.Temporary, successEffect, target, 6.1f);
                });
            }
            else
            {
                creature.AssignCommand(() =>
                {
                    ApplyEffectToObject(DurationType.Temporary, failureEffect, target, 6.1f);
                });
            }

            if (creature.IsPlayer)
            {
                SkillService.RegisterPCToNPCForSkill(creature.Object, target, SkillType.ForceAlter);
            }

            EnmityService.AdjustEnmity(target.Object, creature, 1);
        }
        public void OnImpact(NWCreature creature, NWObject target, int perkLevel, int spellTier)
        {
            int chance = perkLevel * 25;

            // Failed to interrupt.
            if (RandomService.D100(1) > chance)
            {
                creature.SendMessage("You fail to interrupt your target's concentration.");
                return;
            }

            NWCreature targetCreature = target.Object;
            var        effect         = AbilityService.GetActiveConcentrationEffect(targetCreature);

            if (effect.Type != PerkType.Unknown)
            {
                targetCreature.SendMessage("Your concentration effect has been interrupted by " + creature.Name + ".");
                AbilityService.EndConcentrationEffect(target.Object);
            }
        }
Example #6
0
        public void OnImpact(NWCreature creature, NWObject target, int perkLevel, int spellTier)
        {
            int   massLevel  = PerkService.GetCreaturePerkLevel(creature, PerkType.MassTranquilizer);
            int   tranqLevel = PerkService.GetCreaturePerkLevel(creature, PerkType.Tranquilizer);
            int   luck       = PerkService.GetCreaturePerkLevel(creature, PerkType.Lucky);
            float duration;
            float range = 5 * massLevel;

            switch (tranqLevel)
            {
            case 0:
                duration = 6;
                break;

            case 1:
                duration = 12;
                break;

            case 2:
                duration = 24;
                break;

            case 3:
                duration = 36;
                break;

            case 4:
                duration = 48;
                break;

            case 5:
                duration = 60;
                break;

            case 6:
                duration = 72;
                break;

            case 7:
                duration = 84;
                break;

            case 8:
                duration = 96;
                break;

            case 9:
                duration = 108;
                break;

            case 10:
                duration = 120;
                break;

            default: return;
            }

            if (RandomService.D100(1) <= luck)
            {
                duration *= 2;
                creature.SendMessage("Lucky shot!");
            }


            // Check if Mind Shield is on target.
            var concentrationEffect = AbilityService.GetActiveConcentrationEffect(target.Object);

            if (concentrationEffect.Type == PerkType.MindShield)
            {
                creature.SendMessage("Your target is immune to tranquilization effects.");
            }
            else
            {
                // Apply to the target.
                if (!RemoveExistingEffect(target, duration))
                {
                    target.SetLocalInt("TRANQUILIZER_EFFECT_FIRST_RUN", 1);

                    Effect effect = _.EffectDazed();
                    effect = _.EffectLinkEffects(effect, _.EffectVisualEffect(VFX_DUR_IOUNSTONE_BLUE));
                    effect = _.TagEffect(effect, "TRANQUILIZER_EFFECT");

                    _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, effect, target, duration);
                }
            }



            // Iterate over all nearby hostiles. Apply the effect to them if they meet the criteria.
            int        current = 1;
            NWCreature nearest = _.GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, target, current);

            while (nearest.IsValid)
            {
                float distance = _.GetDistanceBetween(nearest, target);
                // Check distance. Exit loop if we're too far.
                if (distance > range)
                {
                    break;
                }

                concentrationEffect = AbilityService.GetActiveConcentrationEffect(nearest);

                // If this creature isn't hostile to the attacking player or if this creature is already tranquilized, move to the next one.
                if (_.GetIsReactionTypeHostile(nearest, creature) == FALSE ||
                    nearest.Object == target.Object ||
                    RemoveExistingEffect(nearest, duration) ||
                    concentrationEffect.Type == PerkType.MindShield)
                {
                    current++;
                    nearest = _.GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, target, current);
                    continue;
                }

                target.SetLocalInt("TRANQUILIZER_EFFECT_FIRST_RUN", 1);
                Effect effect = _.EffectDazed();
                effect = _.EffectLinkEffects(effect, _.EffectVisualEffect(VFX_DUR_IOUNSTONE_BLUE));
                effect = _.TagEffect(effect, "TRANQUILIZER_EFFECT");
                _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, effect, nearest, duration);

                current++;
                nearest = _.GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, target, current);
            }
        }
Example #7
0
        public void OnImpact(NWCreature creature, NWObject target, int perkLevel, int spellTier)
        {
            var concentrationEffect = AbilityService.GetActiveConcentrationEffect(target.Object);

            if (concentrationEffect.Type == PerkType.MindShield)
            {
                creature.SendMessage("Your target is immune to tranquilization effects.");
                return;
            }

            int   luck = PerkService.GetCreaturePerkLevel(creature, PerkType.Lucky);
            float duration;

            switch (perkLevel)
            {
            case 1:
                duration = 12;
                break;

            case 2:
                duration = 24;
                break;

            case 3:
                duration = 36;
                break;

            case 4:
                duration = 48;
                break;

            case 5:
                duration = 60;
                break;

            case 6:
                duration = 72;
                break;

            case 7:
                duration = 84;
                break;

            case 8:
                duration = 96;
                break;

            case 9:
                duration = 108;
                break;

            case 10:
                duration = 120;
                break;

            default: return;
            }

            if (RandomService.D100(1) <= luck)
            {
                duration *= 2;
                creature.SendMessage("Lucky shot!");
            }

            if (RemoveExistingEffect(target, duration))
            {
                creature.SendMessage("A more powerful effect already exists on your target.");
                return;
            }

            target.SetLocalInt("TRANQUILIZER_EFFECT_FIRST_RUN", 1);

            Effect effect = _.EffectDazed();

            effect = _.EffectLinkEffects(effect, _.EffectVisualEffect(VFX_DUR_IOUNSTONE_BLUE));
            effect = _.TagEffect(effect, "TRANQUILIZER_EFFECT");

            _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, effect, target, duration);
        }
Example #8
0
        private static void ProcessPerkFeats(NWCreature self)
        {
            // Bail early if any of the following is true:
            //      - Creature has a weapon skill queued.
            //      - Creature does not have a PerkFeat cache.
            //      - There are no perk feats in the cache.
            //      - Creature has no target.

            if (self.GetLocalInt("ACTIVE_WEAPON_SKILL") > 0)
            {
                return;
            }
            if (!self.Data.ContainsKey("PERK_FEATS"))
            {
                return;
            }

            Dictionary <int, AIPerkDetails> cache = self.Data["PERK_FEATS"];

            if (cache.Count <= 0)
            {
                return;
            }

            NWObject target = _.GetAttackTarget(self);

            if (!target.IsValid)
            {
                return;
            }


            // todo: GetEffectType() returns EFFECT_TYPE_INVALIDEFFECT for knockdown effects.
            // todo: The following code is causing a segfault crash... look into other solutions or figure out what's causing that.
            // target.Effects.Any(x => NWNXEffect.UnpackEffect(x).Type == (int)EffectTypeEngine.Knockdown) ||
            // Potential workaround: if (target.GetLocalBool("KNOCKDOWN")) return;
            if (target.GetLocalBool("KNOCKDOWN"))
            {
                return;
            }
            if (target.Effects.Any(x => _.GetEffectTag(x) == "TRANQUILIZER_EFFECT"))
            {
                return;
            }

            // Pull back whatever concentration effect is currently active, if any.
            var concentration = AbilityService.GetActiveConcentrationEffect(self);

            // Exclude any concentration effects, if necessary, then randomize potential feats to use.
            var randomizedFeatIDs = concentration.Type == PerkType.Unknown
                ? cache.Values                                                                        // No concentration exclusions
                : cache.Values.Where(x => x.ExecutionType != PerkExecutionType.ConcentrationAbility); // Exclude concentration abilities

            randomizedFeatIDs = randomizedFeatIDs.OrderBy(o => RandomService.Random());

            foreach (var perkDetails in randomizedFeatIDs)
            {
                // Move to next feat if this creature cannot use this one.
                if (!AbilityService.CanUsePerkFeat(self, target, (Feat)perkDetails.FeatID))
                {
                    continue;
                }

                self.AssignCommand(() =>
                {
                    _.ActionUseFeat((Feat)perkDetails.FeatID, target);
                });

                break;
            }
        }