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)); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } } }
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); }
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); } }
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); }
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); }
public void OnImpact(NWPlayer player, NWObject target, int perkLevel, int spellFeatID) { CustomEffectService.ApplyCustomEffect(player, player, CustomEffectType.Rest, -1, 0, null); }
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); }
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)); }
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); }
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); } } }
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); }
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); } }
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); } } }
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); }