Beispiel #1
0
        /// <summary>
        /// Processes and runs the specific chat command entered by the user.
        /// </summary>
        /// <param name="commandName">Name of the command</param>
        /// <param name="sender">The sender object</param>
        /// <param name="target">The target of the command. OBJECT_INVALID if no target is necessary.</param>
        /// <param name="targetLocation">The target location of the command. null if no target is necessary.</param>
        /// <param name="args">User-entered arguments</param>
        private static void ProcessChatCommand(string commandName, uint sender, uint target, Location targetLocation, string args)
        {
            var command = ChatCommands[commandName];

            if (targetLocation == null)
            {
                targetLocation = new Location(IntPtr.Zero);
            }

            var authorization = Authorization.GetAuthorizationLevel(sender);

            if (command.Permissions.HasFlag(CommandPermissionType.Player) && authorization == AuthorizationLevel.Player ||
                command.Permissions.HasFlag(CommandPermissionType.DM) && authorization == AuthorizationLevel.DM ||
                command.Permissions.HasFlag(CommandPermissionType.Admin) && authorization == AuthorizationLevel.Admin)
            {
                string[] argsArr = string.IsNullOrWhiteSpace(args) ? new string[0] : args.Split(' ').ToArray();
                string   error   = command.ValidateArguments(sender, argsArr);

                if (!string.IsNullOrWhiteSpace(error))
                {
                    SendMessageToPC(sender, error);
                }
                else
                {
                    command.DoAction(sender, target, targetLocation, argsArr);
                }
            }
            else
            {
                SendMessageToPC(sender, ColorToken.Red("Invalid chat command. Use '/help' to get a list of available commands."));
            }
        }
        /// <summary>
        /// Handles the card list logic.
        /// </summary>
        /// <param name="page">The page to build</param>
        private void ViewCardsPageInit(DialogPage page)
        {
            var model               = GetDataModel <Model>();
            var player              = GetPC();
            var playerId            = GetObjectUUID(player);
            var dbPlayerTripleTriad = DB.Get <PlayerTripleTriad>(playerId) ?? new PlayerTripleTriad();
            var availableCards      = TripleTriad.GetAllCardsAtLevel(model.SelectedCardLevel);

            page.Header = $"{ColorToken.Green("Level: ")} {model.SelectedCardLevel}\n\n" +
                          $"The following is the list of cards available at this level. Cards in {ColorToken.Green("GREEN")} have been acquired. Those in {ColorToken.Red("RED")} have not. Only one card per type can be collected.\n\n" +
                          "Please select a card.";

            foreach (var(type, card) in availableCards)
            {
                if (!card.IsVisibleInMenu)
                {
                    continue;
                }

                var option = dbPlayerTripleTriad.AvailableCards.ContainsKey(type)
                    ? ColorToken.Green(card.Name)
                    : ColorToken.Red(card.Name);

                page.AddResponse(option, () =>
                {
                    model.SelectedCardType = type;
                    SetLocalInt(player, "CARD_MENU_SELECTED_CARD_ID", (int)model.SelectedCardType);
                    ChangePage(ViewCardDetailsPageId);
                });
            }
        }
Beispiel #3
0
        /// <summary>
        /// Handles the "Sell House Page" header and responses.
        /// </summary>
        /// <param name="page">The page we're building.</param>
        private void SellHousePageInit(DialogPage page)
        {
            var player   = GetPC();
            var playerId = GetObjectUUID(player);
            var dbHouse  = DB.Get <PlayerHouse>(playerId);
            var model    = GetDataModel <Model>();

            var houseDetail = Housing.GetHouseTypeDetail(dbHouse.HouseType);
            var gil         = houseDetail.Price / 2;

            page.Header = ColorToken.Red("WARNING: ") + "You are about to sell your property. All items contained inside will be permanently lost!\n\n" +
                          "It is highly recommended you pick up all items and furniture inside before selling the property.\n\n" +
                          ColorToken.Green($"You will receive {gil} gil for the sale of this property. Are you sure you wish to sell it?");

            if (model.IsConfirmingSell)
            {
                page.AddResponse(ColorToken.Red($"CONFIRM SELL PROPERTY"), () =>
                {
                    DB.Delete <PlayerHouse>(playerId);

                    GiveGoldToCreature(player, gil);
                    FloatingTextStringOnCreature($"Property sold successfully for {gil} gil.", player, false);
                    EndConversation();

                    Log.Write(LogGroup.PlayerHousing, $"Player {GetName(player)} (ID = '{playerId}') sold their property for {gil} gil.");
                });
            }
            else
            {
                page.AddResponse(ColorToken.Red("Sell Property"), () =>
                {
                    model.IsConfirmingSell = true;
                });
            }
        }
 public string ValidateArguments(NWGameObject user, params string[] args)
 {
     if (args.Length <= 0)
     {
         return(ColorToken.Red("Please specify a quantity. Example: /" + nameof(SpawnGold) + " 34"));
     }
     return(string.Empty);
 }
Beispiel #5
0
        public string ValidateArguments(NWGameObject user, params string[] args)
        {
            if (args.Length <= 0)
            {
                return(ColorToken.Red("Please specify a resref and optionally a quantity. Example: /" + nameof(SpawnItem) + " my_resref 20"));
            }

            return(string.Empty);
        }
Beispiel #6
0
        private static string HandleArgumentValidation(uint user, params string[] args)
        {
            if (args.Length <= 0)
            {
                return(ColorToken.Red("Please specify a resref and optionally a quantity. Example: /spawnitem my_resref 20"));
            }

            return(string.Empty);
        }
Beispiel #7
0
        private string GetLeaseStatus()
        {
            var player        = GetPC();
            var playerId      = GetObjectUUID(player);
            var dbPlayerStore = DB.Get <PlayerStore>(playerId);
            var leaseStatus   = DateTime.UtcNow > dbPlayerStore.DateLeaseExpires
                ? ColorToken.Red("EXPIRED")
                : dbPlayerStore.DateLeaseExpires.ToString("MM/dd/yyyy hh:mm:ss");

            return(leaseStatus);
        }
Beispiel #8
0
        /// <summary>
        /// Validates whether all requirements to use ability are met.
        /// Returns true if successful, false otherwise.
        /// </summary>
        /// <param name="stats">The user's ability stats</param>
        /// <returns>true if successful, false otherwise</returns>
        private static bool ValidateFeatUse(UserStats stats)
        {
            var user    = stats.User;
            var ability = stats.AbilityDefinition;
            var target  = stats.Target;
            var canUse  = ability.CanUse(user, target);

            if (stats.MP < stats.MPCost)
            {
                SendMessageToPC(user, ColorToken.Red("Insufficient MP."));
                return(false);
            }

            if (!GetIsObjectValid(user))
            {
                return(false);
            }

            if (!GetIsObjectValid(target))
            {
                SendMessageToPC(user, ColorToken.Red("Target lost."));
                return(false);
            }

            if (!string.IsNullOrWhiteSpace(canUse))
            {
                SendMessageToPC(user, ColorToken.Red(canUse));
                return(false);
            }

            if (stats.Now < stats.CooldownUnlock)
            {
                var timeToWait = Time.GetTimeToWaitLongIntervals(stats.Now, stats.CooldownUnlock, false);
                SendMessageToPC(user, ColorToken.Red($"Ability available in {timeToWait}."));
                return(false);
            }

            if (!LineOfSightObject(user, target))
            {
                SendMessageToPC(user, ColorToken.Red($"You cannot see your target."));
                return(false);
            }

            if (GetIsBusy(user) || GetCurrentHitPoints(user) <= 0 || !GetCommandable(user))
            {
                SendMessageToPC(user, ColorToken.Red("You are too busy."));
                return(false);
            }

            return(true);
        }
        public static void ValidateDualWield()
        {
            var creature = OBJECT_SELF;
            var item     = StringToObject(Events.GetEventData("ITEM"));
            var slot     = (InventorySlot)Convert.ToInt32(Events.GetEventData("SLOT"));

            // Not equipping to the left hand, or there's nothing equipped in the right hand.
            if (slot != InventorySlot.LeftHand)
            {
                return;
            }
            if (!GetIsObjectValid(GetItemInSlot(InventorySlot.RightHand, creature)))
            {
                return;
            }

            var baseItem         = GetBaseItemType(item);
            var dualWieldWeapons = new[]
            {
                BaseItem.ShortSword,
                BaseItem.Longsword,
                BaseItem.BattleAxe,
                BaseItem.BastardSword,
                BaseItem.LightFlail,
                BaseItem.LightMace,
                BaseItem.Dagger,
                BaseItem.Club,
                BaseItem.HandAxe,
                BaseItem.Kama,
                BaseItem.Katana,
                BaseItem.Kukri,
                BaseItem.Rapier,
                BaseItem.Scimitar,
                BaseItem.Sickle
            };

            if (!dualWieldWeapons.Contains(baseItem))
            {
                return;
            }

            var dualWieldLevel = Perk.GetEffectivePerkLevel(creature, PerkType.DualWield);

            if (dualWieldLevel <= 0)
            {
                SendMessageToPC(creature, ColorToken.Red("Equipping two weapons requires the Dual Wield perk."));
                Events.SkipEvent();
            }
        }
        /// <summary>
        /// Handles the card details logic.
        /// </summary>
        /// <param name="page">The page to build</param>
        private void ViewCardDetailsPageInit(DialogPage page)
        {
            var player              = GetPC();
            var playerId            = GetObjectUUID(player);
            var dbPlayerTripleTriad = DB.Get <PlayerTripleTriad>(playerId);
            var model        = GetDataModel <Model>();
            var card         = TripleTriad.GetCardByType(model.SelectedCardType);
            var dateAcquired = dbPlayerTripleTriad.AvailableCards.ContainsKey(model.SelectedCardType)
                ? dbPlayerTripleTriad.AvailableCards[model.SelectedCardType].ToString("yyyy-MM-dd hh:mm:ss")
                : ColorToken.Red("Unacquired");

            page.Header = $"{ColorToken.Green("Name: ")} {card.Name}\n" +
                          $"{ColorToken.Green("Level: ")} {card.Level}\n" +
                          $"{ColorToken.Green("Date Acquired: ")} {dateAcquired}";
        }
        public static void ValidateItemEquip()
        {
            var creature = OBJECT_SELF;
            var item     = StringToObject(Events.GetEventData("ITEM"));

            var error = CanItemBeUsed(creature, item);

            if (string.IsNullOrWhiteSpace(error))
            {
                ApplyEquipTriggers();
                return;
            }

            SendMessageToPC(creature, ColorToken.Red(error));
            Events.SkipEvent();
        }
Beispiel #12
0
        public static void TakeItem()
        {
            var disturbType = GetInventoryDisturbType();

            if (disturbType != DisturbType.Removed)
            {
                return;
            }

            var player = GetLastDisturbed();
            var item   = GetInventoryDisturbItem();
            var resref = GetResRef(item);
            var device = OBJECT_SELF;
            var state  = Craft.GetPlayerCraftingState(player);

            if (state.IsAutoCrafting)
            {
                SendMessageToPC(player, ColorToken.Red("You are auto-crafting."));
                return;
            }

            // Auto-craft item
            if (resref == AutoCraftItemResref)
            {
                Item.ReturnItem(device, item);
                AutoCraftItem(player);
            }
            // Manually craft the item
            else if (resref == CraftItemResref)
            {
                Item.ReturnItem(device, item);
                CraftItem(player);
            }
            // Load components into container
            else if (resref == LoadComponentsResref)
            {
                Item.ReturnItem(device, item);
                LoadComponents(player);
            }
            // Select a different recipe
            else if (resref == SelectRecipeResref)
            {
                Item.ReturnItem(device, item);
                SelectRecipe(player);
            }
        }
        /// <summary>
        /// Handles the card selection logic for deck building.
        /// This differs from the card viewer in that cards show based on which cards the player owns.
        /// </summary>
        /// <param name="page">The page to build.</param>
        private void DeckCardSelectionListPageInit(DialogPage page)
        {
            var player              = GetPC();
            var playerId            = GetObjectUUID(player);
            var dbPlayerTripleTriad = DB.Get <PlayerTripleTriad>(playerId);
            var model        = GetDataModel <Model>();
            var cardsAtLevel = TripleTriad.GetAllCardsAtLevel(model.SelectedCardLevel);

            page.Header = $"{ColorToken.Green("Level: ")} {model.SelectedCardLevel}\n\n" +
                          "Please select cards to add to this deck.";

            if (model.CurrentCardNumber > 1)
            {
                page.AddResponse(ColorToken.Red("Remove Card"), RemoveTopMostCard);
            }

            foreach (var(cardType, card) in cardsAtLevel)
            {
                if (!card.IsVisibleInMenu)
                {
                    continue;
                }

                // Only one of each card type can be added to decks.
                if (IsInActiveDeck(cardType))
                {
                    continue;
                }

                if (dbPlayerTripleTriad.AvailableCards.ContainsKey(cardType))
                {
                    page.AddResponse($"Add: {card.Name}", () =>
                    {
                        SetLocalInt(player, $"CARD_MENU_DECK_CARD_{model.CurrentCardNumber}", (int)cardType);
                        model.CurrentCardNumber++;

                        // This was the last card.
                        if (model.CurrentCardNumber > 5)
                        {
                            ChangePage(DeckCardSelectionConfirmDeckPageId);
                        }
                    });
                }
            }
        }
        /// <summary>
        /// Handles the card selection level logic for deck building.
        /// This differs from the card viewer in that levels show based on which cards the player owns.
        /// </summary>
        /// <param name="page">The page to build.</param>
        private void DeckCardSelectionLevelsPageInit(DialogPage page)
        {
            var player              = GetPC();
            var playerId            = GetObjectUUID(player);
            var dbPlayerTripleTriad = DB.Get <PlayerTripleTriad>(playerId);
            var model  = GetDataModel <Model>();
            var levels = new HashSet <int>();

            page.Header = "Please select cards to add to this deck.";

            if (model.CurrentCardNumber > 1)
            {
                page.AddResponse(ColorToken.Red("Remove Card"), RemoveTopMostCard);
            }

            foreach (var(cardType, _) in dbPlayerTripleTriad.AvailableCards)
            {
                var card = TripleTriad.GetCardByType(cardType);

                if (!card.IsVisibleInMenu)
                {
                    continue;
                }

                if (!levels.Contains(card.Level))
                {
                    levels.Add(card.Level);
                }
            }

            page.Header = $"{ColorToken.Green("Select card #")} {model.CurrentCardNumber}";

            foreach (var level in levels)
            {
                page.AddResponse($"Level {level}", () =>
                {
                    model.SelectedCardLevel = level;
                    ChangePage(DeckCardSelectionListPageId);
                });
            }
        }
        private void MainPageInit(DialogPage page)
        {
            var player             = GetPC();
            var cdKey              = GetPCPublicCDKey(player);
            var account            = DB.Get <Account>(cdKey) ?? new Account();
            var achievements       = account.Achievements;
            var activeAchievements = Achievement.GetActiveAchievements();
            var model              = GetDataModel <Model>();

            foreach (var achievement in activeAchievements)
            {
                var text = achievements.ContainsKey(achievement.Key) ?
                           ColorToken.Green(achievement.Value.Name) :
                           ColorToken.Red(achievement.Value.Name);
                page.AddResponse(text, () =>
                {
                    model.Type = achievement.Key;
                    ChangePage(AchievementDetailId);
                });
            }
        }
        private void AchievementDetailInit(DialogPage page)
        {
            var player             = GetPC();
            var cdKey              = GetPCPublicCDKey(player);
            var account            = DB.Get <Account>(cdKey) ?? new Account();
            var activeAchievements = Achievement.GetActiveAchievements();
            var model              = GetDataModel <Model>();
            var achievement        = activeAchievements[model.Type];

            page.Header = ColorToken.Green("Name: ") + achievement.Name + "\n" +
                          ColorToken.Green("Description: ") + achievement.Description + "\n\n";

            if (account.Achievements.ContainsKey(model.Type))
            {
                var pcAchievement = account.Achievements[model.Type];
                page.Header += ColorToken.Green("Unlocked: ") + pcAchievement.ToString("yyyy-MM-dd hh:mm:ss");
            }
            else
            {
                page.Header += ColorToken.Red("Not yet acquired.");
            }
        }
Beispiel #17
0
        private static void HandleAction(uint user, uint target, Location targetLocation, params string[] args)
        {
            string resref   = args[0];
            int    quantity = 1;

            if (args.Length > 1)
            {
                if (!int.TryParse(args[1], out quantity))
                {
                    return;
                }
            }

            uint item = (CreateItemOnObject(resref, user, quantity));

            if (!GetIsObjectValid(item))
            {
                SendMessageToPC(user, ColorToken.Red("Item not found! Did you enter the correct ResRef?"));
                return;
            }

            SetIdentified(item, true);
        }
        private static void ProcessChatCommand(IChatCommand command, NWGameObject sender, NWGameObject target, Location targetLocation, string args)
        {
            if (target == null)
            {
                target = new NWGameObject();
            }

            if (targetLocation == null)
            {
                targetLocation = new Location();
            }

            CommandDetailsAttribute attribute = command.GetType().GetCustomAttribute <CommandDetailsAttribute>();
            var authorization = AuthorizationRegistry.GetAuthorizationLevel(sender);

            if (attribute != null &&
                (attribute.Permissions.HasFlag(CommandPermissionType.Player) && authorization == AuthorizationLevel.Player ||
                 attribute.Permissions.HasFlag(CommandPermissionType.DM) && authorization == AuthorizationLevel.DM ||
                 attribute.Permissions.HasFlag(CommandPermissionType.Admin) && authorization == AuthorizationLevel.Admin))
            {
                string[] argsArr = string.IsNullOrWhiteSpace(args) ? new string[0] : args.Split(' ').ToArray();
                string   error   = command.ValidateArguments(sender, argsArr);

                if (!string.IsNullOrWhiteSpace(error))
                {
                    SendMessageToPC(sender, error);
                }
                else
                {
                    command.DoAction(sender, target, targetLocation, argsArr);
                }
            }
            else
            {
                SendMessageToPC(sender, ColorToken.Red("Invalid chat command. Use '/help' to get a list of available commands."));
            }
        }
Beispiel #19
0
 public Dice()
 {
     _genericError = ColorToken.Red("Please enter /dice help for more information on how to use this command.");
 }
Beispiel #20
0
        /// <summary>
        /// Handles the auto-craft procedure. This is an automatic (no mini-game) form of crafting
        /// where success is determined by a player's stats. This simply creates the item on a successful crafting attempt.
        /// </summary>
        /// <param name="player">The player performing the auto-craft.</param>
        private static void AutoCraftItem(uint player)
        {
            var state  = Craft.GetPlayerCraftingState(player);
            var device = OBJECT_SELF;

            float CalculateAutoCraftingDelay()
            {
                var baseDelay = 20f;
                var perk      = _autoCraftPerk[state.DeviceSkillType];

                switch (Perk.GetEffectivePerkLevel(player, perk))
                {
                case 2: baseDelay -= 4; break;

                case 3: baseDelay -= 8; break;

                case 4: baseDelay -= 12; break;

                case 5: baseDelay -= 16; break;
                }

                return(baseDelay);
            }

            void CraftItem(bool isSuccessful)
            {
                var recipe = Craft.GetRecipe(state.SelectedRecipe);

                var playerComponents    = GetComponents(player, device);
                var remainingComponents = recipe.Components.ToDictionary(x => x.Key, y => y.Value);

                for (var index = playerComponents.Count - 1; index >= 0; index--)
                {
                    var component = playerComponents[index];
                    var resref    = GetResRef(component);

                    // Item does not need any more of this component type.
                    if (!remainingComponents.ContainsKey(resref))
                    {
                        continue;
                    }

                    var quantity = GetItemStackSize(component);

                    // Player's component stack size is greater than the amount required.
                    if (quantity > remainingComponents[resref])
                    {
                        SetItemStackSize(component, quantity - remainingComponents[resref]);
                        remainingComponents[resref] = 0;
                    }
                    // Player's component stack size is less than or equal to the amount required.
                    else if (quantity <= remainingComponents[resref])
                    {
                        remainingComponents[resref] -= quantity;
                        DestroyObject(component);
                    }

                    if (remainingComponents[resref] <= 0)
                    {
                        remainingComponents.Remove(resref);
                    }
                }

                if (isSuccessful)
                {
                    CreateItemOnObject(recipe.Resref, player, recipe.Quantity);
                }
            }

            if (!HasAllComponents(player, device))
            {
                SendMessageToPC(player, ColorToken.Red("You are missing some necessary components..."));
                return;
            }

            var craftingDelay = CalculateAutoCraftingDelay();

            state.IsAutoCrafting = true;
            Player.StartGuiTimingBar(player, craftingDelay);
            AssignCommand(player, () => ActionPlayAnimation(Animation.LoopingGetMid, 1f, craftingDelay));
            DelayCommand(craftingDelay, () =>
            {
                // Player logged out.
                if (!GetIsObjectValid(player))
                {
                    Craft.ClearPlayerCraftingState(player);
                    return;
                }

                var chanceToCraft = Craft.CalculateChanceToCraft(player, state.SelectedRecipe);
                var roll          = Random.NextFloat(0f, 100f);

                if (roll <= chanceToCraft)
                {
                    CraftItem(true);
                }
                else
                {
                    CraftItem(false);
                    SendMessageToPC(player, ColorToken.Red("You failed to craft the item..."));
                }

                state.IsAutoCrafting = false;
            });
            ApplyEffectToObject(DurationType.Temporary, EffectCutsceneParalyze(), player, craftingDelay);
        }
Beispiel #21
0
        /// <summary>
        /// Sends a message to a player informing them of the current number of items in the container and the maximum allowed.
        /// If incrementByOne is true, the current count will be increased by one. This is to account for the fact that
        /// the OnAddItem event fires before the item is actually added to the inventory (therefore it would have an off-by-one error)
        /// </summary>
        /// <param name="player">The player receiving the message</param>
        /// <param name="incrementByOne">Increments current item count by one if true, else does nothing.</param>
        protected static void SendItemLimitMessage(NWGameObject player, bool incrementByOne)
        {
            var container = NWGameObject.OBJECT_SELF;
            var limit     = GetItemLimit();
            var count     = _.GetInventoryItemCount(container);

            // The Add event fires before the item exists in the container. Need to increment by one in this scenario.
            if (incrementByOne)
            {
                count++;
            }

            _.SendMessageToPC(player, ColorToken.White("Item Limit: " + (count > limit ? limit : count) + " / ") + ColorToken.Red("" + limit));
        }
Beispiel #22
0
        /// <summary>
        /// Builds all chat commands and puts them into cache.
        /// </summary>
        private static void LoadChatCommands()
        {
            ChatCommands["bored"] = new ChatCommandDefinition(
                "Plays a bored animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetPauseBored));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["bow"] = new ChatCommandDefinition(
                "Plays a bow animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetBow));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["bug"] = new BugReportChatCommandDefinition();

            ChatCommands["cdkey"] = new ChatCommandDefinition(
                "Displays your public CD key.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                string cdKey = GetPCPublicCDKey(user);
                SendMessageToPC(user, "Your public CD Key is: " + cdKey);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["coord"] = new ChatCommandDefinition(
                "Displays your current coordinates in the area.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                Vector3 position = GetPosition(user);
                int cellX        = (int)(position.X / 10);
                int cellY        = (int)(position.Y / 10);

                SendMessageToPC(user, $"Current Area Coordinates: ({cellX}, {cellY})");
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["copyitem"] = new ChatCommandDefinition(
                "Copies the targeted item.",
                CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                if (GetObjectType(target) != ObjectType.Item)
                {
                    SendMessageToPC(user, "You can only copy items with this command.");
                    return;
                }

                CopyItem(target, user, true);
                SendMessageToPC(user, "Item copied successfully.");
            },
                (user, args) => string.Empty,
                true);

            ChatCommands["day"] = new ChatCommandDefinition(
                "Sets the world time to 8 AM.",
                CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                SetTime(8, 0, 0, 0);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["deadback"] = new ChatCommandDefinition(
                "Plays a dead back animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                LoopingAnimationAction(user, Animation.LoopingDeadBack, args);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["deadfront"] = new ChatCommandDefinition(
                "Plays a dead front animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                LoopingAnimationAction(user, Animation.LoopingDeadFront, args);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["delete"] = new CharacterDeletionChatCommandDefinition();

            ChatCommands["dice"] = new DiceChatCommandDefinition();


            ChatCommands["drink"] = new ChatCommandDefinition(
                "Plays a drinking animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetDrink));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["drunk"] = new ChatCommandDefinition(
                "Plays a drunk animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                LoopingAnimationAction(user, Animation.LoopingPauseDrunk, args);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["duck"] = new ChatCommandDefinition(
                "Plays a duck animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetDodgeDuck));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["getlocalfloat"]  = new GetLocalFloatChatCommandDefinition();
            ChatCommands["getlocalint"]    = new GetLocalIntChatCommandDefinition();
            ChatCommands["getlocalstring"] = new GetLocalStringChatCommandDefinition();

            ChatCommands["getplot"] = new ChatCommandDefinition(
                "Gets whether an object is marked plot.",
                CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                if (GetPlotFlag(target))
                {
                    SendMessageToPC(user, "Target is marked plot.");
                }
                else
                {
                    SendMessageToPC(user, "Target is NOT marked plot.");
                }
            },
                (user, args) => string.Empty,
                true);

            ChatCommands["greet"] = new ChatCommandDefinition(
                "Plays a greet animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetGreeting));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["help"] = new ChatCommandDefinition(
                "Displays all chat commands available to you.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                var authorization = Authorization.GetAuthorizationLevel(user);

                if (authorization == AuthorizationLevel.DM)
                {
                    SendMessageToPC(user, HelpTextDM);
                }
                else if (authorization == AuthorizationLevel.Admin)
                {
                    SendMessageToPC(user, HelpTextAdmin);
                }
                else
                {
                    SendMessageToPC(user, HelpTextPlayer);
                }
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["interact"] = new ChatCommandDefinition(
                "Plays an interact animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.LoopingGetMid));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["kill"] = new ChatCommandDefinition(
                "Kills your target.",
                CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                var amount = GetMaxHitPoints(target) + 11;
                var damage = EffectDamage(amount);
                ApplyEffectToObject(DurationType.Instant, damage, target);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["laughing"] = new ChatCommandDefinition(
                "Plays a laughing animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                LoopingAnimationAction(user, Animation.LoopingTalkLaughing, args);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["listen"] = new ChatCommandDefinition(
                "Plays a listen animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                LoopingAnimationAction(user, Animation.LoopingListen, args);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["look"] = new ChatCommandDefinition(
                "Plays a look far animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                LoopingAnimationAction(user, Animation.LoopingLookFar, args);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["name"] = new ChatCommandDefinition(
                "Plays a drunk animation.",
                CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                if (GetIsPC(target) || GetIsDM(target))
                {
                    SendMessageToPC(user, "PCs cannot be targeted with this command.");
                    return;
                }

                string name = string.Empty;
                foreach (var arg in args)
                {
                    name += " " + arg;
                }

                SetName(target, name);
            },
                (user, args) =>
            {
                if (args.Length <= 0)
                {
                    return("Please enter a name. Example: /name My Creature");
                }

                return(string.Empty);
            },
                false);

            ChatCommands["night"] = new ChatCommandDefinition(
                "Sets the world time to 8 AM.",
                CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                SetTime(20, 0, 0, 0);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["pickup"] = new ChatCommandDefinition(
                "Plays an interact animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.LoopingGetLow));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["pos"] = new ChatCommandDefinition(
                "Displays your current position in the area.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                var position = GetPosition(user);
                SendMessageToPC(user, $"Current Position: ({position.X}, {position.Y}, {position.Z})");
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["read"] = new ChatCommandDefinition(
                "Plays a read animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetRead));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["rest"] = new ChatCommandDefinition(
                "Opens the rest menu.",
                CommandPermissionType.Player,
                (user, target, location, args) =>
            {
                Dialog.StartConversation(user, user, nameof(RestMenu));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["rez"] = new ChatCommandDefinition(
                "Revives you, heals you to full, and restores all MP.",
                CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                if (GetIsDead(user))
                {
                    ApplyEffectToObject(DurationType.Instant, EffectResurrection(), user);
                }

                ApplyEffectToObject(DurationType.Instant, EffectHeal(999), user);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["salute"] = new ChatCommandDefinition(
                "Plays a salute animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetSalute));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["save"] = new ChatCommandDefinition(
                "Manually saves your character. Your character also saves automatically every few minutes.",
                CommandPermissionType.Player,
                (user, target, location, args) =>
            {
                ExportSingleCharacter(user);
                SendMessageToPC(user, "Character saved successfully.");
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["scratchhead"] = new ChatCommandDefinition(
                "Plays a scratch head animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetPauseScratchHead));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["setlocalfloat"]  = new SetLocalFloatChatCommandDefinition();
            ChatCommands["setlocalint"]    = new SetLocalIntChatCommandDefinition();
            ChatCommands["setlocalstring"] = new SetLocalStringChatCommandDefinition();

            ChatCommands["setportrait"] = new SetPortraitChatCommandDefinition();

            ChatCommands["sidestep"] = new ChatCommandDefinition(
                "Plays a side-step animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetDodgeSide));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["sit"] = new ChatCommandDefinition(
                "Makes your character sit down.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                LoopingAnimationAction(user, Animation.LoopingSitCross, args);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["spasm"] = new ChatCommandDefinition(
                "Plays a spasm animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetSpasm));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["spawngold"] = new ChatCommandDefinition(
                "Spawns gold of a specific quantity on your character. Example: /spawngold 33",
                CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                int quantity = 1;

                if (args.Length >= 1)
                {
                    if (!int.TryParse(args[0], out quantity))
                    {
                        return;
                    }
                }

                GiveGoldToCreature(user, quantity);
            },
                (user, args) =>
            {
                if (args.Length <= 0)
                {
                    return(ColorToken.Red("Please specify a quantity. Example: /spawngold 34"));
                }
                return(string.Empty);
            },
                false);

            ChatCommands["spawnitem"] = new SpawnItemChatCommandDefinition();

            ChatCommands["taunt"] = new ChatCommandDefinition(
                "Plays a taunt animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetTaunt));
            },
                (user, args) => string.Empty,
                false);


            ChatCommands["time"] = new ChatCommandDefinition(
                "Returns the current UTC server time.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                DateTime now   = DateTime.UtcNow;
                string nowText = now.ToString("yyyy-MM-dd hh:mm:ss");

                SendMessageToPC(user, "Current Server Date: " + nowText);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["tired"] = new ChatCommandDefinition(
                "Plays a taunt animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                LoopingAnimationAction(user, Animation.LoopingPauseTired, args);
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["tpwp"] = new ChatCommandDefinition(
                "Teleports you to a waypoint with a specified tag.",
                CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                string tag = args[0];
                uint wp    = GetWaypointByTag(tag);

                if (!GetIsObjectValid(wp))
                {
                    SendMessageToPC(user, "Invalid waypoint tag. Did you enter the right tag?");
                    return;
                }

                AssignCommand(user, () => ActionJumpToLocation(GetLocation(wp)));
            },
                (user, args) =>
            {
                if (args.Length < 1)
                {
                    return("You must specify a waypoint tag. Example: /tpwp MY_WAYPOINT_TAG");
                }

                return(string.Empty);
            },
                false);

            ChatCommands["victory1"] = new ChatCommandDefinition(
                "Plays a victory 1 animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetVictory1));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["victory2"] = new ChatCommandDefinition(
                "Plays a victory 2 animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetVictory2));
            },
                (user, args) => string.Empty,
                false);

            ChatCommands["victory3"] = new ChatCommandDefinition(
                "Plays a victory 3 animation.",
                CommandPermissionType.Player | CommandPermissionType.DM | CommandPermissionType.Admin,
                (user, target, location, args) =>
            {
                AssignCommand(user, () => ActionPlayAnimation(Animation.FireForgetVictory3));
            },
                (user, args) => string.Empty,
                false);
        }
Beispiel #23
0
        public override async Task <int> Main()
        {
            var results = new List <ColorToken[]>
            {
                new []
                {
                    "NAME".White(),
                    "CURRENT".White(),
                    "WANTED".White(),
                    "LATEST".White()
                }
            };

            var definition = LoadDefinition();

            foreach (var dependency in definition?.Dependencies ?? new Dictionary <Name, VersionRange>())
            {
                var repo    = definition?.Repositories?.FirstOrDefault(r => r.Name.ToString() == dependency.Key.ToString());
                var adapter = new AdapterBuilder(dependency.Key, repo).Adapter();

                var versions     = (await adapter.GetVersions()).ToList();
                var versionMatch = versions.LastOrDefault(version => dependency.Value.IsSatisfied(version));
                if (versionMatch == null)
                {
                    throw new Exception("No matching version found");
                }

                var        current = "MISSING".Red();
                ColorToken wanted  = versionMatch.ToString();
                ColorToken latest  = versions.Last().ToString();

                var pluginDefinition = new FileInfo(Path.Combine(Environment.CurrentDirectory, ConfigurationManager.PluginPath, dependency.Key.Vendor, dependency.Key.Project, ConfigurationManager.DefinitionFile));

                if (pluginDefinition.Exists)
                {
                    var plugin = Plugin.Load(pluginDefinition.FullName);

                    current = plugin.Version.ToString();

                    current = current.Text != wanted.Text ? current.Red() : current.Green();
                    wanted  = wanted.Text != latest.Text ? wanted.Red() : wanted.Green();

                    if (!this.All && current.Text == wanted.Text && wanted.Text == latest.Text)
                    {
                        continue;
                    }
                }

                results.Add(new[]
                {
                    dependency.Key.ToString(),
                    current,
                    wanted,
                    latest
                });
            }

            if (results.Count < 2)
            {
                return(0);
            }

            var nameLength    = Math.Max(Math.Min(50, results.Max(d => d[0].Text.Length)), 10);
            var currentLength = Math.Max(Math.Min(20, results.Max(d => d[1].Text.ToString().Length)), 7);
            var wantedLength  = Math.Max(Math.Min(20, results.Max(d => d[2].Text.ToString().Length)), 7);
            var latestLength  = Math.Max(Math.Min(20, results.Max(d => d[3].Text.ToString().Length)), 7);

            foreach (var result in results)
            {
                result[0].Text = result[0].Text.Truncate(nameLength).PadRight(nameLength);
                result[1].Text = result[1].Text.Truncate(currentLength).PadLeft(currentLength);
                result[2].Text = result[2].Text.Truncate(wantedLength).PadLeft(wantedLength);
                result[3].Text = result[3].Text.Truncate(latestLength).PadLeft(latestLength);

                Console.WriteLine(result[0], " | ", result[1], " | ", result[2], " | ", result[3]);
            }

            return(await Task.FromResult(0));
        }
Beispiel #24
0
        public static void HandleChatMessage()
        {
            uint   sender          = OBJECT_SELF;
            string originalMessage = Chat.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);

            Chat.SkipMessage();

            if (!ChatCommands.ContainsKey(command))
            {
                SendMessageToPC(sender, ColorToken.Red("Invalid chat command. Use '/help' to get a list of available commands."));
                return;
            }

            var chatCommand = ChatCommands[command];

            string args = string.Join(" ", split);

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

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

                if (!GetHasFeat(Feat.ChatCommandTargeter, sender) || GetIsDM(sender) || GetIsDMPossessed(sender))
                {
                    Creature.AddFeatByLevel(sender, Feat.ChatCommandTargeter, 1);

                    if (GetIsDM(sender) || GetIsDMPossessed(sender))
                    {
                        var qbs = Player.GetQuickBarSlot(sender, 11);
                        if (qbs.ObjectType == QuickBarSlotType.Empty)
                        {
                            Player.SetQuickBarSlot(sender, 11, PlayerQuickBarSlot.UseFeat(Feat.ChatCommandTargeter));
                        }
                    }
                }
            }
        }
Beispiel #25
0
        private void RecipePageInit(DialogPage page)
        {
            var model             = GetDataModel <Model>();
            var player            = GetPC();
            var meetsRequirements = true;

            string BuildHeader()
            {
                var recipe   = Craft.GetRecipe(model.SelectedRecipe);
                var category = Craft.GetCategoryDetail(recipe.Category);
                var skill    = Skill.GetSkillDetails(recipe.Skill);

                // Recipe quantity and name.
                var header = $"{ColorToken.Green("Recipe:")} {recipe.Quantity}x {recipe.Name} \n";

                // Associated skill
                header += $"{ColorToken.Green("Craft:")} {skill.Name}\n";

                // Associated category
                header += $"{ColorToken.Green("Category:")} {category.Name}\n";

                // Recipe's description, if available.
                if (!string.IsNullOrWhiteSpace(recipe.Description))
                {
                    header += $"{ColorToken.Green("Description:")} {recipe.Description} \n";
                }

                // Chance to craft
                header += $"{ColorToken.Green("Chance to Auto-Craft:")} {Craft.CalculateChanceToCraft(player, model.SelectedRecipe)}%";

                // List of requirements, if applicable.
                if (recipe.Requirements.Count > 0)
                {
                    header += $"\n{ColorToken.Green("Requirements:")}\n\n";

                    foreach (var req in recipe.Requirements)
                    {
                        // If the player meets the requirement, show it in green. Otherwise show it in red.
                        if (string.IsNullOrWhiteSpace(req.CheckRequirements(player)))
                        {
                            header += $"{ColorToken.Green(req.RequirementText)}\n";
                        }
                        else
                        {
                            header           += $"{ColorToken.Red(req.RequirementText)}\n";
                            meetsRequirements = false;
                        }
                    }
                }

                // List of components
                header += $"\n\n{ColorToken.Green("Components:")}\n\n";

                foreach (var(resref, quantity) in recipe.Components)
                {
                    var name = Cache.GetItemNameByResref(resref);
                    header += $"{quantity}x {name}\n";
                }

                return(header);
            }

            page.Header = BuildHeader();

            if (model.IsFabricator && meetsRequirements)
            {
                page.AddResponse("Select Recipe", () =>
                {
                    var state            = Craft.GetPlayerCraftingState(player);
                    state.SelectedRecipe = model.SelectedRecipe;

                    EndConversation();
                    Player.ForcePlaceableInventoryWindow(player, OBJECT_SELF);
                });
            }
        }
Beispiel #26
0
        private void ListingInit(DialogPage page)
        {
            var player        = GetPC();
            var playerId      = GetObjectUUID(player);
            var dbPlayerStore = DB.Get <PlayerStore>(playerId);
            var model         = GetDataModel <Model>();
            var item          = dbPlayerStore.ItemsForSale[model.SelectedItemId];

            void AdjustPrice(int amount)
            {
                item.Price += amount;

                if (item.Price <= 0)
                {
                    item.Price = 1;
                }
                else if (item.Price > 999999)
                {
                    item.Price = 999999;
                }

                DB.Set(playerId, dbPlayerStore);
                PlayerMarket.UpdateCacheEntry(playerId, dbPlayerStore);
            }

            page.Header = ColorToken.Green("Item: ") + item.StackSize + "x " + item.Name + "\n" +
                          ColorToken.Green("Price: ") + item.Price + "\n\n" +
                          "Please select an option.";

            if (model.IsConfirmingRemoveItem)
            {
                page.AddResponse(ColorToken.Red("CONFIRM REMOVE ITEM"), () =>
                {
                    var inWorldItem = Object.Deserialize(item.Data);
                    Object.AcquireItem(player, inWorldItem);
                    dbPlayerStore.ItemsForSale.Remove(model.SelectedItemId);

                    DB.Set(playerId, dbPlayerStore);
                    PlayerMarket.UpdateCacheEntry(playerId, dbPlayerStore);

                    ChangePage(EditItemListPageId, false);
                    model.IsConfirmingRemoveItem = false;
                });
            }
            else
            {
                page.AddResponse(ColorToken.Red("Remove Item"), () =>
                {
                    model.IsConfirmingRemoveItem = true;
                });
            }

            page.AddResponse("Increase by 10,000 gil", () =>
            {
                AdjustPrice(10000);
            });
            page.AddResponse("Increase by 1,000 gil", () =>
            {
                AdjustPrice(1000);
            });
            page.AddResponse("Increase by 100 gil", () =>
            {
                AdjustPrice(100);
            });
            page.AddResponse("Increase by 10 gil", () =>
            {
                AdjustPrice(10);
            });
            page.AddResponse("Increase by 1 gil", () =>
            {
                AdjustPrice(1);
            });

            page.AddResponse("Decrease by 10,000 gil", () =>
            {
                AdjustPrice(-10000);
            });
            page.AddResponse("Decrease by 1,000 gil", () =>
            {
                AdjustPrice(-1000);
            });
            page.AddResponse("Decrease by 100 gil", () =>
            {
                AdjustPrice(-100);
            });
            page.AddResponse("Decrease by 10 gil", () =>
            {
                AdjustPrice(-10);
            });
            page.AddResponse("Decrease by 1 gil", () =>
            {
                AdjustPrice(-1);
            });
        }
        private void PerkDetailsPageInit(DialogPage page)
        {
            var player            = GetPC();
            var model             = GetDataModel <Model>();
            var perkDetail        = Perk.GetPerkDetails(model.SelectedPerk);
            var playerId          = GetObjectUUID(player);
            var dbPlayer          = DB.Get <Player>(playerId);
            var categoryDetail    = Perk.GetPerkCategoryDetails(model.SelectedCategory);
            var rank              = dbPlayer.Perks.ContainsKey(model.SelectedPerk) ? dbPlayer.Perks[model.SelectedPerk] : 0;
            var maxRank           = perkDetail.PerkLevels.Count;
            var currentLevel      = perkDetail.PerkLevels.ContainsKey(rank) ? perkDetail.PerkLevels[rank] : null;
            var nextLevel         = perkDetail.PerkLevels.ContainsKey(rank + 1) ? perkDetail.PerkLevels[rank + 1] : null;
            var price             = nextLevel == null ? "N/A" : $"{nextLevel.Price} SP (Available: {dbPlayer.UnallocatedSP} SP)";
            var meetsRequirements = true;

            string BuildPerkSection(bool isCurrent, PerkLevel perkLevel)
            {
                var currentOrNext = isCurrent ? "Current" : "Next";
                var bonus         = perkLevel == null ? "N/A" : perkLevel.Description;

                return(ColorToken.Green($"{currentOrNext} Bonus: ") + bonus + "\n");
            }

            string BuildRequirements(List <IPerkRequirement> requirements)
            {
                if (requirements == null)
                {
                    return(string.Empty);
                }

                string text = ColorToken.Green("Requirements:\n\n");

                if (requirements.Count <= 0)
                {
                    text += "N/A";
                }

                foreach (var req in requirements)
                {
                    var requirementMet = string.IsNullOrWhiteSpace(req.CheckRequirements(player));
                    var reqText        = requirementMet ? ColorToken.Green(req.RequirementText) : ColorToken.Red(req.RequirementText);
                    text += reqText + "\n";

                    if (!requirementMet)
                    {
                        meetsRequirements = false;
                    }
                }

                return(text);
            }

            void PurchaseUpgrade()
            {
                if (model.IsConfirmingPurchase)
                {
                    model.IsConfirmingPurchase = false;
                    DoPerkUpgrade();
                }
                else
                {
                    model.IsConfirmingPurchase = true;
                }
            }

            bool CanUpgrade()
            {
                if (!meetsRequirements)
                {
                    return(false);
                }
                if (rank + 1 > maxRank)
                {
                    return(false);
                }
                if (nextLevel == null)
                {
                    return(false);
                }
                if (dbPlayer.UnallocatedSP < nextLevel.Price)
                {
                    return(false);
                }

                return(true);
            }

            void DoPerkUpgrade()
            {
                if (!CanUpgrade() || nextLevel == null)
                {
                    FloatingTextStringOnCreature("You do not meet the requirements to purchase this perk upgrade.", player, false);
                    return;
                }

                int perkRank = dbPlayer.Perks.ContainsKey(model.SelectedPerk) ? dbPlayer.Perks[model.SelectedPerk] : 0;

                dbPlayer.Perks[model.SelectedPerk] = perkRank + 1;
                dbPlayer.UnallocatedSP            -= nextLevel.Price;
                DB.Set(playerId, dbPlayer);

                GrantFeats();
                ApplyPurchasePerkTriggers(dbPlayer.Perks[model.SelectedPerk]);

                Events.SignalEvent("FFO_BUY_PERK", player);
            }

            void GrantFeats()
            {
                foreach (var feat in nextLevel.GrantedFeats)
                {
                    if (GetHasFeat(feat, player))
                    {
                        continue;
                    }

                    Creature.AddFeatByLevel(player, feat, 1);
                    AddFeatToHotBar(feat);
                }
            }

            void AddFeatToHotBar(Feat feat)
            {
                var qbs = PlayerQuickBarSlot.UseFeat(feat);

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

            // Applies any Purchase triggers associated with this perk.
            void ApplyPurchasePerkTriggers(int perkLevel)
            {
                if (perkDetail.PurchasedTriggers.Count > 0)
                {
                    foreach (var action in perkDetail.PurchasedTriggers)
                    {
                        action(player, model.SelectedPerk, perkLevel);
                    }
                }
            }

            var currentPerkLevelDetails = BuildPerkSection(true, currentLevel);
            var nextPerkLevelDetails    = BuildPerkSection(false, nextLevel);
            var requirementsSection     = BuildRequirements(nextLevel?.Requirements);

            page.Header = ColorToken.Green("Name: ") + perkDetail.Name + "\n" +
                          ColorToken.Green("Description: ") + perkDetail.Description + "\n" +
                          ColorToken.Green("Category: ") + categoryDetail.Name + "\n" +
                          ColorToken.Green("Rank: ") + rank + " / " + maxRank + "\n" +
                          ColorToken.Green("Price: ") + price + "\n" +
                          currentPerkLevelDetails + "\n" +
                          nextPerkLevelDetails + "\n" +
                          requirementsSection;

            if (CanUpgrade())
            {
                page.AddResponse(model.IsConfirmingPurchase ? "CONFIRM PURCHASE" : "Purchase Upgrade", PurchaseUpgrade);
            }
        }
        /// <summary>
        /// Handles the deck details logic.
        /// </summary>
        /// <param name="page">The page to build</param>
        private void DeckDetailsPageInit(DialogPage page)
        {
            var player              = GetPC();
            var playerId            = GetObjectUUID(player);
            var dbPlayerTripleTriad = DB.Get <PlayerTripleTriad>(playerId);
            var model = GetDataModel <Model>();
            var deck  = dbPlayerTripleTriad.Decks.ContainsKey(model.SelectedDeckId)
                ? dbPlayerTripleTriad.Decks[model.SelectedDeckId]
                : new CardDeck {
                Name = $"Deck #{model.SelectedDeckId}"
            };

            page.Header = $"{ColorToken.Green("Deck Name: ")} {deck.Name}\n\n" +
                          "What would you like to do with this deck?";

            // Deck Renaming
            page.AddResponse("Change Name", () =>
            {
                model.IsConfirming = false;
                ChangePage(ChangeDeckNamePageId);
            });

            // Card Selection
            page.AddResponse("Select Cards", () =>
            {
                model.IsConfirming = false;
                LoadDeckOntoPC(-1); // Intentionally blank out the card display since we're picking new cards.
                model.CurrentCardNumber = 1;

                // Clone the stack. We will revert back to this state when the player finishes building the deck.
                model.NavigationStackBeforeDeckBuilding = new Stack <DialogNavigation>(NavigationStack.Reverse());
                // The topmost navigation points back to the deck list page which leads to users having to click "Back" twice after confirming their deck selections.
                // Pop this since we only need one.
                model.NavigationStackBeforeDeckBuilding.Pop();

                ChangePage(DeckCardSelectionLevelsPageId);
            });

            // Deck Deletion
            if (model.IsConfirming)
            {
                page.AddResponse($"{ColorToken.Red("CONFIRM DELETE DECK")}", () =>
                {
                    if (dbPlayerTripleTriad.Decks.ContainsKey(model.SelectedDeckId))
                    {
                        dbPlayerTripleTriad.Decks.Remove(model.SelectedDeckId);
                        DB.Set(playerId, dbPlayerTripleTriad);
                    }

                    LoadDeckOntoPC(model.SelectedDeckId);
                    model.IsConfirming = false;
                });
            }
            else
            {
                page.AddResponse($"{ColorToken.Red("Delete Deck")}", () =>
                {
                    model.IsConfirming = true;
                });
            }
        }
Beispiel #29
0
        /// <summary>
        /// Builds the Skill Details page.
        /// </summary>
        /// <param name="page">The page to build.</param>
        private void SkillDetailsInit(DialogPage page)
        {
            var model    = GetDataModel <Model>();
            var player   = GetPC();
            var playerId = GetObjectUUID(player);

            void BuildHeader()
            {
                var dbPlayer   = DB.Get <Player>(playerId);
                var skill      = Skill.GetSkillDetails(model.SelectedSkill);
                var pcSkill    = dbPlayer.Skills[model.SelectedSkill];
                var requiredXP = Skill.GetRequiredXP(pcSkill.Rank);

                string title;

                if (pcSkill.Rank <= 3)
                {
                    title = "Untrained";
                }
                else if (pcSkill.Rank <= 7)
                {
                    title = "Neophyte";
                }
                else if (pcSkill.Rank <= 13)
                {
                    title = "Novice";
                }
                else if (pcSkill.Rank <= 20)
                {
                    title = "Apprentice";
                }
                else if (pcSkill.Rank <= 35)
                {
                    title = "Journeyman";
                }
                else if (pcSkill.Rank <= 50)
                {
                    title = "Expert";
                }
                else if (pcSkill.Rank <= 65)
                {
                    title = "Adept";
                }
                else if (pcSkill.Rank <= 80)
                {
                    title = "Master";
                }
                else if (pcSkill.Rank <= 100)
                {
                    title = "Grandmaster";
                }
                else
                {
                    title = "Unknown";
                }

                title += " (" + pcSkill.Rank + ")";

                string decayLock = ColorToken.Green("Decay Lock: ") + ColorToken.White("Unlocked");

                if (pcSkill.IsLocked)
                {
                    decayLock = ColorToken.Green("Decay Lock: ") + ColorToken.Red("Locked");
                }

                // Skills which don't contribute to the cap cannot be locked (there's no reason for it.)
                // Display a message explaining this to the player instead.
                string noContributeMessage = string.Empty;

                if (!skill.ContributesToSkillCap)
                {
                    decayLock           = string.Empty;
                    noContributeMessage = ColorToken.Green("This skill does not contribute to your cumulative skill cap.") + "\n\n";
                }

                string unallocatedXP = ColorToken.Green("Unallocated XP: ") + dbPlayer.UnallocatedXP + "\n";

                page.Header =
                    ColorToken.Green("Skill: ") + skill.Name + "\n" +
                    ColorToken.Green("Rank: ") + title + "\n" +
                    ColorToken.Green("Exp: ") + Menu.BuildBar(pcSkill.XP, requiredXP, 100, ColorToken.TokenStart(255, 127, 0)) + "\n" +
                    unallocatedXP +
                    noContributeMessage +
                    decayLock + "\n\n" +
                    ColorToken.Green("Description: ") + skill.Description + "\n";
            }

            void DistributeXP()
            {
                ChangePage(DistributeXPId);
            }

            void ToggleDecayLock()
            {
                var dbPlayer = DB.Get <Player>(playerId);

                dbPlayer.Skills[model.SelectedSkill].IsLocked = !dbPlayer.Skills[model.SelectedSkill].IsLocked;
                DB.Set(playerId, dbPlayer);
            }

            BuildHeader();

            page.AddResponse("Distribute XP", DistributeXP);
            page.AddResponse("Toggle Decay Lock", ToggleDecayLock);
        }