예제 #1
0
        private void DoPerkRemoval()
        {
            if (!CanRefundPerk())
            {
                return;
            }

            var model        = GetDialogCustomData <Model>();
            var player       = GetPC();
            var pcPerk       = DataService.Single <PCPerk>(x => x.ID == model.PCPerkID);
            var perk         = DataService.Get <Data.Entity.Perk>(pcPerk.PerkID);
            var minimumLevel = 1;

            if (IsGrantedByBackground((PerkType)perk.ID))
            {
                minimumLevel = 2;
            }

            var refundAmount = DataService.Where <PerkLevel>(x => x.PerkID == perk.ID && x.Level <= pcPerk.PerkLevel && x.Level >= minimumLevel).Sum(x => x.Price);
            var dbPlayer     = DataService.Single <Player>(x => x.ID == player.GlobalID);

            dbPlayer.DatePerkRefundAvailable = DateTime.UtcNow.AddHours(24);
            RemovePerkItem(perk);
            RemovePerkFeat(perk);
            CustomEffectService.RemoveStance(GetPC());
            PlayerStatService.ApplyStatChanges(GetPC(), null);

            dbPlayer.UnallocatedSP += refundAmount;

            var refundAudit = new PCPerkRefund
            {
                PlayerID     = player.GlobalID,
                DateAcquired = pcPerk.AcquiredDate,
                DateRefunded = DateTime.UtcNow,
                Level        = pcPerk.PerkLevel,
                PerkID       = pcPerk.PerkID
            };

            // Bypass caching for perk refunds.
            DataService.DataQueue.Enqueue(new DatabaseAction(refundAudit, DatabaseActionType.Insert));
            DataService.SubmitDataChange(pcPerk, DatabaseActionType.Delete);
            DataService.SubmitDataChange(dbPlayer, DatabaseActionType.Update);

            // If perk refunded was one granted by a background bonus, we need to reapply it.
            ReapplyBackgroundBonus((PerkType)pcPerk.PerkID);

            GetPC().FloatingText("Perk refunded! You reclaimed " + refundAmount + " SP.");
            model.TomeItem.Destroy();

            var handler = PerkService.GetPerkHandler(perk.ID);

            handler.OnRemoved(player);
            MessageHub.Instance.Publish(new OnPerkRefunded(player, pcPerk.PerkID));
        }
예제 #2
0
        public void OnImpact(NWPlayer player, NWObject target, int perkLevel, int spellFeatID)
        {
            int duration = 60;

            var vfx = _.EffectVisualEffect(VFX_DUR_BLUR);

            vfx = _.TagEffect(vfx, "SHIELD_BOOST_VFX");

            _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, vfx, target, duration);
            CustomEffectService.ApplyCustomEffect(player, target.Object, CustomEffectType.ShieldBoost, duration, perkLevel, null);
        }
        public void Main()
        {
            NWCreature oTarget = _.GetSpellTargetObject();

            if (RandomService.D100(1) > 5)
            {
                return;
            }

            CustomEffectService.ApplyCustomEffect(NWGameObject.OBJECT_SELF, oTarget, CustomEffectType.Bleeding, 12, 1, null);
        }
예제 #4
0
        public string Apply(NWCreature oCaster, NWObject oTarget, int effectiveLevel)
        {
            PlayerStatService.ApplyStatChanges(oTarget.Object, null);
            int healAmount = (int)(CustomEffectService.CalculateEffectHPBonusPercent(oTarget.Object) * oTarget.MaxHP);

            if (healAmount > 0)
            {
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectHeal(healAmount), oTarget);
            }

            return(null);
        }
예제 #5
0
        public bool Run(params object[] args)
        {
            NWCreature oTarget = _.GetSpellTargetObject();

            if (RandomService.D100(1) > 5)
            {
                return(false);
            }

            CustomEffectService.ApplyCustomEffect(Object.OBJECT_SELF, oTarget, CustomEffectType.Bleeding, 12, 1, null);
            return(true);
        }
예제 #6
0
        public void OnImpact(NWPlayer player, NWObject target, int perkLevel, int spellFeatID)
        {
            NWCreature targetCreature = target.Object;

            int   duration;
            int   uses;
            float range;

            switch (perkLevel)
            {
            case 1:
                duration = 30;
                uses     = 1;
                range    = 10f;
                break;

            case 2:
                duration = 30;
                uses     = 2;
                range    = 10f;
                break;

            case 3:
                duration = 60;
                uses     = 2;
                range    = 20f;
                break;

            case 4:
                duration = 60;
                uses     = 3;
                range    = 20f;
                break;

            case 5:
                duration = 60;
                uses     = 4;
                range    = 20f;
                break;

            case 6:
                duration = 60;
                uses     = 5;
                range    = 20f;
                break;

            default: return;
            }

            _.PlaySound("v_useforce");
            CustomEffectService.ApplyCustomEffect(player, targetCreature, CustomEffectType.ForceSpread, duration, perkLevel, uses + "," + range);
            SkillService.RegisterPCToAllCombatTargetsForSkill(player, SkillType.ForceUtility, null);
        }
예제 #7
0
        public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData)
        {
            NWPlayer player               = (user.Object);
            var      effectiveStats       = PlayerStatService.GetPlayerItemEffectiveStats(player);
            int      rank                 = SkillService.GetPCSkillRank(player, SkillType.Medicine);
            int      luck                 = PerkService.GetCreaturePerkLevel(player, PerkType.Lucky);
            int      perkDurationBonus    = PerkService.GetCreaturePerkLevel(player, PerkType.HealingKitExpert) * 6 + (luck * 2);
            float    duration             = 30.0f + (rank * 0.4f) + perkDurationBonus + effectiveStats.Medicine;
            int      restoreAmount        = 1 + item.GetLocalInt("HEALING_BONUS") + (rank / 10);
            int      delta                = item.RecommendedLevel - rank;
            float    effectivenessPercent = 1.0f;

            if (delta > 0)
            {
                effectivenessPercent = effectivenessPercent - (delta * 0.1f);
            }

            restoreAmount = (int)(restoreAmount * effectivenessPercent) + item.MedicineBonus;

            int perkBlastBonus = PerkService.GetCreaturePerkLevel(player, PerkType.ImmediateForcePack);

            if (perkBlastBonus > 0)
            {
                int blastHeal = restoreAmount * perkBlastBonus;
                if (RandomService.Random(100) + 1 <= luck / 2)
                {
                    blastHeal *= 2;
                }

                AbilityService.RestorePlayerFP(target.Object, blastHeal);
            }

            float          interval   = 6.0f;
            BackgroundType background = (BackgroundType)player.Class1;

            if (background == BackgroundType.Medic)
            {
                interval *= 0.5f;
            }

            string data = (int)interval + ", " + restoreAmount;

            CustomEffectService.ApplyCustomEffect(user, target.Object, CustomEffectType.ForcePack, (int)duration, restoreAmount, data);

            player.SendMessage("You successfully apply a force pack to " + target.Name + ". The force pack will expire in " + duration + " seconds.");

            _.DelayCommand(duration + 0.5f, () => { player.SendMessage("The force pack that you applied to " + target.Name + " has expired."); });

            int xp = (int)SkillService.CalculateRegisteredSkillLevelAdjustedXP(300, item.RecommendedLevel, rank);

            SkillService.GiveSkillXP(player, SkillType.Medicine, xp);
        }
예제 #8
0
        public void OnImpact(NWPlayer player, NWObject target, int level, int spellFeatID)
        {
            int ticks;
            var spread = CustomEffectService.GetForceSpreadDetails(player);

            switch (level)
            {
            default:
                ticks = 300;
                break;

            case 5:
            case 6:
                ticks = 600;
                break;
            }

            int itemPotency  = CombatService.CalculateItemPotencyBonus(player.Object, ForceAbilityType.Light);
            int basePotency  = (int)(player.Wisdom + player.Intelligence * 0.5f + player.Charisma * 0.25f);
            int finalPotency = itemPotency + basePotency;

            ticks += finalPotency * 10; // +10 seconds per potency


            // Force Spread isn't active. This is a single target cast.
            if (spread.Level <= 0)
            {
                CustomEffectService.ApplyCustomEffect(player, target.Object, CustomEffectType.ForceAura, ticks, level, null);
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_IMP_AC_BONUS), target);
            }
            // Force Spread is active. Target nearby party members.
            else
            {
                spread.Uses--;
                var members = player.PartyMembers.Where(x => _.GetDistanceBetween(x, target) <= spread.Range ||
                                                        Equals(x, target));

                foreach (var member in members)
                {
                    CustomEffectService.ApplyCustomEffect(member, target.Object, CustomEffectType.ForceAura, ticks, level, null);
                    _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_IMP_AC_BONUS), member);
                }

                _.PlaySound("v_pro_frcaura");
                CustomEffectService.SetForceSpreadUses(player, spread.Uses);
                SkillService.RegisterPCToAllCombatTargetsForSkill(player, SkillType.ForceUtility, null);
            }

            SkillService.RegisterPCToAllCombatTargetsForSkill(player, SkillType.ForceSupport, null);
        }
예제 #9
0
        public void Tick(NWCreature oCaster, NWObject oTarget, int currentTick, int effectiveLevel, string data)
        {
            AbilityService.EndConcentrationEffect(oCaster);

            NWPlayer player   = oTarget.Object;
            int      restTick = oTarget.GetLocalInt("REST_TICK") + 1;


            // Pull original position from data
            string[] values           = data.Split(',');
            Vector3  originalPosition = _.Vector3
                                        (
                Convert.ToSingle(values[0]),
                Convert.ToSingle(values[1]),
                Convert.ToSingle(values[2])
                                        );

            // Check position
            Vector3 position = player.Position;

            if ((Math.Abs(position.X - originalPosition.X) > 0.01f ||
                 Math.Abs(position.Y - originalPosition.Y) > 0.01f ||
                 Math.Abs(position.Z - originalPosition.Z) > 0.01f) ||
                !CanRest(player) ||
                !player.IsValid)
            {
                player.IsBusy = false;
                CustomEffectService.RemovePCCustomEffect(player, CustomEffectType.Rest);
                return;
            }

            player.IsBusy = true;

            player.AssignCommand(() =>
            {
                _.ActionPlayAnimation(Animation.LoopingSitCross, 1.0f, 6.1f);
            });

            if (restTick >= 6)
            {
                int amount = CalculateAmount(player);

                _.ApplyEffectToObject(DurationType.Instant, _.EffectHeal(amount), player);
                Effect vfx = _.EffectVisualEffect(VisualEffect.Vfx_Imp_Head_Holy);
                _.ApplyEffectToObject(DurationType.Instant, vfx, player);
                restTick = 0;
            }

            oTarget.SetLocalInt("REST_TICK", restTick);
        }
예제 #10
0
        public void Tick(NWCreature oCaster, NWObject oTarget, int currentTick, int effectiveLevel, string data)
        {
            AbilityService.EndConcentrationEffect(oCaster);

            NWPlayer player   = oTarget.Object;
            int      restTick = oTarget.GetLocalInt("REST_TICK") + 1;


            // Pull original position from data
            string[] values           = data.Split(',');
            Vector   originalPosition = _.Vector
                                        (
                Convert.ToSingle(values[0]),
                Convert.ToSingle(values[1]),
                Convert.ToSingle(values[2])
                                        );

            // Check position
            Vector position = player.Position;

            if ((Math.Abs(position.m_X - originalPosition.m_X) > 0.01f ||
                 Math.Abs(position.m_Y - originalPosition.m_Y) > 0.01f ||
                 Math.Abs(position.m_Z - originalPosition.m_Z) > 0.01f) ||
                !CanRest(player) ||
                !player.IsValid)
            {
                player.IsBusy = false;
                CustomEffectService.RemovePCCustomEffect(player, CustomEffectType.Rest);
                return;
            }

            player.IsBusy = true;

            player.AssignCommand(() =>
            {
                _.ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0f, 6.1f);
            });

            if (restTick >= 6)
            {
                int amount = CalculateAmount(player);

                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectHeal(amount), player);
                Effect vfx = _.EffectVisualEffect(VFX_IMP_HEAD_HOLY);
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, vfx, player);
                restTick = 0;
            }

            oTarget.SetLocalInt("REST_TICK", restTick);
        }
예제 #11
0
        public void Tick(NWCreature oCaster, NWObject oTarget, int currentTick, int effectiveLevel, string data)
        {
            NWPlayer targetPlayer = oTarget.Object;

            if (targetPlayer.Chest.CustomItemType != CustomItemType.HeavyArmor)
            {
                CustomEffectService.RemovePCCustomEffect(targetPlayer, CustomEffectType.ShieldBoost);
                PlayerStatService.ApplyStatChanges(targetPlayer, null);

                var vfx = targetPlayer.Effects.SingleOrDefault(x => _.GetEffectTag(x) == "SHIELD_BOOST_VFX");

                if (vfx != null)
                {
                    _.RemoveEffect(targetPlayer, vfx);
                }
            }
        }
예제 #12
0
        public string IsValidTarget(NWCreature user, NWItem item, NWObject target, Location targetLocation)
        {
            if (!target.IsCreature || target.IsDM)
            {
                return("Only creatures may be targeted with this item.");
            }

            bool hasEffect = false;

            foreach (Effect effect in target.Effects)
            {
                if (_.GetIsEffectValid(effect) == true)
                {
                    var effectType = _.GetEffectType(effect);
                    if (effectType == EffectTypeScript.Poison || effectType == EffectTypeScript.Disease || effectType == EffectTypeScript.AbilityDecrease)
                    {
                        hasEffect = true;
                    }
                }
            }

            if (CustomEffectService.DoesPCHaveCustomEffect(target.Object, CustomEffectType.Poison))
            {
                hasEffect = true;
            }

            if (!hasEffect)
            {
                return("This player is not diseased or poisoned.");
            }

            int rank = SkillService.GetPCSkillRank(user.Object, SkillType.Medicine);

            if (rank < item.RecommendedLevel)
            {
                return("Your skill level is too low to use this item.");
            }

            return(null);
        }
예제 #13
0
        public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData)
        {
            NWPlayer player         = (user.Object);
            var      effectiveStats = PlayerStatService.GetPlayerItemEffectiveStats(player);

            CustomEffectService.RemovePCCustomEffect(target.Object, CustomEffectType.Bleeding);
            player.SendMessage("You finish bandaging " + target.Name + "'s wounds.");

            int rank = SkillService.GetPCSkillRank(player, SkillType.Medicine);

            int healAmount = 2 + effectiveStats.Medicine / 2;

            healAmount += item.MedicineBonus;
            if (rank >= item.RecommendedLevel && item.MedicineBonus > 0)
            {
                _.ApplyEffectToObject(DurationType.Instant, _.EffectHeal(healAmount), target);
            }
            if (target.IsPlayer)
            {
                int xp = (int)SkillService.CalculateRegisteredSkillLevelAdjustedXP(100, item.RecommendedLevel, rank);
                SkillService.GiveSkillXP(player, SkillType.Medicine, xp);
            }
        }
예제 #14
0
        public void OnImpact(NWPlayer player, NWObject target, int perkLevel, int spellFeatID)
        {
            int duration;

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

            case 2:
                duration = 48;
                break;

            case 3:
                duration = 72;
                break;

            default: throw new ArgumentOutOfRangeException();
            }

            CustomEffectService.ApplyCustomEffect(player, player, CustomEffectType.Chainspell, duration, perkLevel, null);
            SkillService.RegisterPCToAllCombatTargetsForSkill(player, SkillType.ForceUtility, null);
        }
예제 #15
0
        public void OnImpact(NWCreature creature, NWObject target, int perkLevel, int spellTier)
        {
            CustomEffectService.ApplyCustomEffect(creature, creature, CustomEffectType.AbsorptionField, 20, perkLevel, null);

            _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_IMP_GLOBE_USE), target);
        }
예제 #16
0
 public void OnImpact(NWPlayer player, NWObject target, int perkLevel, int spellFeatID)
 {
     CustomEffectService.ApplyCustomEffect(player, player, CustomEffectType.Rest, -1, 0, null);
 }
예제 #17
0
        public void OnImpact(NWPlayer player, NWObject target, int level, int spellFeatID)
        {
            int damage;
            int seconds;
            int dotDamage;

            switch (level)
            {
            case 1:
                damage    = RandomService.D4(1);
                seconds   = 6;
                dotDamage = 1;
                break;

            case 2:
                damage    = RandomService.D8(1);
                seconds   = 6;
                dotDamage = 1;
                break;

            case 3:
                damage    = RandomService.D8(2);
                seconds   = 6;
                dotDamage = 1;
                break;

            case 4:
                damage    = RandomService.D8(2);
                seconds   = 12;
                dotDamage = 2;
                break;

            case 5:
                damage    = RandomService.D8(3);
                seconds   = 12;
                dotDamage = 2;
                break;

            case 6:
                damage    = RandomService.D8(4);
                seconds   = 12;
                dotDamage = 2;
                break;

            case 7:
                damage    = RandomService.D8(5);
                seconds   = 12;
                dotDamage = 3;
                break;

            case 8:
                damage    = RandomService.D8(5);
                seconds   = 18;
                dotDamage = 3;
                break;

            case 9:
                damage    = RandomService.D8(6);
                seconds   = 24;
                dotDamage = 3;
                break;

            default: return;
            }

            _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectDamage(damage, DAMAGE_TYPE_PIERCING), target);
            CustomEffectService.ApplyCustomEffect(player, target.Object, CustomEffectType.Bleeding, seconds, level, Convert.ToString(dotDamage));
        }
 public void OnImpact(NWCreature creature, NWObject target, int perkLevel, int spellTier)
 {
     CustomEffectService.ApplyCustomEffect(creature, creature, CustomEffectType.Rest, -1, 0, null);
 }
예제 #19
0
        public void OnImpact(NWCreature creature, NWObject target, int level, int spellTier)
        {
            int damage;
            int seconds;
            int dotDamage;

            switch (level)
            {
            case 1:
                damage    = RandomService.D4(1);
                seconds   = 6;
                dotDamage = 1 + (creature.RightHand.DamageBonus / 5);
                break;

            case 2:
                damage    = RandomService.D8(1);
                seconds   = 6;
                dotDamage = 1 + (creature.RightHand.DamageBonus / 5);
                break;

            case 3:
                damage    = RandomService.D8(2);
                seconds   = 6;
                dotDamage = 1 + (creature.RightHand.DamageBonus / 5);
                break;

            case 4:
                damage    = RandomService.D8(2);
                seconds   = 12;
                dotDamage = 2 + (creature.RightHand.DamageBonus / 4);
                break;

            case 5:
                damage    = RandomService.D8(3);
                seconds   = 12;
                dotDamage = 2 + (creature.RightHand.DamageBonus / 4);
                break;

            case 6:
                damage    = RandomService.D8(4);
                seconds   = 12;
                dotDamage = 2 + (creature.RightHand.DamageBonus / 4);
                break;

            case 7:
                damage    = RandomService.D8(5);
                seconds   = 12;
                dotDamage = 3 + (creature.RightHand.DamageBonus / 3);
                break;

            case 8:
                damage    = RandomService.D8(5);
                seconds   = 18;
                dotDamage = 3 + (creature.RightHand.DamageBonus / 3);
                break;

            case 9:
                damage    = RandomService.D8(6);
                seconds   = 24;
                dotDamage = 3 + (creature.RightHand.DamageBonus / 3);
                break;

            default: return;
            }

            _.ApplyEffectToObject(DurationType.Instant, _.EffectDamage(damage, DamageType.Piercing), target);
            CustomEffectService.ApplyCustomEffect(creature, target.Object, CustomEffectType.Bleeding, seconds, level, Convert.ToString(dotDamage));
        }
예제 #20
0
        public void OnImpact(NWPlayer player, NWObject target, int level, int spellFeatID)
        {
            int length;
            int dotAmount;

            int         basePotency;
            const float Tier1Modifier = 1.0f;
            const float Tier2Modifier = 1.6f;
            const float Tier3Modifier = 2.2f;
            const float Tier4Modifier = 0;

            switch (level)
            {
            case 1:
                basePotency = 15;
                length      = 0;
                dotAmount   = 0;
                break;

            case 2:
                basePotency = 20;
                length      = 6;
                dotAmount   = 4;
                break;

            case 3:
                basePotency = 25;
                length      = 6;
                dotAmount   = 6;
                break;

            case 4:
                basePotency = 40;
                length      = 12;
                dotAmount   = 6;
                break;

            case 5:
                basePotency = 50;
                length      = 12;
                dotAmount   = 6;
                break;

            case 6:
                basePotency = 60;
                length      = 12;
                dotAmount   = 6;
                break;

            case 7:
                basePotency = 70;
                length      = 12;
                dotAmount   = 6;
                break;

            case 8:
                basePotency = 80;
                length      = 12;
                dotAmount   = 8;
                break;

            case 9:
                basePotency = 90;
                length      = 12;
                dotAmount   = 8;
                break;

            case 10:
                basePotency = 100;
                length      = 12;
                dotAmount   = 10;
                break;

            default: return;
            }

            var effectiveStats = PlayerStatService.GetPlayerItemEffectiveStats(player);
            int luck           = PerkService.GetPCPerkLevel(player, PerkType.Lucky) + effectiveStats.Luck;

            if (RandomService.Random(100) + 1 <= luck)
            {
                length = length * 2;
                player.SendMessage("Lucky force lightning!");
            }

            var calc = CombatService.CalculateForceDamage(
                player,
                target.Object,
                ForceAbilityType.Electrical,
                basePotency,
                Tier1Modifier,
                Tier2Modifier,
                Tier3Modifier,
                Tier4Modifier);

            player.AssignCommand(() =>
            {
                Effect damage = _.EffectDamage(calc.Damage, DAMAGE_TYPE_ELECTRICAL);
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, damage, target);
            });

            if (length > 0.0f && dotAmount > 0)
            {
                CustomEffectService.ApplyCustomEffect(player, target.Object, CustomEffectType.ForceShock, length, level, dotAmount.ToString());
            }

            SkillService.RegisterPCToAllCombatTargetsForSkill(player, SkillType.ForceCombat, target.Object);

            player.AssignCommand(() =>
            {
                _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectVisualEffect(VFX_BEAM_LIGHTNING), target, 1.0f);
            });
            _.PlaySound("v_pro_lightning");
            CombatService.AddTemporaryForceDefense(target.Object, ForceAbilityType.Electrical);
        }
예제 #21
0
        public static void grenadeAoe(NWObject oTarget, string grenadeType)
        {
            if (oTarget.ObjectType != ObjectType.Creature)
            {
                return;
            }
            NWCreature user           = GetAreaOfEffectCreator(_.OBJECT_SELF);
            int        perkLevel      = PerkService.GetCreaturePerkLevel(user, PerkType.GrenadeProficiency);
            int        duration       = 1;
            Effect     impactEffect   = null;
            Effect     durationEffect = null;

            //Console.WriteLine("In grenadeAoe for grenade type " + grenadeType + " on " + GetName(oTarget));

            switch (grenadeType)
            {
            case "SMOKE":
                durationEffect = EffectInvisibility(InvisibilityType.Normal);
                break;

            case "BACTABOMB":
                durationEffect = EffectRegenerate(perkLevel * 2, 6.0f);
                break;

            case "INCENDIARY":
                impactEffect = EffectDamage(RandomService.D6(perkLevel), DamageType.Fire);
                duration     = RandomService.D6(1);
                if (RandomService.D6(1) > 4)
                {
                    CustomEffectService.ApplyCustomEffect(user, (NWCreature)oTarget, CustomEffectType.Burning, duration * 6, perkLevel, Convert.ToString(perkLevel));
                }
                break;

            case "GAS":
                impactEffect = EffectDamage(RandomService.D6(perkLevel), DamageType.Acid);
                duration     = RandomService.D6(1);
                if (RandomService.D6(1) > 4 && GetIsImmune(oTarget, ImmunityType.Poison) == false)
                {
                    durationEffect = EffectPoison(Poison.Arsenic);
                }
                break;

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

            if (GetIsObjectValid(oTarget) == true)
            {
                if (impactEffect != null)
                {
                    ApplyEffectToObject(DurationType.Instant, impactEffect, oTarget);
                }
                if (durationEffect != null)
                {
                    ApplyEffectToObject(DurationType.Temporary, durationEffect, oTarget, duration * 6.0f);
                }
                if (!oTarget.IsPlayer)
                {
                    SkillService.RegisterPCToNPCForSkill(user.Object, oTarget, SkillType.Throwing);
                }
            }
        }
예제 #22
0
        private bool UseFeat(int featID, string featName, NWCreature caster, NWCreature target)
        {
            // Note - this code is loosely based on code from AbilityService.  However, the perk interface
            // is written assuming players will always be using perks.  To allow NPCs to use them requires some hackery.
            int perkLevel = (int)caster.ChallengeRating / 5;

            if (perkLevel < 1)
            {
                perkLevel = 1;
            }

            if (caster.Area.Resref != target.Area.Resref ||
                _.LineOfSightObject(caster.Object, target.Object) == 0)
            {
                return(false);
            }

            // Give NPCs a bit longer range than most PCs.
            if (_.GetDistanceBetween(caster, target) > 20.0f)
            {
                return(false);
            }

            // Note - NPCs are assumed to have infinite FPs.
            if (_.GetIsDead(caster) == 1)
            {
                return(false);
            }

            // Cooldown of 1 round.
            string   timeout    = caster.GetLocalString("TIMEOUT_" + featName);
            DateTime unlockTime = DateTime.UtcNow;

            if (!string.IsNullOrWhiteSpace(timeout))
            {
                unlockTime = DateTime.Parse(timeout);
            }
            DateTime now = DateTime.UtcNow;

            if (unlockTime > now)
            {
                return(false);
            }
            else
            {
                unlockTime = now.AddSeconds(6);
                caster.SetLocalString("TIMEOUT_" + featName, unlockTime.ToString());
            }

            // Do the actual force attack.  Code taken from perks.
            if (featID == (int)CustomFeatType.ForceLightning)
            {
                int length;
                int dotAmount;

                int         basePotency;
                const float Tier1Modifier = 1.0f;
                const float Tier2Modifier = 1.6f;
                const float Tier3Modifier = 2.2f;
                const float Tier4Modifier = 0;

                switch (perkLevel)
                {
                case 1:
                    basePotency = 15;
                    length      = 0;
                    dotAmount   = 0;
                    break;

                case 2:
                    basePotency = 20;
                    length      = 6;
                    dotAmount   = 4;
                    break;

                case 3:
                    basePotency = 25;
                    length      = 6;
                    dotAmount   = 6;
                    break;

                case 4:
                    basePotency = 40;
                    length      = 12;
                    dotAmount   = 6;
                    break;

                case 5:
                    basePotency = 50;
                    length      = 12;
                    dotAmount   = 6;
                    break;

                case 6:
                    basePotency = 60;
                    length      = 12;
                    dotAmount   = 6;
                    break;

                case 7:
                    basePotency = 70;
                    length      = 12;
                    dotAmount   = 6;
                    break;

                case 8:
                    basePotency = 80;
                    length      = 12;
                    dotAmount   = 8;
                    break;

                case 9:
                    basePotency = 90;
                    length      = 12;
                    dotAmount   = 8;
                    break;

                default:
                    basePotency = 100;
                    length      = 12;
                    dotAmount   = 10;
                    break;
                }

                var calc = CombatService.CalculateForceDamage(
                    caster,
                    target.Object,
                    ForceAbilityType.Electrical,
                    basePotency,
                    Tier1Modifier,
                    Tier2Modifier,
                    Tier3Modifier,
                    Tier4Modifier);

                caster.AssignCommand(() => {
                    _.SetFacingPoint(target.Location.Position);
                    _.ActionPlayAnimation(ANIMATION_LOOPING_CONJURE1, 1.0f, 1.0f);
                });

                caster.SetLocalInt("CASTING", 1);

                _.DelayCommand(1.0f, () =>
                {
                    caster.AssignCommand(() =>
                    {
                        Effect damage = _.EffectDamage(calc.Damage, DAMAGE_TYPE_ELECTRICAL);
                        _.ApplyEffectToObject(DURATION_TYPE_INSTANT, damage, target);
                    });

                    if (length > 0.0f && dotAmount > 0)
                    {
                        CustomEffectService.ApplyCustomEffect(caster, target.Object, CustomEffectType.ForceShock, length, perkLevel, dotAmount.ToString());
                    }

                    caster.AssignCommand(() =>
                    {
                        _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectVisualEffect(VFX_BEAM_LIGHTNING), target, 1.0f);
                        caster.DeleteLocalInt("CASTING");
                    });

                    CombatService.AddTemporaryForceDefense(target.Object, ForceAbilityType.Electrical);
                });
            }
            else if (featID == (int)CustomFeatType.DrainLife)
            {
                float       recoveryPercent;
                int         basePotency;
                const float Tier1Modifier = 1;
                const float Tier2Modifier = 2;
                const float Tier3Modifier = 0;
                const float Tier4Modifier = 0;

                switch (perkLevel)
                {
                case 1:
                    basePotency     = 10;
                    recoveryPercent = 0.2f;
                    break;

                case 2:
                    basePotency     = 15;
                    recoveryPercent = 0.2f;
                    break;

                case 3:
                    basePotency     = 20;
                    recoveryPercent = 0.4f;
                    break;

                case 4:
                    basePotency     = 25;
                    recoveryPercent = 0.4f;
                    break;

                default:
                    basePotency     = 30;
                    recoveryPercent = 0.5f;
                    break;
                }

                var calc = CombatService.CalculateForceDamage(
                    caster,
                    target.Object,
                    ForceAbilityType.Dark,
                    basePotency,
                    Tier1Modifier,
                    Tier2Modifier,
                    Tier3Modifier,
                    Tier4Modifier);

                caster.AssignCommand(() => {
                    _.SetFacingPoint(target.Location.Position);
                    _.ActionPlayAnimation(ANIMATION_LOOPING_CONJURE1, 1.0f, 1.0f);
                });
                caster.SetLocalInt("CASTING", 1);

                _.DelayCommand(1.0f, () =>
                {
                    _.AssignCommand(caster, () =>
                    {
                        int heal = (int)(calc.Damage * recoveryPercent);
                        if (heal > target.CurrentHP)
                        {
                            heal = target.CurrentHP;
                        }

                        _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectDamage(calc.Damage), target);
                        _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectHeal(heal), caster);
                        _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectVisualEffect(VFX_BEAM_MIND), target, 1.0f);
                        caster.DeleteLocalInt("CASTING");
                    });
                });


                CombatService.AddTemporaryForceDefense(target.Object, ForceAbilityType.Dark);
            }

            return(true);
        }
예제 #23
0
        public bool Run(params object[] args)
        {
            using (new Profiler(nameof(FinishAbilityUse)))
            {
                NWPlayer pc          = (NWPlayer)args[0];
                string   spellUUID   = Convert.ToString(args[1]);
                int      perkID      = (int)args[2];
                NWObject target      = (NWObject)args[3];
                int      pcPerkLevel = (int)args[4];
                int      featID      = (int)args[5];

                Data.Entity.Perk  entity        = DataService.Single <Data.Entity.Perk>(x => x.ID == perkID);
                PerkExecutionType executionType = (PerkExecutionType)entity.ExecutionTypeID;
                IPerkHandler      perk          = PerkService.GetPerkHandler(perkID);

                int?cooldownID            = perk.CooldownCategoryID(pc, entity.CooldownCategoryID, featID);
                CooldownCategory cooldown = cooldownID == null ? null : DataService.SingleOrDefault <CooldownCategory>(x => x.ID == cooldownID);

                if (pc.GetLocalInt(spellUUID) == (int)SpellStatusType.Interrupted || // Moved during casting
                    pc.CurrentHP < 0 || pc.IsDead)                                   // Or is dead/dying
                {
                    pc.DeleteLocalInt(spellUUID);
                    return(false);
                }

                pc.DeleteLocalInt(spellUUID);

                if (executionType == PerkExecutionType.ForceAbility ||
                    executionType == PerkExecutionType.CombatAbility ||
                    executionType == PerkExecutionType.Stance)
                {
                    perk.OnImpact(pc, target, pcPerkLevel, featID);

                    if (entity.CastAnimationID != null && entity.CastAnimationID > 0)
                    {
                        pc.AssignCommand(() => { _.ActionPlayAnimation((int)entity.CastAnimationID, 1f, 1f); });
                    }

                    if (target.IsNPC)
                    {
                        AbilityService.ApplyEnmity(pc, (target.Object), entity);
                    }
                }
                else if (executionType == PerkExecutionType.QueuedWeaponSkill)
                {
                    AbilityService.HandleQueueWeaponSkill(pc, entity, perk, featID);
                }


                // Adjust FP only if spell cost > 0
                Data.Entity.Player pcEntity = DataService.Single <Data.Entity.Player>(x => x.ID == pc.GlobalID);
                int fpCost = perk.FPCost(pc, entity.BaseFPCost, featID);

                if (fpCost > 0)
                {
                    pcEntity.CurrentFP = pcEntity.CurrentFP - fpCost;
                    DataService.SubmitDataChange(pcEntity, DatabaseActionType.Update);
                    pc.SendMessage(ColorTokenService.Custom("FP: " + pcEntity.CurrentFP + " / " + pcEntity.MaxFP, 32, 223, 219));
                }

                bool hasChainspell = CustomEffectService.DoesPCHaveCustomEffect(pc, CustomEffectType.Chainspell) &&
                                     executionType == PerkExecutionType.ForceAbility;

                if (!hasChainspell && cooldown != null)
                {
                    // Mark cooldown on category
                    AbilityService.ApplyCooldown(pc, cooldown, perk, featID);
                }

                pc.IsBusy = false;
                pc.SetLocalInt(spellUUID, (int)SpellStatusType.Completed);

                return(true);
            }
        }
예제 #24
0
        public void DoImpact(NWCreature user, NWItem item, Location targetLocation, string grenadeType, int perkLevel, float fExplosionRadius, ObjectType nObjectFilter)
        {
            Effect damageEffect   = EffectDamage(0, DamageType.Negative);
            Effect durationEffect = null;
            int    duration       = perkLevel + 1;
            int    bonus          = item.DamageBonus;
            int    medbonus       = item.MedicineBonus;

            switch (grenadeType)
            {
            case "SMOKE":
                durationEffect = EffectAreaOfEffect(AreaOfEffect.FogOfBewilderment, "grenade_smoke_en", "grenade_smoke_hb", "");
                break;

            case "BACTABOMB":
                durationEffect = EffectAreaOfEffect(AreaOfEffect.FogMind, "grenade_bbomb_en", "grenade_bbomb_hb", "");
                break;

            case "INCENDIARY":
                durationEffect = EffectAreaOfEffect(AreaOfEffect.FogFire, "grenade_incen_en", "grenade_incen_hb", "");
                break;

            case "GAS":
                durationEffect = EffectAreaOfEffect(AreaOfEffect.FogAcid, "grenade_gas_en", "grenade_gas_hb", "");
                break;

            default:
                break;
            }

            if (durationEffect != null)
            {
                //Apply AOE
                ApplyEffectAtLocation(DurationType.Temporary, durationEffect, targetLocation, duration * 6.0f);
            }
            else
            {
                //Apply impact

                // Target the next nearest creature and do the same thing.
                NWObject targetCreature = GetFirstObjectInShape(Shape.Sphere, fExplosionRadius, targetLocation, true, nObjectFilter);
                while (targetCreature.IsValid)
                {
                    //Console.WriteLine("Grenade hit on " + targetCreature.Name);

                    switch (grenadeType)
                    {
                    case "FRAG":
                        damageEffect = EffectDamage(RandomService.D6(perkLevel) + bonus, DamageType.Fire);
                        damageEffect = EffectLinkEffects(EffectDamage(RandomService.D6(perkLevel) + bonus, DamageType.Piercing), damageEffect);
                        if (RandomService.D6(1) > 4)
                        {
                            //Console.WriteLine("grenade effect bleeding - frag");
                            CustomEffectService.ApplyCustomEffect(user, targetCreature.Object, CustomEffectType.Bleeding, duration * 6, perkLevel, Convert.ToString(perkLevel));
                        }
                        if (RandomService.D6(1) > 4)
                        {
                            //Console.WriteLine("grenade effects burning - frag");
                            CustomEffectService.ApplyCustomEffect(user, targetCreature.Object, CustomEffectType.Burning, duration * 6, perkLevel, Convert.ToString(perkLevel));
                        }
                        //Console.WriteLine("grenade effects set - frag");
                        break;

                    case "CONCUSSION":
                        damageEffect   = EffectDamage(RandomService.D12(perkLevel) + bonus, DamageType.Sonic);
                        durationEffect = EffectDeaf();
                        if (RandomService.D6(1) > 4)
                        {
                            FloatingTextStringOnCreature("Your ears ring and your body shakes.", targetCreature);
                            durationEffect = EffectLinkEffects(AbilityService.EffectKnockdown(targetCreature, duration), durationEffect);
                        }
                        break;

                    case "FLASHBANG":
                        duration       = RandomService.D4(1);
                        durationEffect = EffectDeaf();
                        if (RandomService.D6(1) > 4)
                        {
                            FloatingTextStringOnCreature("Your vision blurs and blacks out.", targetCreature);
                            durationEffect = EffectLinkEffects(EffectBlindness(), durationEffect);
                        }
                        break;

                    case "ION":
                        duration     = RandomService.D4(1);
                        damageEffect = EffectDamage(RandomService.D6(perkLevel) + bonus, DamageType.Electrical);
                        if (GetRacialType(targetCreature) == RacialType.Robot ||
                            (RandomService.D6(1) > 4 && GetRacialType(targetCreature) == RacialType.Cyborg))
                        {
                            FloatingTextStringOnCreature("Your circuits are overloaded.", targetCreature);
                            durationEffect = EffectStunned();
                        }
                        break;

                    case "BACTA":
                        damageEffect   = null;
                        durationEffect = EffectRegenerate(perkLevel + 1 + medbonus, 6.0f);
                        break;

                    case "ADHESIVE":
                        durationEffect = EffectSlow();
                        if (RandomService.D6(1) > 4)
                        {
                            FloatingTextStringOnCreature("You are slowed by the adhesive explosion.", targetCreature);
                            durationEffect = EffectLinkEffects(EffectCutsceneImmobilize(), durationEffect);
                        }
                        break;

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

                    //Console.WriteLine("applying effects to " + GetName(targetCreature));

                    if (damageEffect != null)
                    {
                        ApplyEffectToObject(DurationType.Instant, damageEffect, targetCreature);
                    }
                    if (durationEffect != null)
                    {
                        ApplyEffectToObject(DurationType.Temporary, durationEffect, targetCreature, duration * 6.0f);
                    }

                    if (!targetCreature.IsPlayer)
                    {
                        SkillService.RegisterPCToNPCForSkill(user.Object, targetCreature, SkillType.Throwing);
                    }

                    targetCreature = GetNextObjectInShape(Shape.Sphere, fExplosionRadius, targetLocation, true, nObjectFilter);
                }
            }
        }
예제 #25
0
        public void OnImpact(NWPlayer player, NWObject target, int perkLevel, int spellFeatID)
        {
            CustomEffectService.ApplyCustomEffect(player, player, CustomEffectType.AbsorptionField, 20, perkLevel, null);

            _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_IMP_GLOBE_USE), target);
        }