Esempio n. 1
0
        /// <summary>
        /// Checks caster's position. If they have moved too far from the initial casting position, the spell will be cancelled.
        /// </summary>
        /// <param name="stats">The user stats</param>
        private static void CheckMovement(UserStats stats)
        {
            if (stats.IsComplete)
            {
                return;
            }
            if (!GetIsObjectValid(stats.User))
            {
                return;
            }

            var position = GetPosition(stats.User);

            // Player moved too far from starting position. Cancel the spell.
            if (Math.Abs(position.X - stats.CastingPosition.X) > 0.01f ||
                Math.Abs(position.Y - stats.CastingPosition.Y) > 0.01f ||
                Math.Abs(position.Z - stats.CastingPosition.Z) > 0.01f)
            {
                stats.IsCancelled = true;
                NWNXPlayer.StopGuiTimingBar(stats.User, string.Empty);
                SetIsBusy(stats.User, false);
                SendMessageToPC(stats.User, "You move and interrupt your concentration.");
                return;
            }

            DelayCommand(0.5f, () => CheckMovement(stats));
        }
Esempio n. 2
0
        public static void Main()
        {
            NWGameObject player = GetExitingObject();

            if (!GetIsPlayer(player))
            {
                return;
            }

            var playerID = GetGlobalID(player);
            var area     = GetArea(player);

            if (!GetIsObjectValid(area))
            {
                area = NWGameObject.OBJECT_SELF;
            }

            var areaResref = GetResRef(area);

            var progress = NWNXPlayer.GetAreaExplorationState(player, area);

            var progression = MapProgressionRepo.Get(playerID, areaResref);

            progression.Progression = progress;
            MapProgressionRepo.Set(playerID, progression);
        }
Esempio n. 3
0
        private static void CheckForSpellInterruption(NWCreature activator, string spellUUID, Vector position)
        {
            if (activator.GetLocalInt(spellUUID) == (int)SpellStatusType.Completed)
            {
                return;
            }

            Vector currentPosition = activator.Position;

            if (currentPosition.X != position.X ||
                currentPosition.Y != position.Y ||
                currentPosition.Z != position.Z)
            {
                var effect = activator.Effects.SingleOrDefault(x => _.GetEffectTag(x) == "ACTIVATION_VFX");
                if (effect != null)
                {
                    _.RemoveEffect(activator, effect);
                }

                NWNXPlayer.StopGuiTimingBar(activator, "", -1);
                activator.IsBusy = false;
                activator.SetLocalInt(spellUUID, (int)SpellStatusType.Interrupted);
                activator.SendMessage("Your ability has been interrupted.");
                return;
            }

            _.DelayCommand(0.5f, () => { CheckForSpellInterruption(activator, spellUUID, position); });
        }
Esempio n. 4
0
        private void SalvagePageResponses(int responseID)
        {
            var player = GetPC();
            var model  = CraftService.GetPlayerCraftingData(player);

            switch (responseID)
            {
            case 1:     // Reassemble Component(s)

                NWItem fuel = _.GetItemPossessedBy(player, "ass_power");
                // Look for reassembly fuel in the player's inventory.
                if (!fuel.IsValid)
                {
                    player.SendMessage(ColorTokenService.Red("You must have a 'Reassembly Fuel Cell' in your inventory in order to start this process."));
                    return;
                }

                if (model.IsConfirmingReassemble)
                {
                    // Calculate delay, fire off delayed event, and show timing bar.
                    float delay = CraftService.CalculateCraftingDelay(player, (int)SkillType.Harvesting);
                    NWNXPlayer.StartGuiTimingBar(player, delay, string.Empty);
                    var @event = new OnReassembleComplete(player, model.SerializedSalvageItem, model.SalvageComponentTypeID);
                    player.DelayEvent(delay, @event);

                    // Make the player play an animation.
                    player.AssignCommand(() =>
                    {
                        _.ClearAllActions();
                        _.ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0f, delay);
                    });

                    // Show sparks halfway through the process.
                    _.DelayCommand(1.0f * (delay / 2.0f), () =>
                    {
                        _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_COM_BLOOD_SPARK_MEDIUM), NWGameObject.OBJECT_SELF);
                    });

                    // Immobilize the player while crafting.
                    Effect immobilize = _.EffectCutsceneImmobilize();
                    immobilize = _.TagEffect(immobilize, "CRAFTING_IMMOBILIZATION");
                    _.ApplyEffectToObject(DURATION_TYPE_PERMANENT, immobilize, player);

                    // Clear the temporary crafting data and end this conversation.
                    model.SerializedSalvageItem = string.Empty;
                    EndConversation();
                }
                else
                {
                    model.IsConfirmingReassemble = true;
                    SetResponseText("SalvagePage", 1, "CONFIRM REASSEMBLE COMPONENT(S)");
                }
                break;
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Initializes the casting process.
        /// </summary>
        /// <param name="stats"></param>
        private static void StartCasting(UserStats stats)
        {
            var castingTime = stats.AbilityDefinition.CastingTime(stats.User);

            NWNXPlayer.StartGuiTimingBar(stats.User, castingTime, string.Empty);

            SetIsBusy(stats.User, true);
            PlayAnimation(stats.User, stats.AbilityDefinition.Category);

            DelayCommand(0.5f, () => CheckMovement(stats));
            DelayCommand(castingTime, () => FinishCasting(stats));
        }
Esempio n. 6
0
        private static void InitializeHotBar(NWPlayer player)
        {
            var openRestMenu        = NWNXPlayerQuickBarSlot.UseFeat(Feat.OpenRestMenu);
            var structure           = NWNXPlayerQuickBarSlot.UseFeat(Feat.StructureManagementTool);
            var renameCraftedItem   = NWNXPlayerQuickBarSlot.UseFeat(Feat.RenameCraftedItem);
            var chatCommandTargeter = NWNXPlayerQuickBarSlot.UseFeat(Feat.ChatCommandTargeter);

            NWNXPlayer.SetQuickBarSlot(player, 0, openRestMenu);
            NWNXPlayer.SetQuickBarSlot(player, 1, structure);
            NWNXPlayer.SetQuickBarSlot(player, 2, renameCraftedItem);
            NWNXPlayer.SetQuickBarSlot(player, 3, chatCommandTargeter);
        }
Esempio n. 7
0
        private static void LoadMapProgression(NWArea area, NWPlayer player)
        {
            var map = DataService.PCMapProgression.GetByPlayerIDAndAreaResrefOrDefault(player.GlobalID, area.Resref);

            // No progression set - do a save which will create the record.
            if (map == null)
            {
                SaveMapProgression(area, player);
                return;
            }

            NWNXPlayer.SetAreaExplorationState(player, area, map.Progression);
        }
Esempio n. 8
0
        private void StartSmelt(NWPlaceable forge, NWPlayer pc, NWItem item)
        {
            int charges = forge.GetLocalInt("FORGE_CHARGES");

            if (item.Resref == "power_core")
            {
                item.Destroy();
                charges += 10 + CalculatePerkCoalBonusCharges(pc) + GetPowerCoreDurability(item) * 2;
                forge.SetLocalInt("FORGE_CHARGES", charges);

                NWPlaceable flames = (forge.GetLocalObject("FORGE_FLAMES"));
                if (!flames.IsValid)
                {
                    Vector   flamePosition = BiowarePosition.GetChangedPosition(forge.Position, 0.36f, forge.Facing);
                    Location flameLocation = _.Location(forge.Area.Object, flamePosition, 0.0f);
                    flames = (_.CreateObject(_.OBJECT_TYPE_PLACEABLE, "forge_flame", flameLocation));
                    forge.SetLocalObject("FORGE_FLAMES", flames.Object);
                }

                return;
            }
            else if (charges <= 0)
            {
                ReturnItemToPC(pc, item, "You must power the refinery with a power unit before refining.");
                return;
            }

            // Ready to smelt
            float baseCraftDelay = 18.0f - (18.0f * PerkService.GetCreaturePerkLevel(pc, PerkType.SpeedyRefining) * 0.1f);

            pc.IsBusy = true;
            NWNXPlayer.StartGuiTimingBar(pc, baseCraftDelay, string.Empty);

            // Any component bonuses on the ore get applied to the end product.
            var itemProperties = item.ItemProperties.Where(x =>
                                                           _.GetItemPropertyType(x) == (int)CustomItemPropertyType.ComponentBonus ||
                                                           _.GetItemPropertyType(x) == (int)CustomItemPropertyType.RecommendedLevel).ToList();

            string itemResref = item.Resref;

            var @event = new OnCompleteSmelt(pc, itemResref, itemProperties);

            pc.DelayEvent(baseCraftDelay, @event);

            _.ApplyEffectToObject(_.DURATION_TYPE_TEMPORARY, _.EffectCutsceneImmobilize(), pc.Object, baseCraftDelay);
            pc.AssignCommand(() => _.ActionPlayAnimation(_.ANIMATION_LOOPING_GET_MID, 1.0f, baseCraftDelay));
            item.Destroy();
        }
Esempio n. 9
0
        public static void CraftItem(NWPlayer oPC, NWPlaceable device)
        {
            var            model     = GetPlayerCraftingData(oPC);
            CraftBlueprint blueprint = DataService.Single <CraftBlueprint>(x => x.ID == model.BlueprintID);

            if (blueprint == null)
            {
                return;
            }

            if (oPC.IsBusy)
            {
                oPC.SendMessage("You are too busy right now.");
                return;
            }

            if (!model.CanBuildItem)
            {
                oPC.SendMessage("You are missing one or more components...");
                return;
            }

            oPC.IsBusy = true;

            float modifiedCraftDelay = CalculateCraftingDelay(oPC, blueprint.SkillID);

            oPC.AssignCommand(() =>
            {
                _.ClearAllActions();
                _.ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0f, modifiedCraftDelay);
            });
            _.DelayCommand(1.0f * (modifiedCraftDelay / 2.0f), () =>
            {
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_COM_BLOOD_SPARK_MEDIUM), device.Object);
            });
            Effect immobilize = _.EffectCutsceneImmobilize();

            immobilize = _.TagEffect(immobilize, "CRAFTING_IMMOBILIZATION");
            _.ApplyEffectToObject(DURATION_TYPE_PERMANENT, immobilize, oPC.Object);

            NWNXPlayer.StartGuiTimingBar(oPC, modifiedCraftDelay, "");

            oPC.DelayEvent <CraftCreateItem>(
                modifiedCraftDelay,
                oPC);
        }
Esempio n. 10
0
        public static void CraftItem(NWPlayer oPC, NWPlaceable device)
        {
            var            model     = GetPlayerCraftingData(oPC);
            CraftBlueprint blueprint = DataService.CraftBlueprint.GetByID(model.BlueprintID);

            if (blueprint == null)
            {
                return;
            }

            if (oPC.IsBusy)
            {
                oPC.SendMessage("You are too busy right now.");
                return;
            }

            if (!model.CanBuildItem)
            {
                oPC.SendMessage("You are missing one or more components...");
                return;
            }

            oPC.IsBusy = true;

            float modifiedCraftDelay = CalculateCraftingDelay(oPC, blueprint.SkillID);

            oPC.AssignCommand(() =>
            {
                _.ClearAllActions();
                _.ActionPlayAnimation(Animation.LoopingGetMid, 1.0f, modifiedCraftDelay);
            });
            _.DelayCommand(1.0f * (modifiedCraftDelay / 2.0f), () =>
            {
                _.ApplyEffectToObject(DurationType.Instant, _.EffectVisualEffect(VisualEffect.Vfx_Com_Blood_Spark_Medium), device.Object);
            });
            var immobilize = _.EffectCutsceneImmobilize();

            immobilize = _.TagEffect(immobilize, "CRAFTING_IMMOBILIZATION");
            _.ApplyEffectToObject(DurationType.Permanent, immobilize, oPC.Object);

            NWNXPlayer.StartGuiTimingBar(oPC, modifiedCraftDelay, "");

            var @event = new OnCreateCraftedItem(oPC);

            oPC.DelayEvent(modifiedCraftDelay, @event);
        }
Esempio n. 11
0
        private void SalvagePageResponses(int responseID)
        {
            var player = GetPC();
            var model  = CraftService.GetPlayerCraftingData(player);

            switch (responseID)
            {
            case 1:     // Reassemble Component(s)
                if (model.IsConfirmingReassemble)
                {
                    // Calculate delay, fire off delayed event, and show timing bar.
                    float delay = CraftService.CalculateCraftingDelay(player, (int)SkillType.Harvesting);
                    NWNXPlayer.StartGuiTimingBar(player, delay, string.Empty);
                    player.DelayEvent <ReassembleComplete>(delay, player, model.SerializedSalvageItem, model.SalvageComponentTypeID);

                    // Make the player play an animation.
                    player.AssignCommand(() =>
                    {
                        _.ClearAllActions();
                        _.ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0f, delay);
                    });

                    // Show sparks halfway through the process.
                    _.DelayCommand(1.0f * (delay / 2.0f), () =>
                    {
                        _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_COM_BLOOD_SPARK_MEDIUM), Object.OBJECT_SELF);
                    });

                    // Immobilize the player while crafting.
                    Effect immobilize = _.EffectCutsceneImmobilize();
                    immobilize = _.TagEffect(immobilize, "CRAFTING_IMMOBILIZATION");
                    _.ApplyEffectToObject(DURATION_TYPE_PERMANENT, immobilize, player);

                    // Clear the temporary crafting data and end this conversation.
                    model.SerializedSalvageItem = string.Empty;
                    EndConversation();
                }
                else
                {
                    model.IsConfirmingReassemble = true;
                    SetResponseText("SalvagePage", 1, "CONFIRM REASSEMBLE COMPONENT(S)");
                }
                break;
            }
        }
Esempio n. 12
0
        public static void Main()
        {
            var player = GetEnteringObject();

            if (!GetIsPlayer(player))
            {
                return;
            }

            var area        = GetArea(player);
            var areaResref  = GetResRef(area);
            var playerID    = GetGlobalID(player);
            var progression = MapProgressionRepo.Get(playerID, areaResref);

            if (!string.IsNullOrWhiteSpace(progression.Progression))
            {
                NWNXPlayer.SetAreaExplorationState(player, area, progression.Progression);
            }
        }
Esempio n. 13
0
        protected static void Recalculate(NWGameObject player)
        {
            var playerID      = GetGlobalID(player);
            var playerEntity  = PlayerRepo.Get(playerID);
            var @class        = GetClassByPosition(ClassPosition.First, player);
            var level         = GetLevelByPosition(ClassPosition.First, player);
            var jobDefinition = JobRegistry.Get(@class);

            // Retrieve the rating chart for the stat, then retrieve the value for that stat at this player's level.
            var hp  = RatingRegistry.Get(jobDefinition.HPRating).Get(RatingStat.HP, level);
            var mp  = RatingRegistry.Get(jobDefinition.MPRating).Get(RatingStat.MP, level);
            var ac  = RatingRegistry.Get(jobDefinition.ACRating).Get(RatingStat.AC, level);
            var bab = RatingRegistry.Get(jobDefinition.BABRating).Get(RatingStat.BAB, level);

            var str  = RatingRegistry.Get(jobDefinition.STRRating).Get(RatingStat.STR, level);
            var dex  = RatingRegistry.Get(jobDefinition.DEXRating).Get(RatingStat.DEX, level);
            var con  = RatingRegistry.Get(jobDefinition.CONRating).Get(RatingStat.CON, level);
            var wis  = RatingRegistry.Get(jobDefinition.WISRating).Get(RatingStat.WIS, level);
            var @int = RatingRegistry.Get(jobDefinition.INTRating).Get(RatingStat.INT, level);
            var cha  = RatingRegistry.Get(jobDefinition.CHARating).Get(RatingStat.CHA, level);


            // Now apply the changes to the player.
            ApplyHP(player, hp);
            playerEntity.MaxHP = hp;
            playerEntity.MaxMP = mp;
            playerEntity.HP    = hp;
            playerEntity.MP    = mp;

            NWNXCreature.SetBaseAC(player, ac);
            NWNXCreature.SetBaseAttackBonus(player, bab);

            NWNXCreature.SetRawAbilityScore(player, Ability.Strength, str);
            NWNXCreature.SetRawAbilityScore(player, Ability.Dexterity, dex);
            NWNXCreature.SetRawAbilityScore(player, Ability.Constitution, con);
            NWNXCreature.SetRawAbilityScore(player, Ability.Wisdom, wis);
            NWNXCreature.SetRawAbilityScore(player, Ability.Intelligence, @int);
            NWNXCreature.SetRawAbilityScore(player, Ability.Charisma, cha);

            PlayerRepo.Set(playerEntity);
            DelayCommand(1.0f, () => NWNXPlayer.UpdateCharacterSheet(player));
        }
Esempio n. 14
0
        private static void SaveMapProgression(NWArea area, NWPlayer player)
        {
            var map = DataService.PCMapProgression.GetByPlayerIDAndAreaResrefOrDefault(player.GlobalID, area.Resref);
            DatabaseActionType action = DatabaseActionType.Update;

            if (map == null)
            {
                map = new PCMapProgression
                {
                    PlayerID    = player.GlobalID,
                    AreaResref  = area.Resref,
                    Progression = string.Empty
                };

                action = DatabaseActionType.Insert;
            }

            map.Progression = NWNXPlayer.GetAreaExplorationState(player, area);
            DataService.SubmitDataChange(map, action);
        }
Esempio n. 15
0
        private static void ActivateAbility(
            NWCreature activator,
            NWObject target,
            Data.Entity.Perk entity,
            IPerkHandler perkHandler,
            int pcPerkLevel,
            PerkExecutionType executionType,
            int spellTier)
        {
            string uuid = Guid.NewGuid().ToString();
            float  baseActivationTime = perkHandler.CastingTime(activator, (float)entity.BaseCastingTime, spellTier);
            float  activationTime     = baseActivationTime;
            var    vfxID       = VisualEffect.Invalid;
            var    animationID = Animation.Invalid;

            if (baseActivationTime > 0f && activationTime < 1.0f)
            {
                activationTime = 1.0f;
            }

            // Force ability armor penalties
            float armorPenalty = 0.0f;

            if (executionType == PerkExecutionType.ForceAbility ||
                executionType == PerkExecutionType.ConcentrationAbility)
            {
                string penaltyMessage = string.Empty;
                foreach (var item in activator.EquippedItems)
                {
                    if (item.CustomItemType == CustomItemType.HeavyArmor)
                    {
                        armorPenalty   = 2;
                        penaltyMessage = "Heavy armor slows your force cooldown by 100%.";
                        break;
                    }
                    else if (item.CustomItemType == CustomItemType.LightArmor)
                    {
                        armorPenalty   = 1.25f;
                        penaltyMessage = "Light armor slows your force cooldown by 25%.";
                    }
                }

                // If there's an armor penalty, send a message to the player.
                if (armorPenalty > 0.0f)
                {
                    activator.SendMessage(penaltyMessage);
                }
            }

            // If player is in stealth mode, force them out of stealth mode.
            if (_.GetActionMode(activator.Object, ActionMode.Stealth))
            {
                _.SetActionMode(activator.Object, ActionMode.Stealth, false);
            }

            // Make the player face their target.
            _.ClearAllActions();
            BiowarePosition.TurnToFaceObject(target, activator);

            // Force and Concentration Abilities will display a visual effect during the casting process.
            if (executionType == PerkExecutionType.ForceAbility ||
                executionType == PerkExecutionType.ConcentrationAbility)
            {
                vfxID       = VisualEffect.Vfx_Dur_Iounstone_Yellow;
                animationID = Animation.LoopingConjure1;
            }

            if (executionType == PerkExecutionType.ConcentrationAbility)
            {
                activator.SetLocalObject("CONCENTRATION_TARGET", target);
            }

            // If a VFX ID has been specified, play that effect instead of the default one.
            if (vfxID != VisualEffect.Invalid)
            {
                var vfx = _.EffectVisualEffect(vfxID);
                vfx = _.TagEffect(vfx, "ACTIVATION_VFX");
                _.ApplyEffectToObject(DurationType.Temporary, vfx, activator.Object, activationTime + 0.2f);
            }

            // If an animation has been specified, make the player play that animation now.
            // bypassing if perk is throw saber due to couldn't get the animation to work via db table edit
            if (animationID != Animation.Invalid && entity.ID != (int)PerkType.ThrowSaber)
            {
                activator.AssignCommand(() => _.ActionPlayAnimation(animationID, 1.0f, activationTime - 0.1f));
            }

            // Mark player as busy. Busy players can't take other actions (crafting, harvesting, etc.)
            activator.IsBusy = true;

            // Non-players can't be interrupted via movement.
            if (!activator.IsPlayer)
            {
                // Begin the check for spell interruption. If the activator moves, the spell will be canceled.
                CheckForSpellInterruption(activator, uuid, activator.Position);
            }

            activator.SetLocalInt(uuid, (int)SpellStatusType.Started);

            // If there's a casting delay, display a timing bar on-screen.
            if (activationTime > 0)
            {
                NWNXPlayer.StartGuiTimingBar(activator, (int)activationTime, string.Empty);
            }

            // Run the FinishAbilityUse event at the end of the activation time.
            int perkID = entity.ID;

            var @event = new OnFinishAbilityUse(activator, uuid, perkID, target, pcPerkLevel, spellTier, armorPenalty);

            activator.DelayEvent(activationTime + 0.2f, @event);
        }
Esempio n. 16
0
        public static void ApplyStatChanges(NWPlayer player, NWItem ignoreItem, bool isInitialization = false)
        {
            if (!player.IsPlayer)
            {
                return;
            }
            if (!player.IsInitializedAsPlayer)
            {
                return;
            }
            if (player.GetLocalInt("IS_SHIP") == 1)
            {
                return;
            }

            // Don't fire for ammo as it reapplies bonuses **just** removed from blasters.
            if (ignoreItem != null &&
                (ignoreItem.BaseItemType == BASE_ITEM_BOLT ||
                 ignoreItem.BaseItemType == BASE_ITEM_ARROW ||
                 ignoreItem.BaseItemType == BASE_ITEM_BULLET))
            {
                return;
            }

            Player             pcEntity    = DataService.Get <Player>(player.GlobalID);
            List <PCSkill>     skills      = DataService.Where <PCSkill>(x => x.PlayerID == player.GlobalID && x.Rank > 0).ToList();
            EffectiveItemStats itemBonuses = GetPlayerItemEffectiveStats(player, ignoreItem);

            float strBonus = 0.0f;
            float dexBonus = 0.0f;
            float conBonus = 0.0f;
            float intBonus = 0.0f;
            float wisBonus = 0.0f;
            float chaBonus = 0.0f;

            using (new Profiler("PlayerStatService::ApplyStatChanges::AttributeApplication"))
            {
                foreach (PCSkill pcSkill in skills)
                {
                    Skill           skill     = DataService.Get <Skill>(pcSkill.SkillID);
                    CustomAttribute primary   = (CustomAttribute)skill.Primary;
                    CustomAttribute secondary = (CustomAttribute)skill.Secondary;
                    CustomAttribute tertiary  = (CustomAttribute)skill.Tertiary;

                    // Primary Bonuses
                    if (primary == CustomAttribute.STR)
                    {
                        strBonus += PrimaryIncrease * pcSkill.Rank;
                    }
                    else if (primary == CustomAttribute.DEX)
                    {
                        dexBonus += PrimaryIncrease * pcSkill.Rank;
                    }
                    else if (primary == CustomAttribute.CON)
                    {
                        conBonus += PrimaryIncrease * pcSkill.Rank;
                    }
                    else if (primary == CustomAttribute.INT)
                    {
                        intBonus += PrimaryIncrease * pcSkill.Rank;
                    }
                    else if (primary == CustomAttribute.WIS)
                    {
                        wisBonus += PrimaryIncrease * pcSkill.Rank;
                    }
                    else if (primary == CustomAttribute.CHA)
                    {
                        chaBonus += PrimaryIncrease * pcSkill.Rank;
                    }

                    // Secondary Bonuses
                    if (secondary == CustomAttribute.STR)
                    {
                        strBonus += SecondaryIncrease * pcSkill.Rank;
                    }
                    else if (secondary == CustomAttribute.DEX)
                    {
                        dexBonus += SecondaryIncrease * pcSkill.Rank;
                    }
                    else if (secondary == CustomAttribute.CON)
                    {
                        conBonus += SecondaryIncrease * pcSkill.Rank;
                    }
                    else if (secondary == CustomAttribute.INT)
                    {
                        intBonus += SecondaryIncrease * pcSkill.Rank;
                    }
                    else if (secondary == CustomAttribute.WIS)
                    {
                        wisBonus += SecondaryIncrease * pcSkill.Rank;
                    }
                    else if (secondary == CustomAttribute.CHA)
                    {
                        chaBonus += SecondaryIncrease * pcSkill.Rank;
                    }

                    // Tertiary Bonuses
                    if (tertiary == CustomAttribute.STR)
                    {
                        strBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                    else if (tertiary == CustomAttribute.DEX)
                    {
                        dexBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                    else if (tertiary == CustomAttribute.CON)
                    {
                        conBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                    else if (tertiary == CustomAttribute.INT)
                    {
                        intBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                    else if (tertiary == CustomAttribute.WIS)
                    {
                        wisBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                    else if (tertiary == CustomAttribute.CHA)
                    {
                        chaBonus += TertiaryIncrease * pcSkill.Rank;
                    }
                }
            }


            // Check caps.
            if (strBonus > MaxAttributeBonus)
            {
                strBonus = MaxAttributeBonus;
            }
            if (dexBonus > MaxAttributeBonus)
            {
                dexBonus = MaxAttributeBonus;
            }
            if (conBonus > MaxAttributeBonus)
            {
                conBonus = MaxAttributeBonus;
            }
            if (intBonus > MaxAttributeBonus)
            {
                intBonus = MaxAttributeBonus;
            }
            if (wisBonus > MaxAttributeBonus)
            {
                wisBonus = MaxAttributeBonus;
            }
            if (chaBonus > MaxAttributeBonus)
            {
                chaBonus = MaxAttributeBonus;
            }

            // Apply item bonuses
            strBonus += itemBonuses.Strength / 3;
            dexBonus += itemBonuses.Dexterity / 3;
            conBonus += itemBonuses.Constitution / 3;
            wisBonus += itemBonuses.Wisdom / 3;
            intBonus += itemBonuses.Intelligence / 3;
            chaBonus += itemBonuses.Charisma / 3;

            // Check final caps
            if (strBonus > 55)
            {
                strBonus = 55;
            }
            if (dexBonus > 55)
            {
                dexBonus = 55;
            }
            if (conBonus > 55)
            {
                conBonus = 55;
            }
            if (intBonus > 55)
            {
                intBonus = 55;
            }
            if (wisBonus > 55)
            {
                wisBonus = 55;
            }
            if (chaBonus > 55)
            {
                chaBonus = 55;
            }

            // Apply attributes
            NWNXCreature.SetRawAbilityScore(player, ABILITY_STRENGTH, (int)strBonus + pcEntity.STRBase);
            NWNXCreature.SetRawAbilityScore(player, ABILITY_DEXTERITY, (int)dexBonus + pcEntity.DEXBase);
            NWNXCreature.SetRawAbilityScore(player, ABILITY_CONSTITUTION, (int)conBonus + pcEntity.CONBase);
            NWNXCreature.SetRawAbilityScore(player, ABILITY_INTELLIGENCE, (int)intBonus + pcEntity.INTBase);
            NWNXCreature.SetRawAbilityScore(player, ABILITY_WISDOM, (int)wisBonus + pcEntity.WISBase);
            NWNXCreature.SetRawAbilityScore(player, ABILITY_CHARISMA, (int)chaBonus + pcEntity.CHABase);

            // Apply AC
            using (new Profiler("PlayerStatService::ApplyStatChanges::CalcAC"))
            {
                int ac = EffectiveArmorClass(itemBonuses, player);
                NWNXCreature.SetBaseAC(player, ac);
            }

            // Apply BAB
            using (new Profiler("PlayerStatService::ApplyStatChanges::CalcBAB"))
            {
                int bab = CalculateBAB(player, ignoreItem, itemBonuses);
                NWNXCreature.SetBaseAttackBonus(player, bab);
            }

            // Apply HP
            using (new Profiler("PlayerStatService::ApplyStatChanges::CalcHP"))
            {
                int hp = EffectiveMaxHitPoints(player, itemBonuses);
                for (int level = 1; level <= 5; level++)
                {
                    hp--;
                    NWNXCreature.SetMaxHitPointsByLevel(player, level, 1);
                }

                for (int level = 1; level <= 5; level++)
                {
                    if (hp > 255) // Levels can only contain a max of 255 HP
                    {
                        NWNXCreature.SetMaxHitPointsByLevel(player, level, 255);
                        hp = hp - 254;
                    }
                    else // Remaining value gets set to the level. (<255 hp)
                    {
                        NWNXCreature.SetMaxHitPointsByLevel(player, level, hp + 1);
                        break;
                    }
                }
            }

            if (player.CurrentHP > player.MaxHP)
            {
                int    amount = player.CurrentHP - player.MaxHP;
                Effect damage = _.EffectDamage(amount);
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, damage, player.Object);
            }

            // Apply FP
            using (new Profiler("PlayerStatService::ApplyStatChanges::CalcFP"))
            {
                pcEntity.MaxFP = EffectiveMaxFP(player, itemBonuses);

                if (isInitialization)
                {
                    pcEntity.CurrentFP = pcEntity.MaxFP;
                }

                DataService.SubmitDataChange(pcEntity, DatabaseActionType.Update);
            }

            // Attempt a refresh of the character sheet UI in a second.
            _.DelayCommand(1.0f, () =>
            {
                NWNXPlayer.UpdateCharacterSheet(player);
            });
        }
Esempio n. 17
0
        public static void DoPerkUpgrade(NWPlayer oPC, int perkID, bool freeUpgrade = false)
        {
            var perk       = DataService.Single <Data.Entity.Perk>(x => x.ID == perkID);
            var perkLevels = DataService.Where <PerkLevel>(x => x.PerkID == perkID);
            var pcPerk     = DataService.SingleOrDefault <PCPerk>(x => x.PlayerID == oPC.GlobalID && x.PerkID == perkID);
            var player     = DataService.Single <Player>(x => x.ID == oPC.GlobalID);

            if (freeUpgrade || CanPerkBeUpgraded(oPC, perkID))
            {
                DatabaseActionType action = DatabaseActionType.Update;
                if (pcPerk == null)
                {
                    pcPerk = new PCPerk();
                    DateTime dt = DateTime.UtcNow;
                    pcPerk.AcquiredDate = dt;
                    pcPerk.PerkID       = perk.ID;
                    pcPerk.PlayerID     = oPC.GlobalID;
                    pcPerk.PerkLevel    = 0;

                    action = DatabaseActionType.Insert;
                }

                PerkLevel nextPerkLevel = FindPerkLevel(perkLevels, pcPerk.PerkLevel + 1);
                if (nextPerkLevel == null)
                {
                    return;
                }

                pcPerk.PerkLevel++;
                DataService.SubmitDataChange(pcPerk, action);

                if (!freeUpgrade)
                {
                    player.UnallocatedSP -= nextPerkLevel.Price;
                    DataService.SubmitDataChange(player, DatabaseActionType.Update);
                }

                // Look for any perk levels to grant.
                var perkFeatsToGrant = DataService.Where <PerkFeat>(x => x.PerkID == perkID && x.PerkLevelUnlocked == pcPerk.PerkLevel);

                // If at least one feat ID is assigned, add the feat(s) to the player if it doesn't exist yet.
                if (perkFeatsToGrant.Count > 0)
                {
                    foreach (var perkFeat in perkFeatsToGrant)
                    {
                        if (_.GetHasFeat(perkFeat.FeatID, oPC.Object) == TRUE)
                        {
                            continue;
                        }

                        NWNXCreature.AddFeatByLevel(oPC, perkFeat.FeatID, 1);

                        var qbs = NWNXPlayerQuickBarSlot.UseFeat(perkFeat.FeatID);

                        // Try to add the new feat to the player's hotbar.
                        if (NWNXPlayer.GetQuickBarSlot(oPC, 0).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 0, qbs);
                        }
                        else if (NWNXPlayer.GetQuickBarSlot(oPC, 1).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 1, qbs);
                        }
                        else if (NWNXPlayer.GetQuickBarSlot(oPC, 2).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 2, qbs);
                        }
                        else if (NWNXPlayer.GetQuickBarSlot(oPC, 3).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 3, qbs);
                        }
                        else if (NWNXPlayer.GetQuickBarSlot(oPC, 4).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 4, qbs);
                        }
                        else if (NWNXPlayer.GetQuickBarSlot(oPC, 5).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 5, qbs);
                        }
                        else if (NWNXPlayer.GetQuickBarSlot(oPC, 6).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 6, qbs);
                        }
                        else if (NWNXPlayer.GetQuickBarSlot(oPC, 7).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 7, qbs);
                        }
                        else if (NWNXPlayer.GetQuickBarSlot(oPC, 8).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 8, qbs);
                        }
                        else if (NWNXPlayer.GetQuickBarSlot(oPC, 9).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 9, qbs);
                        }
                        else if (NWNXPlayer.GetQuickBarSlot(oPC, 10).ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(oPC, 10, qbs);
                        }
                    }
                }

                oPC.SendMessage(ColorTokenService.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")"));

                var handler = GetPerkHandler(perkID);
                handler.OnPurchased(oPC, pcPerk.PerkLevel);
                MessageHub.Instance.Publish(new PerkUpgradedMessage(oPC, perkID));
            }
            else
            {
                oPC.FloatingText(ColorTokenService.Red("You cannot purchase the perk at this time."));
            }
        }
Esempio n. 18
0
        private static void OnModuleNWNXChat()
        {
            NWPlayer sender          = Object.OBJECT_SELF;
            string   originalMessage = NWNXChat.GetMessage().Trim();

            if (!CanHandleChat(sender, originalMessage))
            {
                return;
            }

            var split = originalMessage.Split(' ').ToList();

            // Commands with no arguments won't be split, so if we didn't split anything then add the command to the split list manually.
            if (split.Count <= 0)
            {
                split.Add(originalMessage);
            }

            split[0] = split[0].ToLower();
            string command = split[0].Substring(1, split[0].Length - 1);

            split.RemoveAt(0);

            NWNXChat.SkipMessage();

            if (!IsChatCommandRegistered(command))
            {
                sender.SendMessage(ColorTokenService.Red("Invalid chat command. Use '/help' to get a list of available commands."));
                return;
            }

            IChatCommand chatCommand = GetChatCommandHandler(command);
            string       args        = string.Join(" ", split);

            if (!chatCommand.RequiresTarget)
            {
                ProcessChatCommand(chatCommand, sender, null, null, args);
            }
            else
            {
                string error = chatCommand.ValidateArguments(sender, split.ToArray());
                if (!string.IsNullOrWhiteSpace(error))
                {
                    sender.SendMessage(error);
                    return;
                }

                sender.SetLocalString("CHAT_COMMAND", command);
                sender.SetLocalString("CHAT_COMMAND_ARGS", args);
                sender.SendMessage("Please use your 'Chat Command Targeter' feat to select the target of this chat command.");

                if (_.GetHasFeat((int)CustomFeatType.ChatCommandTargeter, sender) == FALSE || sender.IsDM)
                {
                    NWNXCreature.AddFeatByLevel(sender, (int)CustomFeatType.ChatCommandTargeter, 1);

                    if (sender.IsDM)
                    {
                        var qbs = NWNXPlayer.GetQuickBarSlot(sender, 11);
                        if (qbs.ObjectType == QuickBarSlotType.Empty)
                        {
                            NWNXPlayer.SetQuickBarSlot(sender, 11, NWNXPlayerQuickBarSlot.UseFeat((int)CustomFeatType.ChatCommandTargeter));
                        }
                    }
                }
            }
        }
Esempio n. 19
0
        private static void ActivateAbility(NWPlayer pc,
                                            NWObject target,
                                            Data.Entity.Perk entity,
                                            IPerkHandler perkHandler,
                                            int pcPerkLevel,
                                            PerkExecutionType executionType,
                                            int spellFeatID)
        {
            string uuid               = Guid.NewGuid().ToString();
            var    effectiveStats     = PlayerStatService.GetPlayerItemEffectiveStats(pc);
            int    itemBonus          = effectiveStats.CastingSpeed;
            float  baseActivationTime = perkHandler.CastingTime(pc, (float)entity.BaseCastingTime, spellFeatID);
            float  activationTime     = baseActivationTime;
            int    vfxID              = -1;
            int    animationID        = -1;

            // Activation Bonus % - Shorten activation time.
            if (itemBonus > 0)
            {
                float activationBonus = Math.Abs(itemBonus) * 0.01f;
                activationTime = activationTime - activationTime * activationBonus;
            }
            // Activation Penalty % - Increase activation time.
            else if (itemBonus < 0)
            {
                float activationPenalty = Math.Abs(itemBonus) * 0.01f;
                activationTime = activationTime + activationTime * activationPenalty;
            }

            if (baseActivationTime > 0f && activationTime < 1.0f)
            {
                activationTime = 1.0f;
            }

            // Force ability armor penalties
            if (executionType == PerkExecutionType.ForceAbility)
            {
                float  armorPenalty   = 0.0f;
                string penaltyMessage = string.Empty;
                foreach (var item in pc.EquippedItems)
                {
                    if (item.CustomItemType == CustomItemType.HeavyArmor)
                    {
                        armorPenalty   = 2;
                        penaltyMessage = "Heavy armor slows your force activation speed by 100%.";
                        break;
                    }
                    else if (item.CustomItemType == CustomItemType.LightArmor)
                    {
                        armorPenalty   = 1.25f;
                        penaltyMessage = "Light armor slows your force activation speed by 25%.";
                    }
                }

                if (armorPenalty > 0.0f)
                {
                    activationTime = baseActivationTime * armorPenalty;
                    pc.SendMessage(penaltyMessage);
                }
            }

            if (_.GetActionMode(pc.Object, ACTION_MODE_STEALTH) == 1)
            {
                _.SetActionMode(pc.Object, ACTION_MODE_STEALTH, 0);
            }

            _.ClearAllActions();
            BiowarePosition.TurnToFaceObject(target, pc);

            if (executionType == PerkExecutionType.ForceAbility)
            {
                vfxID       = VFX_DUR_IOUNSTONE_YELLOW;
                animationID = ANIMATION_LOOPING_CONJURE1;
            }

            if (vfxID > -1)
            {
                var vfx = _.EffectVisualEffect(vfxID);
                vfx = _.TagEffect(vfx, "ACTIVATION_VFX");
                _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, vfx, pc.Object, activationTime + 0.2f);
            }

            if (animationID > -1)
            {
                pc.AssignCommand(() => _.ActionPlayAnimation(animationID, 1.0f, activationTime - 0.1f));
            }

            pc.IsBusy = true;
            CheckForSpellInterruption(pc, uuid, pc.Position);
            pc.SetLocalInt(uuid, (int)SpellStatusType.Started);

            NWNXPlayer.StartGuiTimingBar(pc, (int)activationTime, "");

            int perkID = entity.ID;

            pc.DelayEvent <FinishAbilityUse>(activationTime + 0.2f,
                                             pc,
                                             uuid,
                                             perkID,
                                             target,
                                             pcPerkLevel,
                                             spellFeatID);
        }
Esempio n. 20
0
        private static void OnItemUsed()
        {
            NWPlayer user            = _.OBJECT_SELF;
            NWItem   oItem           = _.StringToObject(NWNXEvents.GetEventData("ITEM_OBJECT_ID"));
            NWObject target          = _.StringToObject(NWNXEvents.GetEventData("TARGET_OBJECT_ID"));
            var      targetPositionX = (float)Convert.ToDouble(NWNXEvents.GetEventData("TARGET_POSITION_X"));
            var      targetPositionY = (float)Convert.ToDouble(NWNXEvents.GetEventData("TARGET_POSITION_Y"));
            var      targetPositionZ = (float)Convert.ToDouble(NWNXEvents.GetEventData("TARGET_POSITION_Z"));
            var      targetPosition  = Vector3(targetPositionX, targetPositionY, targetPositionZ);
            Location targetLocation  = Location(user.Area, targetPosition, 0.0f);

            string className = oItem.GetLocalString("SCRIPT");

            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("ACTIVATE_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("ACTION_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("SCRIPT");
            }
            // Legacy events follow. We can't remove these because of backwards compatibility issues with existing items.
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("JAVA_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("ACTIVATE_JAVA_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("JAVA_ACTION_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                return;
            }

            // Bypass the NWN "item use" animation.
            NWNXEvents.SkipEvent();

            user.ClearAllActions();

            if (user.IsBusy)
            {
                user.SendMessage("You are busy.");
                return;
            }

            // Remove "Item." prefix if it exists.
            if (className.StartsWith("Item."))
            {
                className = className.Substring(5);
            }
            IActionItem item = GetActionItemHandler(className);

            string invalidTargetMessage = item.IsValidTarget(user, oItem, target, targetLocation);

            if (!string.IsNullOrWhiteSpace(invalidTargetMessage))
            {
                user.SendMessage(invalidTargetMessage);
                return;
            }

            // NOTE - these checks are duplicated in FinishActionItem.  Keep both in sync.
            float maxDistance = item.MaxDistance(user, oItem, target, targetLocation);

            if (maxDistance > 0.0f)
            {
                NWObject owner = GetItemPossessor(target);

                if (target.IsValid && owner.IsValid)
                {
                    // We are okay - we have targeted an item in our inventory (we can't target someone
                    // else's inventory, so no need to actually check distance).
                }
                else if (target.Object == _.OBJECT_SELF)
                {
                    // Also okay.
                }
                else if (target.IsValid &&
                         (GetDistanceBetween(user.Object, target.Object) > maxDistance ||
                          user.Area.Resref != target.Area.Resref))
                {
                    user.SendMessage("Your target is too far away.");
                    return;
                }
                else if (!target.IsValid &&
                         (GetDistanceBetweenLocations(user.Location, targetLocation) > maxDistance ||
                          user.Area.Resref != ((NWArea)GetAreaFromLocation(targetLocation)).Resref))
                {
                    user.SendMessage("That location is too far away.");
                    return;
                }
            }

            CustomData customData   = item.StartUseItem(user, oItem, target, targetLocation);
            float      delay        = item.Seconds(user, oItem, target, targetLocation, customData);
            var        animationID  = item.AnimationID();
            bool       faceTarget   = item.FaceTarget();
            Vector3    userPosition = user.Position;

            user.AssignCommand(() =>
            {
                user.IsBusy = true;
                if (faceTarget)
                {
                    SetFacingPoint(!target.IsValid ? GetPositionFromLocation(targetLocation) : target.Position);
                }
                if (animationID > 0)
                {
                    ActionPlayAnimation(animationID, 1.0f, delay);
                }
            });

            if (delay > 0.0f)
            {
                NWNXPlayer.StartGuiTimingBar(user, delay, string.Empty);
            }

            var @event = new OnFinishActionItem(className, user, oItem, target, targetLocation, userPosition, customData);

            user.DelayEvent(delay, @event);
        }
Esempio n. 21
0
        public static void ApplyStatChanges(NWPlayer player, NWItem ignoreItem, bool isInitialization = false)
        {
            if (!player.IsPlayer)
            {
                return;
            }
            if (!player.IsInitializedAsPlayer)
            {
                return;
            }
            if (player.GetLocalInt("IS_SHIP") == 1)
            {
                return;
            }

            // Don't fire for ammo as it reapplies bonuses we **just** removed from blasters.
            if (ignoreItem != null &&
                (ignoreItem.BaseItemType == BaseItem.Bolt ||
                 ignoreItem.BaseItemType == BaseItem.Arrow ||
                 ignoreItem.BaseItemType == BaseItem.Bullet))
            {
                return;
            }

            Player         pcEntity = DataService.Player.GetByID(player.GlobalID);
            List <PCSkill> skills   = DataService.PCSkill
                                      .GetAllByPlayerID(player.GlobalID)
                                      .Where(x => x.Rank > 0).ToList();
            EffectiveItemStats itemBonuses = GetPlayerItemEffectiveStats(player, ignoreItem);

            float strBonus = 0.0f;
            float dexBonus = 0.0f;
            float conBonus = 0.0f;
            float intBonus = 0.0f;
            float wisBonus = 0.0f;
            float chaBonus = 0.0f;

            foreach (PCSkill pcSkill in skills)
            {
                Skill           skill     = DataService.Skill.GetByID(pcSkill.SkillID);
                CustomAttribute primary   = (CustomAttribute)skill.Primary;
                CustomAttribute secondary = (CustomAttribute)skill.Secondary;
                CustomAttribute tertiary  = (CustomAttribute)skill.Tertiary;

                // Primary Bonuses
                if (primary == CustomAttribute.STR)
                {
                    strBonus += PrimaryIncrease * pcSkill.Rank;
                }
                else if (primary == CustomAttribute.DEX)
                {
                    dexBonus += PrimaryIncrease * pcSkill.Rank;
                }
                else if (primary == CustomAttribute.CON)
                {
                    conBonus += PrimaryIncrease * pcSkill.Rank;
                }
                else if (primary == CustomAttribute.INT)
                {
                    intBonus += PrimaryIncrease * pcSkill.Rank;
                }
                else if (primary == CustomAttribute.WIS)
                {
                    wisBonus += PrimaryIncrease * pcSkill.Rank;
                }
                else if (primary == CustomAttribute.CHA)
                {
                    chaBonus += PrimaryIncrease * pcSkill.Rank;
                }

                // Secondary Bonuses
                if (secondary == CustomAttribute.STR)
                {
                    strBonus += SecondaryIncrease * pcSkill.Rank;
                }
                else if (secondary == CustomAttribute.DEX)
                {
                    dexBonus += SecondaryIncrease * pcSkill.Rank;
                }
                else if (secondary == CustomAttribute.CON)
                {
                    conBonus += SecondaryIncrease * pcSkill.Rank;
                }
                else if (secondary == CustomAttribute.INT)
                {
                    intBonus += SecondaryIncrease * pcSkill.Rank;
                }
                else if (secondary == CustomAttribute.WIS)
                {
                    wisBonus += SecondaryIncrease * pcSkill.Rank;
                }
                else if (secondary == CustomAttribute.CHA)
                {
                    chaBonus += SecondaryIncrease * pcSkill.Rank;
                }

                // Tertiary Bonuses
                if (tertiary == CustomAttribute.STR)
                {
                    strBonus += TertiaryIncrease * pcSkill.Rank;
                }
                else if (tertiary == CustomAttribute.DEX)
                {
                    dexBonus += TertiaryIncrease * pcSkill.Rank;
                }
                else if (tertiary == CustomAttribute.CON)
                {
                    conBonus += TertiaryIncrease * pcSkill.Rank;
                }
                else if (tertiary == CustomAttribute.INT)
                {
                    intBonus += TertiaryIncrease * pcSkill.Rank;
                }
                else if (tertiary == CustomAttribute.WIS)
                {
                    wisBonus += TertiaryIncrease * pcSkill.Rank;
                }
                else if (tertiary == CustomAttribute.CHA)
                {
                    chaBonus += TertiaryIncrease * pcSkill.Rank;
                }
            }

            // Check caps.
            if (strBonus > MaxAttributeBonus)
            {
                strBonus = MaxAttributeBonus;
            }
            if (dexBonus > MaxAttributeBonus)
            {
                dexBonus = MaxAttributeBonus;
            }
            if (conBonus > MaxAttributeBonus)
            {
                conBonus = MaxAttributeBonus;
            }
            if (intBonus > MaxAttributeBonus)
            {
                intBonus = MaxAttributeBonus;
            }
            if (wisBonus > MaxAttributeBonus)
            {
                wisBonus = MaxAttributeBonus;
            }
            if (chaBonus > MaxAttributeBonus)
            {
                chaBonus = MaxAttributeBonus;
            }

            // Apply item bonuses
            strBonus += itemBonuses.Strength;
            dexBonus += itemBonuses.Dexterity;
            conBonus += itemBonuses.Constitution;
            wisBonus += itemBonuses.Wisdom;
            intBonus += itemBonuses.Intelligence;
            chaBonus += itemBonuses.Charisma;

            // Check final caps
            if (strBonus > 55)
            {
                strBonus = 55;
            }
            if (dexBonus > 55)
            {
                dexBonus = 55;
            }
            if (conBonus > 55)
            {
                conBonus = 55;
            }
            if (intBonus > 55)
            {
                intBonus = 55;
            }
            if (wisBonus > 55)
            {
                wisBonus = 55;
            }
            if (chaBonus > 55)
            {
                chaBonus = 55;
            }

            // Apply attributes
            NWNXCreature.SetRawAbilityScore(player, AbilityType.Strength, (int)strBonus + pcEntity.STRBase);
            NWNXCreature.SetRawAbilityScore(player, AbilityType.Dexterity, (int)dexBonus + pcEntity.DEXBase);
            NWNXCreature.SetRawAbilityScore(player, AbilityType.Constitution, (int)conBonus + pcEntity.CONBase);
            NWNXCreature.SetRawAbilityScore(player, AbilityType.Intelligence, (int)intBonus + pcEntity.INTBase);
            NWNXCreature.SetRawAbilityScore(player, AbilityType.Wisdom, (int)wisBonus + pcEntity.WISBase);
            NWNXCreature.SetRawAbilityScore(player, AbilityType.Charisma, (int)chaBonus + pcEntity.CHABase);

            // Apply AC
            int ac = EffectiveArmorClass(player, ignoreItem, itemBonuses);

            NWNXCreature.SetBaseAC(player, ac);

            // Apply BAB
            int bab = CalculateBAB(player, ignoreItem, itemBonuses);

            NWNXCreature.SetBaseAttackBonus(player, bab);

            // Apply HP
            int hp = EffectiveMaxHitPoints(player, itemBonuses);

            for (int level = 1; level <= 5; level++)
            {
                hp--;
                NWNXCreature.SetMaxHitPointsByLevel(player, level, 1);
            }

            for (int level = 1; level <= 5; level++)
            {
                if (hp >= 255) // Levels can only contain a max of 255 HP
                {
                    NWNXCreature.SetMaxHitPointsByLevel(player, level, 255);
                    hp = hp - 254;
                }
                else // Remaining value gets set to the level. (<255 hp)
                {
                    NWNXCreature.SetMaxHitPointsByLevel(player, level, hp + 1);
                    break;
                }
            }

            if (player.CurrentHP > player.MaxHP)
            {
                int amount = player.CurrentHP - player.MaxHP;
                var damage = _.EffectDamage(amount);
                _.ApplyEffectToObject(DurationType.Instant, damage, player.Object);
            }

            // Apply FP
            pcEntity.MaxFP = EffectiveMaxFP(player, itemBonuses);

            if (isInitialization)
            {
                pcEntity.CurrentFP = pcEntity.MaxFP;
            }

            DataService.SubmitDataChange(pcEntity, DatabaseActionType.Update);

            // Attempt a refresh of the character sheet UI in a second.
            _.DelayCommand(1.0f, () =>
            {
                NWNXPlayer.UpdateCharacterSheet(player);
            });
        }
Esempio n. 22
0
        /// <summary>
        /// Performs a perk purchase for a player. This handles deducting SP, inserting perk records,
        /// and adjusting hotbar slots as necessary.
        /// </summary>
        /// <param name="oPC">The player receiving the perk upgrade.</param>
        /// <param name="perkID">The ID number of the perk.</param>
        /// <param name="freeUpgrade">If true, no SP will be deducted. Otherwise, SP will be deducted from player.</param>
        public static void DoPerkUpgrade(NWPlayer oPC, int perkID, bool freeUpgrade = false)
        {
            var perk       = DataService.Perk.GetByID(perkID);
            var perkLevels = DataService.PerkLevel.GetAllByPerkID(perkID);
            var pcPerk     = DataService.PCPerk.GetByPlayerAndPerkIDOrDefault(oPC.GlobalID, perkID);
            var player     = DataService.Player.GetByID(oPC.GlobalID);

            if (freeUpgrade || CanPerkBeUpgraded(oPC, perkID))
            {
                DatabaseActionType action = DatabaseActionType.Update;
                if (pcPerk == null)
                {
                    pcPerk = new PCPerk();
                    DateTime dt = DateTime.UtcNow;
                    pcPerk.AcquiredDate = dt;
                    pcPerk.PerkID       = perk.ID;
                    pcPerk.PlayerID     = oPC.GlobalID;
                    pcPerk.PerkLevel    = 0;

                    action = DatabaseActionType.Insert;
                }

                PerkLevel nextPerkLevel = FindPerkLevel(perkLevels, pcPerk.PerkLevel + 1);

                if (nextPerkLevel == null)
                {
                    return;
                }
                pcPerk.PerkLevel++;
                DataService.SubmitDataChange(pcPerk, action);

                if (!freeUpgrade)
                {
                    player.UnallocatedSP -= nextPerkLevel.Price;
                    DataService.SubmitDataChange(player, DatabaseActionType.Update);
                }

                // Look for a perk feat to grant.
                var perkFeatToGrant = DataService.PerkFeat.GetByPerkIDAndLevelUnlockedOrDefault(perkID, pcPerk.PerkLevel);

                // Add the feat(s) to the player if it doesn't exist yet.
                if (perkFeatToGrant != null && _.GetHasFeat((Feat)perkFeatToGrant.FeatID, oPC.Object) == false)
                {
                    NWNXCreature.AddFeatByLevel(oPC, (Feat)perkFeatToGrant.FeatID, 1);

                    var qbs = NWNXPlayerQuickBarSlot.UseFeat((Feat)perkFeatToGrant.FeatID);

                    // Try to add the new feat to the player's hotbar.
                    if (NWNXPlayer.GetQuickBarSlot(oPC, 0).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 0, qbs);
                    }
                    else if (NWNXPlayer.GetQuickBarSlot(oPC, 1).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 1, qbs);
                    }
                    else if (NWNXPlayer.GetQuickBarSlot(oPC, 2).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 2, qbs);
                    }
                    else if (NWNXPlayer.GetQuickBarSlot(oPC, 3).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 3, qbs);
                    }
                    else if (NWNXPlayer.GetQuickBarSlot(oPC, 4).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 4, qbs);
                    }
                    else if (NWNXPlayer.GetQuickBarSlot(oPC, 5).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 5, qbs);
                    }
                    else if (NWNXPlayer.GetQuickBarSlot(oPC, 6).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 6, qbs);
                    }
                    else if (NWNXPlayer.GetQuickBarSlot(oPC, 7).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 7, qbs);
                    }
                    else if (NWNXPlayer.GetQuickBarSlot(oPC, 8).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 8, qbs);
                    }
                    else if (NWNXPlayer.GetQuickBarSlot(oPC, 9).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 9, qbs);
                    }
                    else if (NWNXPlayer.GetQuickBarSlot(oPC, 10).ObjectType == QuickBarSlotType.Empty)
                    {
                        NWNXPlayer.SetQuickBarSlot(oPC, 10, qbs);
                    }
                }

                oPC.SendMessage(ColorTokenService.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")"));

                MessageHub.Instance.Publish(new OnPerkUpgraded(oPC, perkID));

                var handler = GetPerkHandler(perkID);
                handler.OnPurchased(oPC, pcPerk.PerkLevel);
            }
            else
            {
                oPC.FloatingText(ColorTokenService.Red("You cannot purchase the perk at this time."));
            }
        }
Esempio n. 23
0
        private static void OnModuleActivatedItem()
        {
            NWPlayer user           = (_.GetItemActivator());
            NWItem   oItem          = (_.GetItemActivated());
            NWObject target         = (_.GetItemActivatedTarget());
            Location targetLocation = _.GetItemActivatedTargetLocation();

            string className = oItem.GetLocalString("SCRIPT");

            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("ACTIVATE_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("ACTION_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("SCRIPT");
            }
            // Legacy events follow. We can't remove these because of backwards compatibility issues with existing items.
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("JAVA_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("ACTIVATE_JAVA_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("JAVA_ACTION_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                return;
            }

            user.ClearAllActions();

            if (user.IsBusy)
            {
                user.SendMessage("You are busy.");
                return;
            }

            // Remove "Item." prefix if it exists.
            if (className.StartsWith("Item."))
            {
                className = className.Substring(5);
            }
            IActionItem item = GetActionItemHandler(className);

            string invalidTargetMessage = item.IsValidTarget(user, oItem, target, targetLocation);

            if (!string.IsNullOrWhiteSpace(invalidTargetMessage))
            {
                user.SendMessage(invalidTargetMessage);
                return;
            }

            float maxDistance = item.MaxDistance(user, oItem, target, targetLocation);

            if (maxDistance > 0.0f)
            {
                if (target.IsValid &&
                    (_.GetDistanceBetween(user.Object, target.Object) > maxDistance ||
                     user.Area.Resref != target.Area.Resref))
                {
                    user.SendMessage("Your target is too far away.");
                    return;
                }
                else if (!target.IsValid &&
                         (_.GetDistanceBetweenLocations(user.Location, targetLocation) > maxDistance ||
                          user.Area.Resref != ((NWArea)_.GetAreaFromLocation(targetLocation)).Resref))
                {
                    user.SendMessage("That location is too far away.");
                    return;
                }
            }

            CustomData customData   = item.StartUseItem(user, oItem, target, targetLocation);
            float      delay        = item.Seconds(user, oItem, target, targetLocation, customData);
            int        animationID  = item.AnimationID();
            bool       faceTarget   = item.FaceTarget();
            Vector     userPosition = user.Position;

            user.AssignCommand(() =>
            {
                user.IsBusy = true;
                if (faceTarget)
                {
                    _.SetFacingPoint(!target.IsValid ? _.GetPositionFromLocation(targetLocation) : target.Position);
                }
                if (animationID > 0)
                {
                    _.ActionPlayAnimation(animationID, 1.0f, delay);
                }
            });

            NWNXPlayer.StartGuiTimingBar(user, delay, string.Empty);

            var @event = new OnFinishActionItem(className, user, oItem, target, targetLocation, userPosition, customData);

            user.DelayEvent(delay, @event);
        }