Beispiel #1
0
        public static int CalculateReassemblyChance(NWPlayer player, int penalty)
        {
            const int BaseChance  = 70;
            int       harvesting  = SkillService.GetPCSkillRank(player, SkillType.Harvesting);
            var       itemBonuses = PlayerStatService.GetPlayerItemEffectiveStats(player);
            int       perkLevel   = PerkService.GetPCPerkLevel(player, PerkType.MolecularReassemblyProficiency);

            // Calculate the base chance after factoring in skills, perks, and items.
            int categoryChance = (int)(BaseChance + (harvesting / 2.5f) + perkLevel * 10 + itemBonuses.Harvesting / 3f);

            // Reduce the chance by the penalty. This penalty is generally determined by how many properties were already
            // applied during this batch.
            categoryChance -= penalty;

            // Keep bounds between 0 and 100
            if (categoryChance < 0)
            {
                return(0);
            }
            else if (categoryChance > 100)
            {
                return(100);
            }
            else
            {
                return(categoryChance);
            }
        }
Beispiel #2
0
        private static void HandleFPRegenerationTick(NWPlayer oPC, Data.Entity.Player entity)
        {
            entity.CurrentFPTick = entity.CurrentFPTick - 1;
            int rate   = 20;
            int amount = 1;

            if (entity.CurrentFPTick <= 0)
            {
                if (entity.CurrentFP < entity.MaxFP)
                {
                    var effectiveStats = PlayerStatService.GetPlayerItemEffectiveStats(oPC);
                    // CHA bonus
                    int cha = oPC.CharismaModifier;
                    if (cha > 0)
                    {
                        amount += cha;
                    }
                    amount += effectiveStats.FPRegen;

                    if (oPC.Chest.CustomItemType == CustomItemType.ForceArmor)
                    {
                        int clarityLevel = PerkService.GetPCPerkLevel(oPC, PerkType.Clarity);
                        if (clarityLevel > 0)
                        {
                            amount += clarityLevel + 1;
                        }
                    }

                    entity = AbilityService.RestoreFP(oPC, amount, entity);
                }

                entity.CurrentFPTick = rate;
            }
        }
Beispiel #3
0
        private static void HandleRegenerationTick(NWPlayer oPC, Data.Entity.Player entity)
        {
            entity.RegenerationTick = entity.RegenerationTick - 1;
            int rate   = 20;
            int amount = entity.HPRegenerationAmount;

            if (entity.RegenerationTick <= 0)
            {
                if (oPC.CurrentHP < oPC.MaxHP)
                {
                    var effectiveStats = PlayerStatService.GetPlayerItemEffectiveStats(oPC);
                    // CON bonus
                    int con = oPC.ConstitutionModifier;
                    if (con > 0)
                    {
                        amount += con;
                    }
                    amount += effectiveStats.HPRegen;

                    if (oPC.Chest.CustomItemType == CustomItemType.HeavyArmor)
                    {
                        int sturdinessLevel = PerkService.GetPCPerkLevel(oPC, PerkType.Sturdiness);
                        if (sturdinessLevel > 0)
                        {
                            amount += sturdinessLevel + 1;
                        }
                    }
                    _.ApplyEffectToObject(_.DURATION_TYPE_INSTANT, _.EffectHeal(amount), oPC.Object);
                }

                entity.RegenerationTick = rate;
            }
        }
Beispiel #4
0
        private static int EffectiveMaxFP(NWPlayer player, EffectiveItemStats stats)
        {
            int fp = 20;

            fp += (player.IntelligenceModifier + player.WisdomModifier + player.CharismaModifier) * 5;
            fp += PerkService.GetPCPerkLevel(player, PerkType.FP) * 5;
            fp += stats.FP;

            if (fp < 0)
            {
                fp = 0;
            }

            return(fp);
        }
Beispiel #5
0
        private static int EffectiveMaxHitPoints(NWPlayer player, EffectiveItemStats stats)
        {
            int   hp = 25 + player.ConstitutionModifier * 5;
            float effectPercentBonus = CustomEffectService.CalculateEffectHPBonusPercent(player);

            hp += PerkService.GetPCPerkLevel(player, PerkType.Health) * 5;
            hp += stats.HP;
            hp  = hp + (int)(hp * effectPercentBonus);

            if (hp > 1275)
            {
                hp = 1275;
            }
            if (hp < 20)
            {
                hp = 20;
            }

            return(hp);
        }
Beispiel #6
0
        private static void HandleGrenadeProficiency(NWPlayer oPC, NWObject target)
        {
            NWItem weapon = _.GetSpellCastItem();

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

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

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

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

            default: return;
            }


            if (RandomService.D100(1) <= chance)
            {
                _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectKnockdown(), target, duration);
            }
        }
Beispiel #7
0
        public static float CalculateCraftingDelay(NWPlayer oPC, int skillID)
        {
            int       atmosphere = CalculateAreaAtmosphereBonus(oPC.Area);
            PerkType  perkType;
            float     adjustedSpeed = 1.0f;
            SkillType skillType     = (SkillType)skillID;

            // Identify which perk to use for this skill.
            if (skillType == SkillType.Weaponsmith)
            {
                perkType = PerkType.SpeedyWeaponsmith;
            }
            else if (skillType == SkillType.Armorsmith)
            {
                perkType = PerkType.SpeedyArmorsmith;
            }
            else if (skillType == SkillType.Cooking)
            {
                perkType = PerkType.SpeedyCooking;
            }
            else if (skillType == SkillType.Engineering)
            {
                perkType = PerkType.SpeedyEngineering;
            }
            else if (skillType == SkillType.Fabrication)
            {
                perkType = PerkType.SpeedyFabrication;
            }
            else if (skillType == SkillType.Medicine)
            {
                perkType = PerkType.SpeedyMedicine;
            }
            else if (skillType == SkillType.Harvesting)
            {
                perkType = PerkType.SpeedyReassembly;
            }
            else
            {
                return(BaseCraftDelay);
            }

            int perkLevel = PerkService.GetPCPerkLevel(oPC, perkType);

            // Each perk level reduces crafting speed by 10%.
            switch (perkLevel)
            {
            case 1: adjustedSpeed = 0.9f; break;

            case 2: adjustedSpeed = 0.8f; break;

            case 3: adjustedSpeed = 0.7f; break;

            case 4: adjustedSpeed = 0.6f; break;

            case 5: adjustedSpeed = 0.5f; break;

            case 6: adjustedSpeed = 0.4f; break;

            case 7: adjustedSpeed = 0.3f; break;

            case 8: adjustedSpeed = 0.2f; break;

            case 9: adjustedSpeed = 0.1f; break;

            case 10: adjustedSpeed = 0.01f; break;
            }

            // Workshops with an atmosphere bonus decrease crafting time.
            if (atmosphere >= 45)
            {
                adjustedSpeed -= 0.2f;
            }
            else if (atmosphere >= 5)
            {
                adjustedSpeed -= 0.1f;
            }

            // Never fall below 1% of overall crafting time.
            if (adjustedSpeed <= 0.01f)
            {
                adjustedSpeed = 0.01f;
            }

            return(BaseCraftDelay * adjustedSpeed);
        }
Beispiel #8
0
        private static int CalculateBAB(NWPlayer oPC, NWItem ignoreItem, EffectiveItemStats stats)
        {
            NWItem weapon = oPC.RightHand;

            // The unequip event fires before the item is actually unequipped, so we need
            // to have additional checks to make sure we're not getting the weapon that's about to be
            // unequipped.
            if (weapon.Equals(ignoreItem))
            {
                weapon = null;
                NWItem offHand = oPC.LeftHand;

                if (offHand.CustomItemType == CustomItemType.Vibroblade ||
                    offHand.CustomItemType == CustomItemType.FinesseVibroblade ||
                    offHand.CustomItemType == CustomItemType.Baton ||
                    offHand.CustomItemType == CustomItemType.HeavyVibroblade ||
                    offHand.CustomItemType == CustomItemType.Saberstaff ||
                    offHand.CustomItemType == CustomItemType.Polearm ||
                    offHand.CustomItemType == CustomItemType.TwinBlade ||
                    offHand.CustomItemType == CustomItemType.MartialArtWeapon ||
                    offHand.CustomItemType == CustomItemType.BlasterPistol ||
                    offHand.CustomItemType == CustomItemType.BlasterRifle ||
                    offHand.CustomItemType == CustomItemType.Throwing)
                {
                    weapon = offHand;
                }
            }

            if (weapon == null || !weapon.IsValid)
            {
                weapon = oPC.Arms;
            }
            if (!weapon.IsValid)
            {
                return(0);
            }

            SkillType itemSkill = ItemService.GetSkillTypeForItem(weapon);

            if (itemSkill == SkillType.Unknown ||
                itemSkill == SkillType.LightArmor ||
                itemSkill == SkillType.HeavyArmor ||
                itemSkill == SkillType.ForceArmor ||
                itemSkill == SkillType.Shields)
            {
                return(0);
            }

            int     weaponSkillID = (int)itemSkill;
            PCSkill skill         = DataService.Single <PCSkill>(x => x.PlayerID == oPC.GlobalID && x.SkillID == weaponSkillID);

            if (skill == null)
            {
                return(0);
            }
            int            skillBAB                = skill.Rank / 10;
            int            perkBAB                 = 0;
            int            backgroundBAB           = 0;
            BackgroundType background              = (BackgroundType)oPC.Class1;
            bool           receivesBackgroundBonus = false;

            // Apply increased BAB if player is using a weapon for which they have a proficiency.
            PerkType  proficiencyPerk  = PerkType.Unknown;
            SkillType proficiencySkill = SkillType.Unknown;

            switch (weapon.CustomItemType)
            {
            case CustomItemType.Vibroblade:
                proficiencyPerk  = PerkType.VibrobladeProficiency;
                proficiencySkill = SkillType.OneHanded;
                break;

            case CustomItemType.FinesseVibroblade:
                proficiencyPerk         = PerkType.FinesseVibrobladeProficiency;
                proficiencySkill        = SkillType.OneHanded;
                receivesBackgroundBonus = background == BackgroundType.Duelist;
                break;

            case CustomItemType.Baton:
                proficiencyPerk         = PerkType.BatonProficiency;
                proficiencySkill        = SkillType.OneHanded;
                receivesBackgroundBonus = background == BackgroundType.SecurityOfficer;
                break;

            case CustomItemType.HeavyVibroblade:
                proficiencyPerk         = PerkType.HeavyVibrobladeProficiency;
                proficiencySkill        = SkillType.TwoHanded;
                receivesBackgroundBonus = background == BackgroundType.Soldier;
                break;

            case CustomItemType.Saberstaff:
                proficiencyPerk  = PerkType.SaberstaffProficiency;
                proficiencySkill = SkillType.Lightsaber;
                break;

            case CustomItemType.Polearm:
                proficiencyPerk  = PerkType.PolearmProficiency;
                proficiencySkill = SkillType.TwoHanded;
                break;

            case CustomItemType.TwinBlade:
                proficiencyPerk         = PerkType.TwinVibrobladeProficiency;
                proficiencySkill        = SkillType.TwinBlades;
                receivesBackgroundBonus = background == BackgroundType.Berserker;
                break;

            case CustomItemType.MartialArtWeapon:
                proficiencyPerk         = PerkType.MartialArtsProficiency;
                proficiencySkill        = SkillType.MartialArts;
                receivesBackgroundBonus = background == BackgroundType.TerasKasi;
                break;

            case CustomItemType.BlasterPistol:
                proficiencyPerk         = PerkType.BlasterPistolProficiency;
                proficiencySkill        = SkillType.Firearms;
                receivesBackgroundBonus = background == BackgroundType.Smuggler;
                break;

            case CustomItemType.BlasterRifle:
                proficiencyPerk         = PerkType.BlasterRifleProficiency;
                proficiencySkill        = SkillType.Firearms;
                receivesBackgroundBonus = background == BackgroundType.Sharpshooter || background == BackgroundType.Mandalorian;
                break;

            case CustomItemType.Throwing:
                proficiencyPerk  = PerkType.ThrowingProficiency;
                proficiencySkill = SkillType.Throwing;
                break;

            case CustomItemType.Lightsaber:
                proficiencyPerk  = PerkType.LightsaberProficiency;
                proficiencySkill = SkillType.Lightsaber;
                break;
            }

            if (weapon.GetLocalInt("LIGHTSABER") == TRUE)
            {
                proficiencyPerk  = PerkType.LightsaberProficiency;
                proficiencySkill = SkillType.Lightsaber;
            }

            if (proficiencyPerk != PerkType.Unknown &&
                proficiencySkill != SkillType.Unknown)
            {
                perkBAB += PerkService.GetPCPerkLevel(oPC, proficiencyPerk);
            }

            if (receivesBackgroundBonus)
            {
                backgroundBAB = background == BackgroundType.Mandalorian ? 1 : 2;
            }

            return(1 + skillBAB + perkBAB + stats.BAB + backgroundBAB); // Note: Always add 1 to BAB. 0 will cause a crash in NWNX.
        }
Beispiel #9
0
        public static void HandlePlasmaCellPerk(NWPlayer player, NWObject target)
        {
            if (!player.IsPlayer)
            {
                return;
            }
            if (_.GetHasFeat((int)CustomFeatType.PlasmaCell, player) == FALSE)
            {
                return;                                                                 // Check if player has the perk
            }
            if (player.RightHand.CustomItemType != CustomItemType.BlasterPistol &&
                player.RightHand.CustomItemType != CustomItemType.BlasterRifle)
            {
                return;                                                                 // Check if player has the right weapons
            }
            if (target.GetLocalInt("TRANQUILIZER_EFFECT_FIRST_RUN") == _.TRUE)
            {
                return;                                                                  // Check if Tranquilizer is on to avoid conflict
            }
            if (player.GetLocalInt("PLASMA_CELL_TOGGLE_OFF") == _.TRUE)
            {
                return;                                                          // Check if Plasma Cell toggle is on or off
            }
            if (target.GetLocalInt("TRANQUILIZER_EFFECT_FIRST_RUN") == _.TRUE)
            {
                return;
            }

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

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

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

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

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

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

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

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

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

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

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

            default: return;
            }

            foreach (var effect in damageTypes)
            {
                if (RandomService.D100(1) <= chance)
                {
                    CustomEffectService.ApplyCustomEffect(player, target.Object, effect, RandomService.D6(1), perkLevel, null);
                }
            }
        }
Beispiel #10
0
        private static void OnModuleUseFeat()
        {
            NWPlayer   pc       = Object.OBJECT_SELF;
            NWCreature target   = NWNXEvents.OnFeatUsed_GetTarget().Object;
            int        featID   = NWNXEvents.OnFeatUsed_GetFeatID();
            var        perkFeat = DataService.SingleOrDefault <PerkFeat>(x => x.FeatID == featID);

            if (perkFeat == null)
            {
                return;
            }
            Data.Entity.Perk perk = DataService.GetAll <Data.Entity.Perk>().SingleOrDefault(x => x.ID == perkFeat.PerkID);
            if (perk == null)
            {
                return;
            }

            // Check to see if we are a spaceship.  Spaceships can't use abilities...
            if (pc.GetLocalInt("IS_SHIP") > 0 || pc.GetLocalInt("IS_GUNNER") > 0)
            {
                pc.SendMessage("You cannot use that ability while piloting a ship.");
                return;
            }

            var perkAction = PerkService.GetPerkHandler(perkFeat.PerkID);

            Player playerEntity = DataService.Get <Player>(pc.GlobalID);
            int    pcPerkLevel  = PerkService.GetPCPerkLevel(pc, perk.ID);

            // If player is disabling an existing stance, remove that effect.
            if (perk.ExecutionTypeID == (int)PerkExecutionType.Stance)
            {
                PCCustomEffect stanceEffect = DataService.SingleOrDefault <PCCustomEffect>(x => x.StancePerkID == perk.ID &&
                                                                                           x.PlayerID == pc.GlobalID);

                if (stanceEffect != null)
                {
                    if (CustomEffectService.RemoveStance(pc))
                    {
                        return;
                    }
                }
            }

            if (pcPerkLevel <= 0)
            {
                pc.SendMessage("You do not meet the prerequisites to use this ability.");
                return;
            }

            if (perkAction.IsHostile() && target.IsPlayer)
            {
                if (!PVPSanctuaryService.IsPVPAttackAllowed(pc, target.Object))
                {
                    return;
                }
            }

            if (pc.Area.Resref != target.Area.Resref ||
                _.LineOfSightObject(pc.Object, target.Object) == 0)
            {
                pc.SendMessage("You cannot see your target.");
                return;
            }

            if (!perkAction.CanCastSpell(pc, target))
            {
                pc.SendMessage(perkAction.CannotCastSpellMessage(pc, target) ?? "That ability cannot be used at this time.");
                return;
            }

            int fpCost = perkAction.FPCost(pc, perkAction.FPCost(pc, perk.BaseFPCost, featID), featID);

            if (playerEntity.CurrentFP < fpCost)
            {
                pc.SendMessage("You do not have enough FP. (Required: " + fpCost + ". You have: " + playerEntity.CurrentFP + ")");
                return;
            }

            if (pc.IsBusy || pc.CurrentHP <= 0)
            {
                pc.SendMessage("You are too busy to activate that ability.");
                return;
            }

            // Check cooldown
            int?       cooldownCategoryID = perkAction.CooldownCategoryID(pc, perk.CooldownCategoryID, featID);
            PCCooldown pcCooldown         = DataService.GetAll <PCCooldown>().SingleOrDefault(x => x.PlayerID == pc.GlobalID &&
                                                                                              x.CooldownCategoryID == cooldownCategoryID);

            if (pcCooldown == null)
            {
                pcCooldown = new PCCooldown
                {
                    CooldownCategoryID = Convert.ToInt32(cooldownCategoryID),
                    DateUnlocked       = DateTime.UtcNow.AddSeconds(-1),
                    PlayerID           = pc.GlobalID
                };

                DataService.SubmitDataChange(pcCooldown, DatabaseActionType.Insert);
            }

            DateTime unlockDateTime = pcCooldown.DateUnlocked;
            DateTime now            = DateTime.UtcNow;

            if (unlockDateTime > now)
            {
                string timeToWait = TimeService.GetTimeToWaitLongIntervals(now, unlockDateTime, false);
                pc.SendMessage("That ability can be used in " + timeToWait + ".");
                return;
            }

            // Force Abilities (aka Spells)
            if (perk.ExecutionTypeID == (int)PerkExecutionType.ForceAbility)
            {
                target.SetLocalInt(LAST_ATTACK + pc.GlobalID, ATTACK_FORCE);
                ActivateAbility(pc, target, perk, perkAction, pcPerkLevel, PerkExecutionType.ForceAbility, featID);
            }
            // Combat Abilities
            else if (perk.ExecutionTypeID == (int)PerkExecutionType.CombatAbility)
            {
                target.SetLocalInt(LAST_ATTACK + pc.GlobalID, ATTACK_PHYSICAL);
                ActivateAbility(pc, target, perk, perkAction, pcPerkLevel, PerkExecutionType.CombatAbility, featID);
            }
            // Queued Weapon Skills
            else if (perk.ExecutionTypeID == (int)PerkExecutionType.QueuedWeaponSkill)
            {
                target.SetLocalInt(LAST_ATTACK + pc.GlobalID, ATTACK_PHYSICAL);
                HandleQueueWeaponSkill(pc, perk, perkAction, featID);
            }
            // Stances
            else if (perk.ExecutionTypeID == (int)PerkExecutionType.Stance)
            {
                target.SetLocalInt(LAST_ATTACK + pc.GlobalID, ATTACK_COMBATABILITY);
                ActivateAbility(pc, target, perk, perkAction, pcPerkLevel, PerkExecutionType.Stance, featID);
            }
        }
Beispiel #11
0
        private static void HandleEvadeOrDeflectBlasterFire()
        {
            DamageEventData data = NWNXDamage.GetDamageEventData();

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

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

            int perkLevel;

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

            int    modifier;
            string action;

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

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

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

            if (delta <= 0)
            {
                return;
            }

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

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

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

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

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

            int delay; // Seconds delay between deflect attempts.

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

            case 2:
                delay = 12;
                break;

            case 3:
                delay = 6;
                break;

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

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

            int roll = RandomService.D100(1);

            if (roll <= chanceToDeflect)
            {
                target.SendMessage(ColorTokenService.Gray("You " + action + " a blaster shot."));
                data.AdjustAllByPercent(-1);
                NWNXDamage.SetDamageEventData(data);
            }
            else
            {
                target.SendMessage(ColorTokenService.Gray("You fail to " + action + " a blaster shot. (" + roll + " vs " + chanceToDeflect + ")"));
            }
        }
Beispiel #12
0
        private static void HandleBattlemagePerk()
        {
            DamageEventData data = NWNXDamage.GetDamageEventData();

            if (data.Base <= 0)
            {
                return;
            }

            NWObject target = Object.OBJECT_SELF;

            if (!data.Damager.IsPlayer || !target.IsNPC)
            {
                return;
            }
            if (_.GetHasFeat((int)CustomFeatType.Battlemage, data.Damager.Object) == FALSE)
            {
                return;
            }

            NWPlayer player = data.Damager.Object;
            NWItem   weapon = _.GetLastWeaponUsed(player.Object);

            if (weapon.CustomItemType != CustomItemType.Baton)
            {
                return;
            }
            if (player.Chest.CustomItemType != CustomItemType.ForceArmor)
            {
                return;
            }

            int perkRank = PerkService.GetPCPerkLevel(player, PerkType.Battlemage);

            int  restoreAmount = 0;
            bool metRoll       = RandomService.Random(100) + 1 <= 50;

            switch (perkRank)
            {
            case 1 when metRoll:
                restoreAmount = 1;
                break;

            case 2:
                restoreAmount = 1;
                break;

            case 3:
                restoreAmount = 1;
                if (metRoll)
                {
                    restoreAmount++;
                }
                break;

            case 4:
                restoreAmount = 2;
                break;

            case 5:
                restoreAmount = 2;
                if (metRoll)
                {
                    restoreAmount++;
                }
                break;

            case 6:
                restoreAmount = 3;
                break;
            }

            if (restoreAmount > 0)
            {
                AbilityService.RestoreFP(player, restoreAmount);
            }
        }