예제 #1
0
        public static void HandleQueueWeaponSkill(NWPlayer pc, Data.Entity.Perk entity, IPerkHandler ability, int spellFeatID)
        {
            int?   cooldownCategoryID = ability.CooldownCategoryID(pc, entity.CooldownCategoryID, spellFeatID);
            var    cooldownCategory   = DataService.Get <CooldownCategory>(cooldownCategoryID);
            string queueUUID          = Guid.NewGuid().ToString();

            pc.SetLocalInt("ACTIVE_WEAPON_SKILL", entity.ID);
            pc.SetLocalString("ACTIVE_WEAPON_SKILL_UUID", queueUUID);
            pc.SetLocalInt("ACTIVE_WEAPON_SKILL_FEAT_ID", spellFeatID);
            pc.SendMessage("Weapon skill '" + entity.Name + "' queued for next attack.");

            ApplyCooldown(pc, cooldownCategory, ability, spellFeatID);

            // Player must attack within 30 seconds after queueing or else it wears off.
            _.DelayCommand(30f, () =>
            {
                if (pc.GetLocalString("ACTIVE_WEAPON_SKILL_UUID") == queueUUID)
                {
                    pc.DeleteLocalInt("ACTIVE_WEAPON_SKILL");
                    pc.DeleteLocalString("ACTIVE_WEAPON_SKILL_UUID");
                    pc.DeleteLocalInt("ACTIVE_WEAPON_SKILL_FEAT_ID");
                    pc.SendMessage("Your weapon skill '" + entity.Name + "' is no longer queued.");
                }
            });
        }
예제 #2
0
        public void OnModuleEnter()
        {
            NWPlayer player = _.GetEnteringObject();

            if (!player.IsPlayer)
            {
                return;
            }

            var dbPlayer = _data.Single <Player>(x => x.ID == player.GlobalID);

            player.SetLocalInt("DISPLAY_HOLONET", dbPlayer.DisplayHolonet ? TRUE : FALSE);
            player.SetLocalInt("DISPLAY_DISCORD", dbPlayer.DisplayDiscord ? TRUE : FALSE);
        }
예제 #3
0
        private static void OnModuleUseFeat()
        {
            NWPlayer pc     = Object.OBJECT_SELF;
            int      featID = NWNXEvents.OnFeatUsed_GetFeatID();

            if (featID != (int)CustomFeatType.RenameCraftedItem)
            {
                return;
            }
            pc.ClearAllActions();

            bool   isSetting  = pc.GetLocalInt("CRAFT_RENAMING_ITEM") == TRUE;
            NWItem renameItem = NWNXEvents.OnFeatUsed_GetTarget().Object;

            if (isSetting)
            {
                pc.SendMessage("You are no longer naming an item.");
                pc.DeleteLocalInt("CRAFT_RENAMING_ITEM");
                pc.DeleteLocalObject("CRAFT_RENAMING_ITEM_OBJECT");
                return;
            }

            string crafterPlayerID = renameItem.GetLocalString("CRAFTER_PLAYER_ID");

            if (string.IsNullOrWhiteSpace(crafterPlayerID) || new Guid(crafterPlayerID) != pc.GlobalID)
            {
                pc.SendMessage("You may only rename items which you have personally crafted.");
                return;
            }

            pc.SetLocalInt("CRAFT_RENAMING_ITEM", TRUE);
            pc.SetLocalObject("CRAFT_RENAMING_ITEM_OBJECT", renameItem);
            pc.SendMessage("Please enter in a name for this item. Length should be between 3 and 64 characters. Use this feat again to cancel this procedure.");
        }
예제 #4
0
        private void LoadHeader()
        {
            NWPlayer player = GetPC();

            player.SetLocalInt("ITEM_RENAMING_LISTENING", TRUE);

            NWItem item         = player.GetLocalObject("ITEM_BEING_RENAMED");
            string originalName = item.GetLocalString("RENAMED_ITEM_ORIGINAL_NAME");

            if (string.IsNullOrWhiteSpace(originalName))
            {
                originalName = item.Name;
            }
            string currentName  = item.Name;
            string renamingName = player.GetLocalString("RENAMED_ITEM_NEW_NAME");

            if (string.IsNullOrWhiteSpace(renamingName))
            {
                renamingName = "{UNSPECIFIED}";
            }

            string header = "You are renaming an item.\n\n";

            header += ColorTokenService.Green("Original Name: ") + originalName + "\n";
            header += ColorTokenService.Green("Current Name: ") + currentName + "\n";
            header += ColorTokenService.Green("New Name: ") + renamingName + "\n";
            header += "Type in a new name, click 'Refresh', and then select 'Change Name' to make the changes. Click 'Reset Name' to switch back to the item's original name.";

            SetPageHeader("MainPage", header);
        }
예제 #5
0
        private static void CheckForSpellInterruption(NWPlayer pc, string spellUUID, Vector position)
        {
            if (pc.GetLocalInt(spellUUID) == (int)SpellStatusType.Completed)
            {
                return;
            }

            Vector currentPosition = pc.Position;

            if (currentPosition.m_X != position.m_X ||
                currentPosition.m_Y != position.m_Y ||
                currentPosition.m_Z != position.m_Z)
            {
                var effect = pc.Effects.SingleOrDefault(x => _.GetEffectTag(x) == "ACTIVATION_VFX");
                if (effect != null)
                {
                    _.RemoveEffect(pc, effect);
                }

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

            _.DelayCommand(0.5f, () => { CheckForSpellInterruption(pc, spellUUID, position); });
        }
예제 #6
0
        public static void SetMapPin(NWPlayer oPC, string text, float positionX, float positionY, NWArea area, string tag)
        {
            int numberOfMapPins = GetNumberOfMapPins(oPC);
            int storeAtIndex    = -1;

            for (int index = 0; index < numberOfMapPins; index++)
            {
                MapPin mapPin = GetMapPin(oPC, index);
                if (string.IsNullOrWhiteSpace(mapPin.Text))
                {
                    storeAtIndex = index;
                    break;
                }
            }

            if (storeAtIndex == -1)
            {
                numberOfMapPins++;
                storeAtIndex = numberOfMapPins - 1;
            }

            storeAtIndex++;

            oPC.SetLocalString("NW_MAP_PIN_NTRY_" + storeAtIndex, text);
            oPC.SetLocalFloat("NW_MAP_PIN_XPOS_" + storeAtIndex, positionX);
            oPC.SetLocalFloat("NW_MAP_PIN_YPOS_" + storeAtIndex, positionY);
            oPC.SetLocalObject("NW_MAP_PIN_AREA_" + storeAtIndex, area.Object);
            oPC.SetLocalInt("NW_TOTAL_MAP_PINS", numberOfMapPins);

            if (tag != null)
            {
                oPC.SetLocalString("CUSTOM_NW_MAP_PIN_TAG_" + storeAtIndex, tag);
            }
        }
예제 #7
0
        public bool Run(params object[] args)
        {
            NWPlayer player = GetEnteringPlayer();

            if (player.IsDM)
            {
                App.GetAppState().ConnectedDMs.Add(player);
            }

            player.DeleteLocalInt("IS_CUSTOMIZING_ITEM");
            _.ExecuteScript("dmfi_onclienter ", Object.OBJECT_SELF); // DMFI also calls "x3_mod_def_enter"
            _playerValidation.OnModuleEnter();
            _player.InitializePlayer(player);
            _data.CachePlayerData(player);
            _skill.OnModuleEnter();
            _player.LoadCharacter(player);
            _migration.OnModuleEnter();
            _player.ShowMOTD(player);
            ApplyGhostwalk();
            _quest.OnClientEnter();
            _activityLogging.OnModuleClientEnter();
            ApplyScriptEvents(player);
            _mapPin.OnModuleClientEnter();
            _objectVisibility.OnClientEnter();
            _customEffect.OnModuleEnter();
            _chatText.OnModuleEnter();
            _race.OnModuleEnter();

            player.SetLocalInt("LOGGED_IN_ONCE", TRUE);
            return(true);
        }
예제 #8
0
        public void OnImpact(NWPlayer player, NWObject target, int perkLevel, int spellFeatID)
        {
            float minimum = player.Facing - 20;
            float maximum = player.Facing + 20;

            if (target.Facing >= minimum &&
                target.Facing <= maximum)
            {
                // Mark the player as committing a sneak attack.
                // This is later picked up in the OnApplyDamage event.
                player.SetLocalInt("SNEAK_ATTACK_ACTIVE", 1);
            }
            else
            {
                player.SetLocalInt("SNEAK_ATTACK_ACTIVE", 2);
            }
        }
예제 #9
0
        public void OnImpact(NWPlayer oPC, NWObject oTarget)
        {
            float minimum = oPC.Facing - 20;
            float maximum = oPC.Facing + 20;

            if (oTarget.Facing >= minimum &&
                oTarget.Facing <= maximum)
            {
                // Mark the player as committing a sneak attack.
                // This is later picked up in the OnApplyDamage event.
                oPC.SetLocalInt("SNEAK_ATTACK_ACTIVE", 1);
            }
            else
            {
                oPC.SetLocalInt("SNEAK_ATTACK_ACTIVE", 2);
            }
        }
예제 #10
0
        public bool Run(params object[] args)
        {
            NWPlaceable plc           = NWPlaceable.Wrap(Object.OBJECT_SELF);
            NWPlayer    oPC           = NWPlayer.Wrap(_.GetLastAttacker());
            NWItem      oWeapon       = NWItem.Wrap(_.GetLastWeaponUsed(oPC.Object));
            int         type          = oWeapon.BaseItemType;
            int         resourceCount = plc.GetLocalInt("RESOURCE_COUNT");

            if (resourceCount <= -1)
            {
                resourceCount = _random.Random(3) + 3;
                plc.SetLocalInt("RESOURCE_COUNT", resourceCount);
            }

            if (type == BASE_ITEM_INVALID)
            {
                oWeapon = oPC.RightHand;
            }

            int activityID = plc.GetLocalInt("RESOURCE_ACTIVITY");

            string improperWeaponMessage = "";
            bool   usingCorrectWeapon    = true;

            if (activityID == 1) // 1 = Logging
            {
                usingCorrectWeapon = oWeapon.CustomItemType == CustomItemType.Blade ||
                                     oWeapon.CustomItemType == CustomItemType.TwinBlade ||
                                     oWeapon.CustomItemType == CustomItemType.HeavyBlade ||
                                     oWeapon.CustomItemType == CustomItemType.FinesseBlade ||
                                     oWeapon.CustomItemType == CustomItemType.Polearm;
                improperWeaponMessage = "You must be using a blade to harvest this object.";
            }
            else if (activityID == 2) // Mining
            {
                usingCorrectWeapon = oWeapon.CustomItemType == CustomItemType.Blade ||
                                     oWeapon.CustomItemType == CustomItemType.TwinBlade ||
                                     oWeapon.CustomItemType == CustomItemType.HeavyBlade ||
                                     oWeapon.CustomItemType == CustomItemType.FinesseBlade ||
                                     oWeapon.CustomItemType == CustomItemType.Polearm ||
                                     oWeapon.CustomItemType == CustomItemType.Blunt ||
                                     oWeapon.CustomItemType == CustomItemType.HeavyBlunt;
                improperWeaponMessage = "You must be using a blade or a blunt weapon to harvest this object.";
            }

            if (!usingCorrectWeapon)
            {
                plc.IsPlot = true;
                oPC.SendMessage(_color.Red(improperWeaponMessage));
                oPC.SetLocalInt("NOT_USING_CORRECT_WEAPON", 1);
                oPC.ClearAllActions();
                oPC.DelayCommand(() => plc.IsPlot = false, 1.0f);
            }

            return(true);
        }
예제 #11
0
        private void BuildTurnOptions(NWPlayer pc)
        {
            // Draw a card.
            int score = pc == game.player1 ? game.player1Score : game.player2Score;

            int card = game.DrawCard();

            score += card;
            game.lastCardPlayed = card;
            pc.FloatingText("You drew a " + card + " putting your score at " + score);
            if (pc == game.player1)
            {
                game.player1Score = score;
            }
            else
            {
                game.player2Score = score;
            }

            // Since we're having a turn, we can't be the one standing...
            bool bStand = game.player1Standing || game.player2Standing;

            string header = "Your score is at " + score + ". " + (bStand ? "The other player is standing. " : "") +
                            "What do you want to do?";

            SpeakString(pc.Name + " draws a " + card + " from the deck.  Their score is now " + score);

            if (pc.GetLocalInt("PAZAAK_REMINDED") == 0)
            {
                pc.SendMessage("(Pazaak Rules Reminder: highest score under 21 wins, ending your turn at 21+ loses you the round.  You may play up to one card from your hand each turn. A standing player does not get to play again, but ending your turn means you will have to draw at least one more card.)");
                pc.SetLocalInt("PAZAAK_REMINDED", 1);
            }

            SetPageHeader("MainPage", header);
            ClearPageResponses("MainPage");

            List <int> sideDeck = pc == game.player1 ? game.player1SideDeck : game.player2SideDeck;

            // Build options from the side deck.
            foreach (int sideCard in sideDeck)
            {
                if ((sideCard > 100 && sideCard < 107) || sideCard == 203)
                {
                    // Card can be played either of two ways.
                    AddResponseToPage("MainPage", "Play card from side deck: " + PazaakService.Display(sideCard) + " as positive", true, sideCard);
                    AddResponseToPage("MainPage", "Play card from side deck: " + PazaakService.Display(sideCard) + " as negative", true, sideCard);
                }
                else
                {
                    AddResponseToPage("MainPage", "Play card from side deck: " + PazaakService.Display(sideCard), true, sideCard);
                }
            }

            AddResponseToPage("MainPage", "End Turn", score < 21);
            AddResponseToPage("MainPage", "Stand");
        }
예제 #12
0
        public static void OnActionsTaken(int nodeID)
        {
            NWPlayer     player = (_.GetPCSpeaker());
            PlayerDialog dialog = LoadPlayerDialog(player.GlobalID);

            using (new Profiler(nameof(DialogService) + "." + nameof(OnActionsTaken) + "." + dialog.ActiveDialogName))
            {
                IConversation convo           = GetConversation(dialog.ActiveDialogName);
                int           selectionNumber = nodeID + 1;
                int           responseID      = nodeID + (NumberOfResponsesPerPage * dialog.PageOffset);

                if (selectionNumber == NumberOfResponsesPerPage + 1) // Next page
                {
                    dialog.PageOffset = dialog.PageOffset + 1;
                }
                else if (selectionNumber == NumberOfResponsesPerPage + 2) // Previous page
                {
                    dialog.PageOffset = dialog.PageOffset - 1;
                }
                else if (selectionNumber == NumberOfResponsesPerPage + 3) // Back
                {
                    string currentPageName = dialog.CurrentPageName;
                    var    previous        = dialog.NavigationStack.Pop();

                    // This might be a little confusing but we're passing the active page as the "old page" to the Back() method.
                    // This is because we need to run any dialog-specific clean up prior to moving the conversation backwards.
                    convo.Back(player, currentPageName, previous.PageName);

                    // Previous page was in a different conversation. Switch to it.
                    if (previous.DialogName != dialog.ActiveDialogName)
                    {
                        LoadConversation(player, dialog.DialogTarget, previous.DialogName, dialog.DialogNumber);
                        dialog = LoadPlayerDialog(player.GlobalID);
                        dialog.ResetPage();

                        dialog.CurrentPageName = previous.PageName;
                        dialog.PageOffset      = 0;
                        // ActiveDialogName will have changed by this point. Get the new conversation.
                        convo = GetConversation(dialog.ActiveDialogName);
                        convo.Initialize();
                        player.SetLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN", 1);
                    }
                    // Otherwise it's in the same conversation. Switch to that.
                    else
                    {
                        dialog.CurrentPageName = previous.PageName;
                        dialog.PageOffset      = 0;
                    }
                }
                else if (selectionNumber != NumberOfResponsesPerPage + 4) // End
                {
                    convo.DoAction(player, dialog.CurrentPageName, responseID + 1);
                }
            }
        }
예제 #13
0
        private static void OnModuleEnter()
        {
            NWPlayer player = _.GetEnteringObject();

            if (!player.IsPlayer)
            {
                return;
            }

            var dbPlayer = DataService.Player.GetByID(player.GlobalID);

            player.SetLocalInt("DISPLAY_HOLONET", dbPlayer.DisplayHolonet ? TRUE : FALSE);
        }
예제 #14
0
        public void OnImpact(NWPlayer player, NWObject target, int perkLevel)
        {
            // Mark the player as performing a recovery blast.
            // This is later picked up in the OnApplyDamage event to reduce all damage to 0.
            player.SetLocalInt("RECOVERY_BLAST_ACTIVE", 1);

            var members = player.PartyMembers.Where(x => _.GetDistanceBetween(x, target) <= 10.0f);
            int luck    = _perk.GetPCPerkLevel(player, PerkType.Lucky);

            foreach (var member in members)
            {
                HealTarget(member, perkLevel, luck);
            }
        }
예제 #15
0
        private void PerformMigration(NWPlayer oPC)
        {
            PlayerCharacter entity = _db.PlayerCharacters.Single(x => x.PlayerID == oPC.GlobalID);

            for (int version = entity.VersionNumber + 1; version <= PlayerVersionNumber; version++)
            {
                Dictionary <string, PCMigrationItem> itemMap = new Dictionary <string, PCMigrationItem>();
                List <int>  stripItemList = new List <int>();
                PCMigration migration     = _db.PCMigrations.Single(x => x.PCMigrationID == version);

                foreach (PCMigrationItem item in migration.PCMigrationItems)
                {
                    if (!string.IsNullOrWhiteSpace(item.CurrentResref))
                    {
                        itemMap[item.CurrentResref] = item;
                    }
                    else if (item.BaseItemTypeID > -1 && item.StripItemProperties)
                    {
                        stripItemList.Add(item.BaseItemTypeID);
                    }
                }

                for (int slot = 0; slot < NUM_INVENTORY_SLOTS; slot++)
                {
                    NWItem item = NWItem.Wrap(_.GetItemInSlot(slot, oPC.Object));
                    ProcessItem(oPC, item, itemMap, stripItemList);
                }

                foreach (NWItem item in oPC.InventoryItems)
                {
                    ProcessItem(oPC, item, itemMap, stripItemList);
                }

                RunCustomMigrationProcess(oPC, version);
                entity = _db.PlayerCharacters.Single(x => x.PlayerID == oPC.GlobalID);
                entity.VersionNumber = version;
                _db.SaveChanges();
                oPC.SetLocalInt("MIGRATION_SYSTEM_LOGGED_IN_ONCE", TRUE);

                long   overflowCount = _db.PCOverflowItems.LongCount(x => x.PlayerID == oPC.GlobalID);
                string message       = _color.Green("Your character has been updated!" +
                                                    (overflowCount > 0 ? " Items which could not be created have been placed into overflow inventory. You can access this from the rest menu." : ""));

                oPC.DelayCommand(() =>
                {
                    oPC.FloatingText(message);
                }, 8.0f);
            }
        }
예제 #16
0
        private void CheckForSpellInterruption(NWPlayer pc, string spellUUID, Vector position)
        {
            Vector currentPosition = pc.Position;

            if (currentPosition.m_X != position.m_X ||
                currentPosition.m_Y != position.m_Y ||
                currentPosition.m_Z != position.m_Z)
            {
                _nwnxPlayer.StopGuiTimingBar(pc, "", -1);
                pc.IsBusy = false;
                pc.SetLocalInt(spellUUID, SPELL_STATUS_INTERRUPTED);
                return;
            }

            pc.DelayCommand(() => CheckForSpellInterruption(pc, spellUUID, position), 1.0f);
        }
예제 #17
0
        // ReSharper disable once UnusedMember.Local
        private static void Main()
        {
            // The order of the following procedures matters.
            NWPlayer player = _.GetEnteringObject();

            using (new Profiler(nameof(mod_on_enter) + ":AddDMToCache"))
            {
                if (player.IsDM)
                {
                    AppCache.ConnectedDMs.Add(player);
                }
            }

            using (new Profiler(nameof(mod_on_enter) + ":BiowareDefault"))
            {
                player.DeleteLocalInt("IS_CUSTOMIZING_ITEM");
                _.ExecuteScript("dmfi_onclienter ", NWGameObject.OBJECT_SELF); // DMFI also calls "x3_mod_def_enter"
            }

            using (new Profiler(nameof(mod_on_enter) + ":PlayerValidation"))
            {
                PlayerValidationService.OnModuleEnter();
            }

            using (new Profiler(nameof(mod_on_enter) + ":InitializePlayer"))
            {
                PlayerService.InitializePlayer(player);
            }

            using (new Profiler(nameof(mod_on_enter) + ":CachePlayerData"))
            {
                //DataService.CachePlayerData(player);
            }

            using (new Profiler(nameof(mod_on_enter) + ":SkillServiceEnter"))
            {
                SkillService.OnModuleEnter();
            }

            using (new Profiler(nameof(mod_on_enter) + ":PerkServiceEnter"))
            {
                PerkService.OnModuleEnter();
            }

            MessageHub.Instance.Publish(new OnModuleEnter());
            player.SetLocalInt("LOGGED_IN_ONCE", _.TRUE);
        }
예제 #18
0
파일: Quest.cs 프로젝트: zunath/SWLOR_NWN
        private void RequestRewardSelectionFromPC(NWPlayer player, NWObject questGiver)
        {
            if (!player.IsPlayer)
            {
                return;
            }

            if (AllowRewardSelection)
            {
                player.SetLocalInt("QST_REWARD_SELECTION_QUEST_ID", QuestID);
                DialogService.StartConversation(player, player, "QuestRewardSelection");
            }
            else
            {
                Complete(player, questGiver, null);
            }
        }
예제 #19
0
        public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args)
        {
            var player = _data.Get <Player>(user.GlobalID);

            player.DisplayDiscord = !player.DisplayDiscord;
            user.SetLocalInt("DISPLAY_DISCORD", player.DisplayDiscord ? 1 : 0);
            _data.SubmitDataChange(player, DatabaseActionType.Update);

            if (player.DisplayDiscord)
            {
                user.SendMessage("Discord chat: " + _color.Green("ENABLED"));
            }
            else
            {
                user.SendMessage("Discord chat: " + _color.Red("DISABLED"));
            }
        }
예제 #20
0
        public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args)
        {
            var player = DataService.Player.GetByID(user.GlobalID);

            player.DisplayHolonet = !player.DisplayHolonet;
            user.SetLocalInt("DISPLAY_HOLONET", player.DisplayHolonet ? 1 : 0);

            DataService.SubmitDataChange(player, DatabaseActionType.Update);

            if (player.DisplayHolonet)
            {
                user.SendMessage("Holonet chat: " + ColorTokenService.Green("ENABLED"));
            }
            else
            {
                user.SendMessage("Holonet chat: " + ColorTokenService.Red("DISABLED"));
            }
        }
예제 #21
0
        private static void RequestRewardSelectionFromPC(NWPlayer oPC, NWObject questOwner, int questID)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }

            Quest quest = DataService.Single <Quest>(x => x.ID == questID);

            if (quest.AllowRewardSelection)
            {
                oPC.SetLocalInt("QST_REWARD_SELECTION_QUEST_ID", questID);
                DialogService.StartConversation(oPC, oPC, "QuestRewardSelection");
            }
            else
            {
                CompleteQuest(oPC, questOwner, questID, null);
            }
        }
예제 #22
0
        private void RequestRewardSelectionFromPC(NWPlayer oPC, int questID)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }

            Quest quest = _db.Quests.Single(x => x.QuestID == questID);

            if (quest.AllowRewardSelection)
            {
                oPC.SetLocalInt("QST_REWARD_SELECTION_QUEST_ID", questID);
                _dialog.StartConversation(oPC, oPC, "QuestRewardSelection");
            }
            else
            {
                QuestState lastState = quest.QuestStates.ElementAt(quest.QuestStates.Count - 1);
                _.AddJournalQuestEntry(quest.JournalTag, lastState.JournalStateID, oPC.Object, FALSE);
                CompleteQuest(oPC, questID, null);
            }
        }
예제 #23
0
        private void HandleQueueWeaponSkill(NWPlayer pc, Data.Entities.Perk entity, IPerk ability)
        {
            string queueUUID = Guid.NewGuid().ToString();

            pc.SetLocalInt("ACTIVE_WEAPON_SKILL", entity.PerkID);
            pc.SetLocalString("ACTIVE_WEAPON_SKILL_UUID", queueUUID);
            pc.SendMessage("Weapon skill '" + entity.Name + "' queued for next attack.");

            ApplyCooldown(pc, entity.CooldownCategory, ability);

            // Player must attack within 30 seconds after queueing or else it wears off.
            pc.DelayCommand(() =>
            {
                if (pc.GetLocalString("ACTIVE_WEAPON_SKILL_UUID") == queueUUID)
                {
                    pc.DeleteLocalInt("ACTIVE_WEAPON_SKILL");
                    pc.DeleteLocalString("ACTIVE_WEAPON_SKILL_UUID");
                    pc.SendMessage("Your weapon skill '" + entity.Name + "' is no longer queued.");
                }
            }, 30.0f);
        }
예제 #24
0
        private static void OnModuleClientEnter()
        {
            NWPlayer oPC = (_.GetEnteringObject());

            if (!oPC.IsPlayer)
            {
                return;
            }
            if (oPC.GetLocalInt("MAP_PINS_LOADED") == 1)
            {
                return;
            }

            List <PCMapPin> pins = DataService.Where <PCMapPin>(x => x.PlayerID == oPC.GlobalID).ToList();

            foreach (PCMapPin pin in pins)
            {
                NWArea area = (_.GetObjectByTag(pin.AreaTag));
                SetMapPin(oPC, pin.NoteText, (float)pin.PositionX, (float)pin.PositionY, area);
            }

            oPC.SetLocalInt("MAP_PINS_LOADED", 1);
        }
예제 #25
0
        public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args)
        {
            if (!user.IsPlayer)
            {
                return;
            }

            //Checks if the player has Plasma Cell
            if (!_.GetHasFeat(Feat.PlasmaCell, user))
            {
                user.SendMessage(ColorTokenService.Red("You do not have the perk: Plasma Cell."));
                return;
            }

            //Checks if the player has toggled plasma cell off
            if (user.GetLocalBool("PLASMA_CELL_TOGGLE_OFF") == false)
            {
                user.SetLocalInt("PLASMA_CELL_TOGGLE_OFF", 1);
                user.SendMessage(ColorTokenService.Red("Plasma Cell is now toggled off."));
                return;
            }

            //Checks if plasma cell has been toggled off
            else if (user.GetLocalInt("PLASMA_CELL_TOGGLE_OFF") > 0)
            {
                user.DeleteLocalInt("PLASMA_CELL_TOGGLE_OFF");
                user.SendMessage(ColorTokenService.Green("Plasma Cell is now toggled on!"));
                return;
            }

            //If the above aren't working, this should appear and debugging required
            else
            {
                user.SendMessage(ColorTokenService.Red("Something's wrong, contact a code contributor!"));
                return;
            }
        }
예제 #26
0
        public static string TranslateSnippetForListener(NWObject speaker, NWObject listener, SkillType language, string snippet)
        {
            Dictionary <SkillType, Type> map = new Dictionary <SkillType, Type>
            {
                { SkillType.Bothese, typeof(TranslatorBothese) },
                { SkillType.Catharese, typeof(TranslatorCatharese) },
                { SkillType.Cheunh, typeof(TranslatorCheunh) },
                { SkillType.Dosh, typeof(TranslatorDosh) },
                { SkillType.Droidspeak, typeof(TranslatorDroidspeak) },
                { SkillType.Huttese, typeof(TranslatorHuttese) },
                { SkillType.Mandoa, typeof(TranslatorMandoa) },
                { SkillType.Shyriiwook, typeof(TranslatorShyriiwook) },
                { SkillType.Twileki, typeof(TranslatorTwileki) },
                { SkillType.Zabraki, typeof(TranslatorZabraki) },
                { SkillType.Mirialan, typeof(TranslatorMirialan) },
                { SkillType.MonCalamarian, typeof(TranslatorMonCalamarian) },
                { SkillType.Ugnaught, typeof(TranslatorUgnaught) }
            };

            Type type = typeof(TranslatorGeneric);

            map.TryGetValue(language, out type);
            ITranslator translator = (ITranslator)Activator.CreateInstance(type);

            if (speaker.IsPC && !speaker.IsDM)
            {
                // Get the rank and max rank for the speaker, and garble their English text based on it.
                NWPlayer speakerAsPlayer     = speaker.Object;
                int      speakerSkillRank    = SkillService.GetPCSkillRank(speakerAsPlayer, language);
                int      speakerSkillMaxRank = SkillService.GetSkill(language).MaxRank;

                if (speakerSkillRank != speakerSkillMaxRank)
                {
                    int garbledChance = 100 - (int)(((float)speakerSkillRank / (float)speakerSkillMaxRank) * 100);

                    string[] split = snippet.Split(' ');
                    for (int i = 0; i < split.Length; ++i)
                    {
                        if (RandomService.Random(100) <= garbledChance)
                        {
                            split[i] = new string(split[i].ToCharArray().OrderBy(s => (RandomService.Random(2) % 2) == 0).ToArray());
                        }
                    }

                    snippet = split.Aggregate((a, b) => a + " " + b);
                }
            }

            if (!listener.IsPC || listener.IsDM)
            {
                // Short circuit for a DM or NPC - they will always understand the text.
                return(snippet);
            }

            // Let's grab the max rank for the listener skill, and then we roll for a successful translate based on that.
            NWPlayer listenerAsPlayer = listener.Object;
            int      rank             = SkillService.GetPCSkillRank(listenerAsPlayer, language);
            int      maxRank          = SkillService.GetSkill(language).MaxRank;

            // Check for the Comprehend Speech concentration ability.
            Player dbPlayer     = DataService.Player.GetByID(listenerAsPlayer.GlobalID);
            bool   grantSenseXP = false;

            if (dbPlayer.ActiveConcentrationPerkID == (int)PerkType.ComprehendSpeech)
            {
                int bonus = 5 * dbPlayer.ActiveConcentrationTier;
                rank        += bonus;
                grantSenseXP = true;
            }

            // Ensure we don't go over the maximum.
            if (rank > maxRank)
            {
                rank = maxRank;
            }

            if (rank == maxRank || speaker == listener)
            {
                // Guaranteed success - return original.
                return(snippet);
            }

            string textAsForeignLanguage = translator.Translate(snippet);

            if (rank != 0)
            {
                int englishChance = (int)(((float)rank / (float)maxRank) * 100);

                string[] originalSplit = snippet.Split(' ');
                string[] foreignSplit  = textAsForeignLanguage.Split(' ');

                StringBuilder endResult = new StringBuilder();

                // WARNING: We're making the assumption that originalSplit.Length == foreignSplit.Length.
                // If this assumption changes, the below logic needs to change too.
                for (int i = 0; i < originalSplit.Length; ++i)
                {
                    if (RandomService.Random(100) <= englishChance)
                    {
                        endResult.Append(originalSplit[i]);
                    }
                    else
                    {
                        endResult.Append(foreignSplit[i]);
                    }

                    endResult.Append(" ");
                }

                textAsForeignLanguage = endResult.ToString();
            }

            long now             = DateTime.Now.Ticks;
            int  lastSkillUpLow  = listenerAsPlayer.GetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_LOW");
            int  lastSkillUpHigh = listenerAsPlayer.GetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_HIGH");
            long lastSkillUp     = lastSkillUpHigh;

            lastSkillUp = (lastSkillUp << 32) | (uint)lastSkillUpLow;
            long differenceInSeconds = (now - lastSkillUp) / 10000000;

            if (differenceInSeconds / 60 >= 2)
            {
                int amount = Math.Max(10, Math.Min(150, snippet.Length) / 3);
                // Reward exp towards the language - we scale this with character count, maxing at 50 exp for 150 characters.
                SkillService.GiveSkillXP(listenerAsPlayer, language, amount);

                // Grant Sense XP if player is concentrating Comprehend Speech.
                if (grantSenseXP)
                {
                    SkillService.GiveSkillXP(listenerAsPlayer, SkillType.ForceSense, amount * 10);
                }

                listenerAsPlayer.SetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_LOW", (int)(now & 0xFFFFFFFF));
                listenerAsPlayer.SetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_HIGH", (int)((now >> 32) & 0xFFFFFFFF));
            }

            return(textAsForeignLanguage);
        }
예제 #27
0
        public static bool OnAppearsWhen(int nodeType, int nodeID)
        {
            NWPlayer player    = (_.GetPCSpeaker());
            bool     hasDialog = HasPlayerDialog(player.GlobalID);

            if (!hasDialog)
            {
                return(false);
            }
            PlayerDialog dialog = LoadPlayerDialog(player.GlobalID);

            using (new Profiler(nameof(DialogService) + "." + nameof(OnAppearsWhen) + "." + dialog.ActiveDialogName))
            {
                DialogPage page  = dialog.CurrentPage;
                var        convo = GetConversation(dialog.ActiveDialogName);
                int        currentSelectionNumber = nodeID + 1;
                bool       displayNode            = false;
                string     newNodeText            = string.Empty;
                int        dialogOffset           = (NumberOfResponsesPerPage + 1) * (dialog.DialogNumber - 1);

                if (currentSelectionNumber == NumberOfResponsesPerPage + 1) // Next page
                {
                    int displayCount = page.NumberOfResponses - (NumberOfResponsesPerPage * dialog.PageOffset);

                    if (displayCount > NumberOfResponsesPerPage)
                    {
                        displayNode = true;
                    }
                }
                else if (currentSelectionNumber == NumberOfResponsesPerPage + 2) // Previous Page
                {
                    if (dialog.PageOffset > 0)
                    {
                        displayNode = true;
                    }
                }
                else if (currentSelectionNumber == NumberOfResponsesPerPage + 3) // Back
                {
                    if (dialog.NavigationStack.Count > 0 && dialog.EnableBackButton)
                    {
                        displayNode = true;
                    }
                }
                else if (nodeType == 2)
                {
                    int responseID = (dialog.PageOffset * NumberOfResponsesPerPage) + nodeID;
                    if (responseID + 1 <= page.NumberOfResponses)
                    {
                        DialogResponse response = page.Responses[responseID];

                        if (response != null)
                        {
                            newNodeText = response.Text;
                            displayNode = response.IsActive;
                        }
                    }
                }
                else if (nodeType == 1)
                {
                    if (player.GetLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN") != 1)
                    {
                        convo.Initialize();
                        player.SetLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN", 1);
                    }

                    if (dialog.IsEnding)
                    {
                        convo.EndDialog();
                        RemovePlayerDialog(player.GlobalID);
                        player.DeleteLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN");
                        return(false);
                    }

                    page        = dialog.CurrentPage;
                    newNodeText = page.Header;

                    _.SetCustomToken(90000 + dialogOffset, newNodeText);
                    return(true);
                }

                _.SetCustomToken(90001 + nodeID + dialogOffset, newNodeText);
                return(displayNode);
            }
        }
예제 #28
0
        public bool Run(params object[] args)
        {
            int          nodeID          = (int)args[0];
            NWPlayer     player          = (_.GetPCSpeaker());
            PlayerDialog dialog          = _dialogService.LoadPlayerDialog(player.GlobalID);
            int          selectionNumber = nodeID + 1;
            int          responseID      = nodeID + (_dialogService.NumberOfResponsesPerPage * dialog.PageOffset);

            if (selectionNumber == _dialogService.NumberOfResponsesPerPage + 1) // Next page
            {
                dialog.PageOffset = dialog.PageOffset + 1;
            }
            else if (selectionNumber == _dialogService.NumberOfResponsesPerPage + 2) // Previous page
            {
                dialog.PageOffset = dialog.PageOffset - 1;
            }
            else if (selectionNumber == _dialogService.NumberOfResponsesPerPage + 3) // Back
            {
                string currentPageName = dialog.CurrentPageName;
                var    previous        = dialog.NavigationStack.Pop();

                // This might be a little confusing but we're passing the active page as the "old page" to the Back() method.
                // This is because we need to run any dialog-specific clean up prior to moving the conversation backwards.
                App.ResolveByInterface <IConversation>("Conversation." + dialog.ActiveDialogName, convo =>
                {
                    convo.Back(player, currentPageName, previous.PageName);
                });

                // Previous page was in a different conversation. Switch to it.
                if (previous.DialogName != dialog.ActiveDialogName)
                {
                    _dialogService.LoadConversation(player, dialog.DialogTarget, previous.DialogName, dialog.DialogNumber);
                    dialog = _dialogService.LoadPlayerDialog(player.GlobalID);
                    dialog.ResetPage();

                    dialog.CurrentPageName = previous.PageName;
                    dialog.PageOffset      = 0;

                    App.ResolveByInterface <IConversation>("Conversation." + dialog.ActiveDialogName, convo =>
                    {
                        convo.Initialize();
                        player.SetLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN", 1);
                    });
                }
                // Otherwise it's in the same conversation. Switch to that.
                else
                {
                    dialog.CurrentPageName = previous.PageName;
                    dialog.PageOffset      = 0;
                }
            }
            else if (selectionNumber != _dialogService.NumberOfResponsesPerPage + 4) // End
            {
                App.ResolveByInterface <IConversation>("Conversation." + dialog.ActiveDialogName, convo =>
                {
                    convo.DoAction(player, dialog.CurrentPageName, responseID + 1);
                });
            }

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

            Data.Entity.Perk  entity        = _data.Single <Data.Entity.Perk>(x => x.ID == perkID);
            CooldownCategory  cooldown      = _data.SingleOrDefault <CooldownCategory>(x => x.ID == entity.CooldownCategoryID);
            PerkExecutionType executionType = (PerkExecutionType)entity.ExecutionTypeID;

            return(App.ResolveByInterface <IPerk, bool>("Perk." + entity.ScriptName, perk =>
            {
                if (pc.GetLocalInt(spellUUID) == (int)SpellStatusType.Interrupted || // Moved during casting
                    pc.CurrentHP < 0 || pc.IsDead)                                   // Or is dead/dying
                {
                    pc.DeleteLocalInt(spellUUID);
                    return false;
                }

                pc.DeleteLocalInt(spellUUID);

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

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

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


                // Adjust FP only if spell cost > 0
                Data.Entity.Player pcEntity = _data.Single <Data.Entity.Player>(x => x.ID == pc.GlobalID);
                if (perk.FPCost(pc, entity.BaseFPCost) > 0)
                {
                    pcEntity.CurrentFP = pcEntity.CurrentFP - perk.FPCost(pc, entity.BaseFPCost);
                    _data.SubmitDataChange(pcEntity, DatabaseActionType.Update);
                    pc.SendMessage(_color.Custom("FP: " + pcEntity.CurrentFP + " / " + pcEntity.MaxFP, 32, 223, 219));
                }

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

                if (!hasChainspell)
                {
                    // Mark cooldown on category
                    _ability.ApplyCooldown(pc, cooldown, perk);
                }
                pc.IsBusy = false;
                pc.SetLocalInt(spellUUID, (int)SpellStatusType.Completed);

                return true;
            }));
        }
예제 #30
0
        public bool Run(params object[] args)
        {
            NWPlaceable resource = NWPlaceable.Wrap(Object.OBJECT_SELF);
            NWPlayer    oPC      = NWPlayer.Wrap(_.GetLastDamager(resource.Object));

            if (oPC.GetLocalInt("NOT_USING_CORRECT_WEAPON") == 1)
            {
                oPC.DeleteLocalInt("NOT_USING_CORRECT_WEAPON");
                return(true);
            }

            PlayerCharacter pcEntity = _db.PlayerCharacters.Single(x => x.PlayerID == oPC.GlobalID);

            NWItem    oWeapon            = NWItem.Wrap(_.GetLastWeaponUsed(oPC.Object));
            Location  location           = oPC.Location;
            string    resourceItemResref = resource.GetLocalString("RESOURCE_RESREF");
            int       activityID         = resource.GetLocalInt("RESOURCE_ACTIVITY");
            string    resourceName       = resource.GetLocalString("RESOURCE_NAME");
            int       resourceCount      = resource.GetLocalInt("RESOURCE_COUNT");
            int       difficultyRating   = resource.GetLocalInt("RESOURCE_DIFFICULTY_RATING");
            int       weaponChanceBonus;
            SkillType skillType;
            int       perkChanceBonus;
            int       secondResourceChance;
            int       durabilityChanceReduction = 0;
            int       hasteChance;
            int       lucky = _perk.GetPCPerkLevel(oPC, PerkType.Lucky) + oPC.EffectiveLuckBonus;
            bool      hasBaggerPerk;

            if (activityID == 1) // 1 = Logging
            {
                weaponChanceBonus = oWeapon.LoggingBonus;
                if (weaponChanceBonus > 0)
                {
                    weaponChanceBonus        += _perk.GetPCPerkLevel(oPC, PerkType.LoggingAxeExpert) * 5;
                    durabilityChanceReduction = _perk.GetPCPerkLevel(oPC, PerkType.LoggingAxeExpert) * 10 + lucky;
                }

                skillType            = SkillType.Logging;
                perkChanceBonus      = _perk.GetPCPerkLevel(oPC, PerkType.Lumberjack) * 5 + lucky;
                secondResourceChance = _perk.GetPCPerkLevel(oPC, PerkType.PrecisionLogging) * 10;
                hasteChance          = _perk.GetPCPerkLevel(oPC, PerkType.SpeedyLogger) * 10 + lucky;

                if (pcEntity.BackgroundID == (int)BackgroundType.Lumberjack)
                {
                    hasteChance += 10;
                }

                hasBaggerPerk = _perk.GetPCPerkLevel(oPC, PerkType.WoodBagger) > 0;
            }
            else if (activityID == 2) // Mining
            {
                weaponChanceBonus = oWeapon.MiningBonus;
                if (weaponChanceBonus > 0)
                {
                    weaponChanceBonus        += _perk.GetPCPerkLevel(oPC, PerkType.PickaxeExpert) * 5;
                    durabilityChanceReduction = _perk.GetPCPerkLevel(oPC, PerkType.PickaxeExpert) * 10 + lucky;
                }
                skillType            = SkillType.Mining;
                perkChanceBonus      = _perk.GetPCPerkLevel(oPC, PerkType.Miner) * 5 + lucky;
                secondResourceChance = _perk.GetPCPerkLevel(oPC, PerkType.PrecisionMining) * 10;
                hasteChance          = _perk.GetPCPerkLevel(oPC, PerkType.SpeedyMiner) * 10 + lucky;

                if (pcEntity.BackgroundID == (int)BackgroundType.Miner)
                {
                    hasteChance += 10;
                }

                hasBaggerPerk = _perk.GetPCPerkLevel(oPC, PerkType.OreBagger) > 0;
            }
            else
            {
                return(false);
            }
            PCSkill skill = _skill.GetPCSkillByID(oPC.GlobalID, (int)skillType);
            int     durabilityLossChance = 100 - durabilityChanceReduction;

            if (_random.Random(100) <= durabilityLossChance)
            {
                _durability.RunItemDecay(oPC, oWeapon);
            }

            int baseChance = 10;
            int chance     = baseChance + weaponChanceBonus;

            chance += CalculateSuccessChanceDeltaModifier(difficultyRating, skill.Rank);
            chance += perkChanceBonus;

            bool givePityItem = false;

            if (chance > 0)
            {
                if (_random.Random(100) + 1 <= hasteChance)
                {
                    _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectHaste(), oPC.Object, 8.0f);
                }

                // Give an item if the player hasn't gotten anything after 6-8 attempts.
                int      attemptFailureCount = oPC.GetLocalInt("RESOURCE_ATTEMPT_FAILURE_COUNT") + 1;
                NWObject failureResource     = NWObject.Wrap(oPC.GetLocalObject("RESOURCE_ATTEMPT_FAILURE_OBJECT"));

                if (!failureResource.IsValid || !Equals(failureResource, resource))
                {
                    failureResource     = resource;
                    attemptFailureCount = 1;
                }

                int pityItemChance = 0;
                if (attemptFailureCount == 6)
                {
                    pityItemChance = 60;
                }
                else if (attemptFailureCount == 7)
                {
                    pityItemChance = 80;
                }
                else if (attemptFailureCount >= 8)
                {
                    pityItemChance = 100;
                }

                if (_random.Random(100) + 1 <= pityItemChance)
                {
                    givePityItem        = true;
                    attemptFailureCount = 0;
                }

                oPC.SetLocalInt("RESOURCE_ATTEMPT_FAILURE_COUNT", attemptFailureCount);
                oPC.SetLocalObject("RESOURCE_ATTEMPT_FAILURE_OBJECT", failureResource.Object);
            }

            if (chance <= 0)
            {
                oPC.FloatingText("You do not have enough skill to harvest this resource...");
            }
            else if (_random.Random(100) <= chance || givePityItem)
            {
                if (hasBaggerPerk)
                {
                    _.CreateItemOnObject(resourceItemResref, oPC.Object);
                }
                else
                {
                    _.CreateObject(OBJECT_TYPE_ITEM, resourceItemResref, location);
                }


                oPC.FloatingText("You break off some " + resourceName + ".");
                resource.SetLocalInt("RESOURCE_COUNT", --resourceCount);
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectHeal(10000), resource.Object);

                if (_random.Random(100) + 1 <= secondResourceChance)
                {
                    oPC.FloatingText("You break off a second piece.");

                    if (hasBaggerPerk)
                    {
                        _.CreateItemOnObject(resourceItemResref, oPC.Object);
                    }
                    else
                    {
                        _.CreateObject(OBJECT_TYPE_ITEM, resourceItemResref, location);
                    }
                }

                float deltaModifier = CalculateXPDeltaModifier(difficultyRating, skill.Rank);
                float baseXP        = (100 + _random.Random(20)) * deltaModifier;
                int   xp            = (int)_skill.CalculateRegisteredSkillLevelAdjustedXP(baseXP, oWeapon.RecommendedLevel, skill.Rank);
                _skill.GiveSkillXP(oPC, skillType, xp);

                oPC.DeleteLocalInt("RESOURCE_ATTEMPT_FAILURE_COUNT");
                oPC.DeleteLocalObject("RESOURCE_ATTEMPT_FAILURE_OBJECT");
            }

            if (resourceCount <= 0)
            {
                SpawnSeed(resource, oPC);

                NWObject prop = NWObject.Wrap(resource.GetLocalObject("RESOURCE_PROP_OBJ"));
                if (prop.IsValid)
                {
                    prop.Destroy();
                }
                resource.Destroy();
            }
            return(true);
        }