예제 #1
0
        public static void SpawnChest(Point pos, Point[] items, string name = "", int type = 21)
        {
            int x = pos.X;
            int y = pos.Y;

            WorldGen.PlaceChest(x, y, (ushort)type);
            int   index = Chest.FindEmptyChest(x, y);
            Chest chest = Main.chest[index - 1];

            chest.name = name;
            for (int i = 0; i < items.Length; i++)
            {
                chest.item[i].SetDefaults(items[i].X, false);
                chest.item[i].stack = items[i].Y;
            }
        }
예제 #2
0
        private void ItemShop(CommandArgs args)
        {
            var parameters        = args.Parameters;
            var player            = args.Player;
            var playerGroupConfig = Config.Instance.GetGroupConfig(player.Group.Name);
            var subcommand        = parameters.Count > 0 ? parameters[0] : "";

            if (subcommand.Equals("1", StringComparison.OrdinalIgnoreCase))
            {
                player.AwaitingTempPoint = 1;
                player.SendInfoMessage("Hit a block to set the first point.");
            }
            else if (subcommand.Equals("2", StringComparison.OrdinalIgnoreCase))
            {
                player.AwaitingTempPoint = 2;
                player.SendInfoMessage("Hit a block to set the second point.");
            }
            else if (subcommand.Equals("buy", StringComparison.OrdinalIgnoreCase))
            {
                if (parameters.Count != 2 && parameters.Count != 3)
                {
                    player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop buy <item-index> [amount]");
                    return;
                }

                var session = GetOrCreateSession(player);
                if (session.CurrentlyViewedShop == null)
                {
                    player.SendErrorMessage("You aren't currently viewing a shop.");
                    return;
                }
                var shop = session.CurrentlyViewedShop;

                var inputItemIndex = parameters[1];
                if (!int.TryParse(inputItemIndex, out var itemIndex) || itemIndex < 1 || itemIndex > Chest.maxItems)
                {
                    player.SendErrorMessage($"Invalid item index '{inputItemIndex}'.");
                    return;
                }

                var shopItem = shop.Items.FirstOrDefault(i => i.Index == itemIndex - 1 && i.StackSize > 0);
                if (shopItem == null)
                {
                    player.SendErrorMessage($"Invalid item index '{inputItemIndex}'.");
                    return;
                }

                var inputAmount = parameters.Count == 3 ? parameters[2] : "1";
                if (!int.TryParse(inputAmount, out var amount) || amount < 1 || amount > shopItem.StackSize)
                {
                    player.SendErrorMessage($"Invalid amount '{inputAmount}'.");
                    return;
                }

                var item   = new Item();
                var itemId = shopItem.ItemId;
                item.SetDefaults(itemId);

                //var unitPrice = shop.UnitPrices.Get(itemId, item.value / 5);
                var unitPriceInfo = shop.UnitPrices[itemId];

                if (!unitPriceInfo.IsValid)
                {
                    player.SendErrorMessage("Unfortunately, this item is priced incorrectly. Please contact the shop owner.");
                    return;
                }

                var currencyConverter = unitPriceInfo.Currency.GetCurrencyConverter();

                //var purchaseCost = (amount * shop.UnitPrices.Get(itemId, item.value / 5));
                var purchaseCost       = amount * unitPriceInfo.Value;
                var salesTax           = Math.Round(purchaseCost * (decimal)playerGroupConfig.SalesTaxRate);
                var purchaseCostString = currencyConverter.ToString(purchaseCost);
                var salesTaxString     = currencyConverter.ToString(salesTax);

                var itemText = $"[i/s{amount},p{shopItem.PrefixId}:{shopItem.ItemId}]";
                player.SendInfoMessage(
                    $"Purchasing {itemText} will cost [c/{Color.OrangeRed.Hex3()}:{purchaseCostString}], " +
                    $"with a sales tax of [c/{Color.OrangeRed.Hex3()}:{salesTaxString}].");
                player.SendInfoMessage("Do you wish to proceed? Use /yes or /no.");
                player.AddResponse("yes", args2 =>
                {
                    player.AwaitingResponse.Remove("no");

                    var account = BankingPlugin.Instance.GetBankAccount(player.Name, unitPriceInfo.Currency.InternalName);
                    if (account == null || account.Balance < purchaseCost + salesTax)
                    {
                        player.SendErrorMessage($"You do not have enough of a balance to purchase {itemText}.");
                        shop.TryShowStock(player, MessageRefreshDelay);
                        return;
                    }
                    if (shopItem.StackSize < amount || shopItem.ItemId != itemId || shop.IsBeingChanged)
                    {
                        player.SendErrorMessage("While waiting, the shop changed.");
                        //shop.TryShowStock(player, MessageRefreshDelay * 2);//if the shop is changing, lets not spam anyones display while it is
                        return;
                    }

                    if (purchaseCost > 0)
                    {
                        var account2 = BankingPlugin.Instance.GetBankAccount(shop.OwnerName, unitPriceInfo.Currency.InternalName);
                        account.TryTransferTo(account2, purchaseCost);
                    }
                    if (salesTax > 0)
                    {
                        account.TryTransferTo(BankingPlugin.Instance.GetWorldAccount(), salesTax);
                    }

                    shopItem.StackSize -= amount;
                    database.Update(shop);

                    var totalCost       = purchaseCost + salesTax;
                    var totalCostString = currencyConverter.ToString(totalCost);

                    player.GiveItem(
                        itemId, "", Player.defaultWidth, Player.defaultHeight, amount, shopItem.PrefixId);
                    player.SendSuccessMessage($"Purchased {itemText} for " +
                                              $"[c/{Color.OrangeRed.Hex3()}:{totalCostString}].");

                    var player2 = TShock.Players.Where(p => p?.Active == true)
                                  .FirstOrDefault(p => p.User?.Name == shop.OwnerName);
                    player2?.SendInfoMessage($"{player.Name} purchased {itemText} for " +
                                             $"[c/{Color.OrangeRed.Hex3()}:{totalCostString}].");

                    shop.TryShowStock(player, MessageRefreshDelay);
                });
                player.AddResponse("no", args2 =>
                {
                    player.AwaitingResponse.Remove("yes");
                    player.SendInfoMessage("Canceled purchase.");

                    shop.TryShowStock(player, MessageRefreshDelay);
                });
            }
            else if (subcommand.Equals("close", StringComparison.OrdinalIgnoreCase))
            {
                var session = GetOrCreateSession(player);
                if (session.CurrentShop == null)
                {
                    player.SendErrorMessage("You aren't currently in a shop.");
                    return;
                }

                var shop = session.CurrentShop;
                if (shop.OwnerName != player.User?.Name && !player.HasPermission("housing.itemshop.admin"))
                {
                    player.SendErrorMessage(
                        $"You can't close {shop.OwnerName}'s shop [c/{Color.LimeGreen.Hex3()}:{shop}].");
                    return;
                }

                shop.IsOpen = false;
                database.Update(shop);
                player.SendSuccessMessage(
                    $"Closed {(shop.OwnerName == player.User?.Name ? "your shop" : shop.OwnerName + "'s shop")} " +
                    $"[c/{Color.LimeGreen.Hex3()}:{shop}].");
            }
            else if (subcommand.Equals("info", StringComparison.OrdinalIgnoreCase))
            {
                var session = GetOrCreateSession(player);
                if (session.CurrentShop == null)
                {
                    player.SendErrorMessage("You aren't currently in a shop.");
                    return;
                }

                var shop = session.CurrentShop;
                player.SendInfoMessage($"Owner: {shop.OwnerName}, Name: {shop.Name}");
                var prices = shop.UnitPrices.Where(kvp => kvp.Value.IsValid && kvp.Value.Value > 0)
                             .Select(kvp => $"[i:{kvp.Key}]: {Color.OrangeRed.ColorText(kvp.Value.Price)}");

                player.SendInfoMessage(
                    $"Prices: {string.Join(", ", prices)}. All other items are default sell prices.");
                if (shop.OwnerName == player.User?.Name)
                {
                    //var ownerConfig = shop.GetGroupConfig();

                    var house   = session.CurrentHouse;
                    var taxRate = playerGroupConfig.StoreTaxRate - playerGroupConfig.TaxRate;
                    var taxCost = (decimal)Math.Round(house.Area * taxRate);
                    player.SendInfoMessage($"Extra tax on house: {Color.OrangeRed.ColorText(taxCost.ToMoneyString())}");
                }
            }
            else if (subcommand.Equals("open", StringComparison.OrdinalIgnoreCase))
            {
                var session = GetOrCreateSession(player);
                if (session.CurrentShop == null)
                {
                    player.SendErrorMessage("You aren't currently in a shop.");
                    return;
                }

                var shop = session.CurrentShop;
                if (shop.OwnerName != player.User?.Name && !player.HasPermission("housing.itemshop.admin"))
                {
                    player.SendErrorMessage(
                        $"You can't open {shop.OwnerName}'s shop {Color.LimeGreen.ColorText(shop)}.");
                    return;
                }

                shop.IsOpen = true;
                database.Update(shop);
                player.SendSuccessMessage(
                    $"Opened {(shop.OwnerName == player.User?.Name ? "your shop" : shop.OwnerName + "'s shop")} " +
                    $"{Color.LimeGreen.ColorText(shop)}.");
            }
            else if (subcommand.Equals("remove", StringComparison.OrdinalIgnoreCase))
            {
                var session = GetOrCreateSession(player);
                if (session.CurrentShop == null)
                {
                    player.SendErrorMessage("You aren't currently in a shop.");
                    return;
                }

                var shop = session.CurrentShop;
                if (shop.OwnerName != player.User?.Name && !player.HasPermission("housing.itemshop.admin"))
                {
                    player.SendErrorMessage(
                        $"You can't remove {shop.OwnerName}'s shop {Color.LimeGreen.ColorText(shop)}.");
                    return;
                }

                // Revert the chest to a normal chest.
                var chestId = Chest.FindEmptyChest(shop.ChestX, shop.ChestY);
                if (chestId >= 0)
                {
                    var chest = new Chest();
                    for (var i = 0; i < Chest.maxItems; ++i)
                    {
                        var shopItem = shop.Items.FirstOrDefault(si => si.Index == i);
                        var item     = new Item();
                        item.SetDefaults(shopItem?.ItemId ?? 0);
                        item.stack    = shopItem?.StackSize ?? 0;
                        item.prefix   = shopItem?.PrefixId ?? 0;
                        chest.item[i] = item;
                    }
                    Main.chest[chestId] = chest;
                }

                database.Remove(shop);
                player.SendSuccessMessage(
                    $"Removed {(shop.OwnerName == player.User?.Name ? "your shop" : shop.OwnerName + "'s shop")} " +
                    $"{Color.LimeGreen.ColorText(shop)}.");
            }
            else if (subcommand.Equals("set", StringComparison.OrdinalIgnoreCase))
            {
                if (parameters.Count != 2)
                {
                    player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop set <shop-name>");
                    return;
                }

                if (player.TempPoints.Any(p => p == Point.Zero))
                {
                    player.SendErrorMessage("Not all points have been set.");
                    return;
                }

                var session = GetOrCreateSession(player);
                if (session.CurrentHouse == null || session.CurrentHouse.OwnerName != player.User?.Name)
                {
                    player.SendErrorMessage("You aren't currently in a house that you own.");
                    return;
                }

                //var playerGroupConfig = Config.Instance.GetGroupConfig(player.Group.Name);
                var point1        = player.TempPoints[0];
                var point2        = player.TempPoints[1];
                var inputShopName = parameters[1];
                var x             = Math.Min(point1.X, point2.X);
                var y             = Math.Min(point1.Y, point2.Y);
                var x2            = Math.Max(point1.X, point2.X);
                var y2            = Math.Max(point1.Y, point2.Y);
                var area          = (x2 - x + 1) * (y2 - y + 1);
                if (area < playerGroupConfig.MinShopSize)
                {
                    player.SendErrorMessage($"Your shop is too small. Minimum area is {playerGroupConfig.MinShopSize}.");
                    return;
                }
                if (area > playerGroupConfig.MaxShopSize)
                {
                    player.SendErrorMessage($"Your shop is too large.Maximum area is {playerGroupConfig.MaxShopSize}.");
                    return;
                }

                var rectangle = new Rectangle(x, y, x2 - x + 1, y2 - y + 1);
                if (!session.CurrentHouse.Rectangle.Contains(rectangle))
                {
                    player.SendErrorMessage("Your shop must lie entirely within your house.");
                    return;
                }

                session.NextShopHouse = session.CurrentHouse;
                session.NextShopName  = inputShopName;
                session.NextShopX     = x;
                session.NextShopY     = y;
                session.NextShopX2    = x2;
                session.NextShopY2    = y2;
                player.SendInfoMessage("Place a chest to serve as the item shop chest.");
            }
            else if (subcommand.Equals("setmsg", StringComparison.OrdinalIgnoreCase))
            {
                if (parameters.Count < 2)
                {
                    player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop setmsg <message>");
                    return;
                }

                var session = GetOrCreateSession(player);
                if (session.CurrentShop == null)
                {
                    player.SendErrorMessage("You aren't currently in a shop.");
                    return;
                }

                var shop = session.CurrentShop;
                if (shop.OwnerName != player.User?.Name && !player.HasPermission("housing.itemshop.admin"))
                {
                    player.SendErrorMessage(
                        $"You can't set the message for {shop.OwnerName}'s {Color.LimeGreen.ColorText(shop)} shop.");
                    return;
                }

                var message = string.Join(" ", parameters.Skip(1));
                shop.Message = message;
                database.Update(shop);
                player.SendSuccessMessage(
                    $"Updated {(shop.OwnerName == player.User?.Name ? "your" : shop.OwnerName + "'s")} " +
                    $"{Color.LimeGreen.ColorText(shop)} shop message.");
            }
            else if (subcommand.Equals("setprice", StringComparison.OrdinalIgnoreCase))
            {
                if (parameters.Count != 3)
                {
                    player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop setprice <item-name> <price>");
                    return;
                }

                var session = GetOrCreateSession(player);
                if (session.CurrentShop == null)
                {
                    player.SendErrorMessage("You aren't currently in a shop.");
                    return;
                }

                var shop = session.CurrentShop;
                if (shop.OwnerName != player.User?.Name && !player.HasPermission("housing.itemshop.admin"))
                {
                    player.SendErrorMessage(
                        $"You can't modify {shop.OwnerName}'s {Color.LimeGreen.ColorText(shop)} shop.");
                    return;
                }

                var inputItemName = parameters[1];
                var items         = TShock.Utils.GetItemByIdOrName(inputItemName);
                if (items.Count > 1)
                {
                    player.SendErrorMessage($"Multiple items matched '{inputItemName}':");
                    TShock.Utils.SendMultipleMatchError(player, items);
                    return;
                }
                if (items.Count == 0)
                {
                    player.SendErrorMessage($"Invalid item '{inputItemName}'.");
                    return;
                }

                var inputPrice = parameters[2];
                var priceInfo  = new PriceInfo(inputPrice);
                var disable    = false;

                if (inputPrice == "0" || inputPrice == "none")
                {
                    disable = true;
                }

                //if(!BankingPlugin.Instance.Bank.CurrencyManager.TryFindCurrencyFromString(inputPrice, out var priceCurrency))
                if (!priceInfo.IsValid && !disable)
                {
                    player.SendErrorMessage($"Invalid price. '{inputPrice}' is not a valid currency format.");
                    return;
                }

                if (priceInfo.Value <= 0m && !disable)
                {
                    player.SendErrorMessage($"Invalid price '{inputPrice}'. Price cannot be less than 1.");
                    return;
                }

                //we use CurrencyConverter.ToString() here to ensure the unit price uses the largest currency values possible.
                //shop.UnitPrices[items[0].type] = priceCurrency.GetCurrencyConverter().ToString(price);
                shop.UnitPrices[items[0].type] = priceInfo;
                database.Update(shop);

                if (disable)
                {
                    player.SendSuccessMessage(
                        $"Removed {inputItemName} from the {Color.LimeGreen.ColorText(shop)} item listing.");
                }
                else
                {
                    player.SendSuccessMessage(
                        $"Updated {(shop.OwnerName == player.User?.Name ? "your" : shop.OwnerName + "'s")} " +
                        $"{Color.LimeGreen.ColorText(shop)} shop prices.");
                }
            }
            else
            {
                player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop 1/2");
                player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop buy <item-index> [amount]");
                player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop close");
                player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop info");
                player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop open");
                player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop remove");
                player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop set <shop-name>");
                player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop setmsg <message>");
                player.SendErrorMessage($"Syntax: {Commands.Specifier}itemshop setprice <item-name> <price> ( 0 or none disables listing. )");
            }
        }