Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="creature"></param>
        /// <param name="itemEntityId"></param>
        /// <param name="moveToInventory"></param>
        /// <returns></returns>
        public bool Buy(Creature creature, long itemEntityId, bool moveToInventory)
        {
            var shop  = this;
            var owner = creature.Temp.CurrentShopOwner;

            // Get item
            // In theory someone could buy an item without it being visible
            // to him, but he would need the current entity id that
            // changes on each restart. It's unlikely to ever be a problem.
            var item = shop.GetItem(itemEntityId);

            if (item == null)
            {
                Log.Warning("NpcShopScript.Buy: Item '{0:X16}' doesn't exist in shop.", itemEntityId);
                return(false);
            }

            // Check stock
            if (item.Stock == 0)
            {
                Send.MsgBox(creature, Localization.Get("This item is not in stock anymore."));
                return(false);
            }

            // Determine which payment method to use, the same way the client
            // does to display them. Points > Stars > Ducats > Gold.
            var paymentMethod = PaymentMethod.Gold;

            if (item.OptionInfo.StarPrice > 0)
            {
                paymentMethod = PaymentMethod.Stars;
            }
            if (item.OptionInfo.DucatPrice > 0)
            {
                paymentMethod = PaymentMethod.Ducats;
            }
            if (item.OptionInfo.PointPrice > 0)
            {
                paymentMethod = PaymentMethod.Points;
            }

            // Get buying price
            var price = int.MaxValue;

            switch (paymentMethod)
            {
            case PaymentMethod.Gold: price = item.OptionInfo.Price; break;

            case PaymentMethod.Stars: price = item.OptionInfo.StarPrice; break;

            case PaymentMethod.Ducats: price = item.OptionInfo.DucatPrice; break;

            case PaymentMethod.Points: price = item.OptionInfo.PointPrice; break;
            }

            // The client expects the price for a full stack to be sent
            // in the ItemOptionInfo, so we have to calculate the actual price here.
            if (item.Data.StackType == StackType.Stackable)
            {
                price = (int)(price / (float)item.Data.StackMax * item.Amount);
            }

            // Wednesday: Decrease in prices (5%) for items in NPC shops,
            // including Remote Shop Coupons and money deposit for Exploration Quests.
            if (ErinnTime.Now.Month == ErinnMonth.AlbanHeruin)
            {
                price = (int)(price * 0.95f);
            }

            // Check currency
            var canPay = false;

            switch (paymentMethod)
            {
            case PaymentMethod.Gold: canPay = (creature.Inventory.Gold >= price); break;

            case PaymentMethod.Stars: canPay = (creature.Inventory.Stars >= price); break;

            case PaymentMethod.Ducats: canPay = false; break;                     // TODO: Implement ducats.

            case PaymentMethod.Points: canPay = (creature.Points >= price); break;
            }

            if (!canPay)
            {
                switch (paymentMethod)
                {
                case PaymentMethod.Gold: Send.MsgBox(creature, Localization.Get("Insufficient amount of gold.")); break;

                case PaymentMethod.Stars: Send.MsgBox(creature, Localization.Get("Insufficient amount of stars.")); break;

                case PaymentMethod.Ducats: Send.MsgBox(creature, Localization.Get("Insufficient amount of ducats.")); break;

                case PaymentMethod.Points: Send.MsgBox(creature, Localization.Get("You don't have enough Pon.\nYou will need to buy more.")); break;
                }

                return(false);
            }

            // Buy, adding item, and removing currency
            var success = false;

            var newItem = new Item(item);

            // Set guild data
            if (newItem.HasTag("/guild_robe/") && creature.Guild != null && creature.Guild.HasRobe)
            {
                // EBCL1:4:-11042446;EBCL2:4:-7965756;EBLM1:1:45;EBLM2:1:24;EBLM3:1:6;GLDNAM:s:Name;
                newItem.Info.Color1 = creature.Guild.Robe.RobeColor;
                newItem.Info.Color2 = GuildRobe.GetColor(creature.Guild.Robe.BadgeColor);
                newItem.Info.Color3 = GuildRobe.GetColor(creature.Guild.Robe.EmblemMarkColor);
                newItem.MetaData1.SetInt("EBCL1", (int)GuildRobe.GetColor(creature.Guild.Robe.EmblemOutlineColor));
                newItem.MetaData1.SetInt("EBCL2", (int)GuildRobe.GetColor(creature.Guild.Robe.StripesColor));
                newItem.MetaData1.SetByte("EBLM1", creature.Guild.Robe.EmblemMark);
                newItem.MetaData1.SetByte("EBLM2", creature.Guild.Robe.EmblemOutline);
                newItem.MetaData1.SetByte("EBLM3", creature.Guild.Robe.Stripes);
                newItem.MetaData1.SetString("GLDNAM", creature.Guild.Name);
            }

            // Cursor
            if (!moveToInventory)
            {
                success = creature.Inventory.Add(newItem, Pocket.Cursor);
            }
            // Inventory
            else
            {
                success = creature.Inventory.Add(newItem, false);
            }

            if (success)
            {
                // Reset gold price if payment method wasn't gold, as various
                // things depend on the gold price, like repair prices.
                // If any payment method but gold was used, the gold price
                // would be 0.
                if (paymentMethod != PaymentMethod.Gold)
                {
                    newItem.ResetGoldPrice();
                }

                // Reduce gold/points
                switch (paymentMethod)
                {
                case PaymentMethod.Gold: creature.Inventory.Gold -= price; break;

                case PaymentMethod.Stars: creature.Inventory.Stars -= price; break;

                case PaymentMethod.Ducats: break;                         // TODO: Implement ducats.

                case PaymentMethod.Points: creature.Points -= price; break;
                }

                // Reduce stock
                if (item.Stock > 0)
                {
                    // Don't let it go below 0, that would mean unlimited.
                    item.Stock = Math.Max(0, item.Stock - 1);
                    if (item.Stock == 0)
                    {
                        // Refresh shop, so the item disappears.
                        Send.ClearNpcShop(creature);
                        Send.AddToNpcShop(creature, this.GetTabs(creature, owner));
                    }

                    Send.ServerMessage(creature, "Debug: Stock remaining: {0}", item.Stock);
                }
            }

            return(success);
        }
Esempio n. 2
0
        public void NpcShopBuyItem(ChannelClient client, Packet packet)
        {
            var entityId     = packet.GetLong();
            var targetPocket = packet.GetByte();    // 0:cursor, 1:inv
            var unk          = packet.GetByte();    // storage gold?

            var creature = client.GetCreatureSafe(packet.Id);

            // Check session
            // Not compatible with remote shop access, unless we bind it to NPCs.
            //client.NpcSession.EnsureValid();

            // Check open shop
            if (creature.Temp.CurrentShop == null)
            {
                throw new ModerateViolation("Tried to buy an item with a null shop.");
            }

            // Get item
            // In theory someone could buy an item without it being visible
            // to him, but he would need the current entity id that
            // changes on each restart. It's unlikely to ever be a problem.
            var item = creature.Temp.CurrentShop.GetItem(entityId);

            if (item == null)
            {
                Log.Warning("NpcShopBuyItem: Item '{0:X16}' doesn't exist in shop.", entityId);
                goto L_Fail;
            }

            // Determine which payment method to use, the same way the client
            // does to display them. Points > Stars > Ducats > Gold.
            var paymentMethod = PaymentMethod.Gold;

            if (item.OptionInfo.StarPrice > 0)
            {
                paymentMethod = PaymentMethod.Stars;
            }
            if (item.OptionInfo.DucatPrice > 0)
            {
                paymentMethod = PaymentMethod.Ducats;
            }
            if (item.OptionInfo.PointPrice > 0)
            {
                paymentMethod = PaymentMethod.Points;
            }

            // Get buying price
            var price = int.MaxValue;

            switch (paymentMethod)
            {
            case PaymentMethod.Gold: price = item.OptionInfo.Price; break;

            case PaymentMethod.Stars: price = item.OptionInfo.StarPrice; break;

            case PaymentMethod.Ducats: price = item.OptionInfo.DucatPrice; break;

            case PaymentMethod.Points: price = item.OptionInfo.PointPrice; break;
            }

            // The client expects the price for a full stack to be sent
            // in the ItemOptionInfo, so we have to calculate the actual price here.
            if (item.Data.StackType == StackType.Stackable)
            {
                price = (int)(price / (float)item.Data.StackMax * item.Amount);
            }

            // Wednesday: Decrease in prices (5%) for items in NPC shops,
            // including Remote Shop Coupons and money deposit for Exploration Quests.
            if (ErinnTime.Now.Month == ErinnMonth.AlbanHeruin)
            {
                price = (int)(price * 0.95f);
            }

            // Check currency
            var canPay = false;

            switch (paymentMethod)
            {
            case PaymentMethod.Gold: canPay = (creature.Inventory.Gold >= price); break;

            case PaymentMethod.Stars: canPay = (creature.Inventory.Stars >= price); break;

            case PaymentMethod.Ducats: canPay = false; break;                     // TODO: Implement ducats.

            case PaymentMethod.Points: canPay = (creature.Points >= price); break;
            }

            if (!canPay)
            {
                switch (paymentMethod)
                {
                case PaymentMethod.Gold: Send.MsgBox(creature, Localization.Get("Insufficient amount of gold.")); break;

                case PaymentMethod.Stars: Send.MsgBox(creature, Localization.Get("Insufficient amount of stars.")); break;

                case PaymentMethod.Ducats: Send.MsgBox(creature, Localization.Get("Insufficient amount of ducats.")); break;

                case PaymentMethod.Points: Send.MsgBox(creature, Localization.Get("You don't have enough Pon.\nYou will need to buy more.")); break;
                }

                goto L_Fail;
            }

            // Buy, adding item, and removing currency
            var success = false;

            // Set guild data
            if (item.HasTag("/guild_robe/") && creature.Guild != null && creature.Guild.HasRobe)
            {
                // EBCL1:4:-11042446;EBCL2:4:-7965756;EBLM1:1:45;EBLM2:1:24;EBLM3:1:6;GLDNAM:s:Name;
                item.Info.Color1 = creature.Guild.Robe.RobeColor;
                item.Info.Color2 = GuildRobe.GetColor(creature.Guild.Robe.BadgeColor);
                item.Info.Color3 = GuildRobe.GetColor(creature.Guild.Robe.EmblemMarkColor);
                item.MetaData1.SetInt("EBCL1", (int)GuildRobe.GetColor(creature.Guild.Robe.EmblemOutlineColor));
                item.MetaData1.SetInt("EBCL2", (int)GuildRobe.GetColor(creature.Guild.Robe.StripesColor));
                item.MetaData1.SetByte("EBLM1", creature.Guild.Robe.EmblemMark);
                item.MetaData1.SetByte("EBLM2", creature.Guild.Robe.EmblemOutline);
                item.MetaData1.SetByte("EBLM3", creature.Guild.Robe.Stripes);
                item.MetaData1.SetString("GLDNAM", creature.Guild.Name);
            }

            // Cursor
            if (targetPocket == 0)
            {
                success = creature.Inventory.Add(item, Pocket.Cursor);
            }
            // Inventory
            else if (targetPocket == 1)
            {
                success = creature.Inventory.Add(item, false);
            }

            if (success)
            {
                // Reset gold price if payment method wasn't gold, as various
                // things depend on the gold price, like repair prices.
                // If any payment method but gold was used, the gold price
                // would be 0.
                if (paymentMethod != PaymentMethod.Gold)
                {
                    item.ResetGoldPrice();
                }

                // Reduce
                switch (paymentMethod)
                {
                case PaymentMethod.Gold: creature.Inventory.Gold -= price; break;

                case PaymentMethod.Stars: creature.Inventory.Stars -= price; break;

                case PaymentMethod.Ducats: break;                         // TODO: Implement ducats.

                case PaymentMethod.Points: creature.Points -= price; break;
                }
            }

            // Response
            Send.NpcShopBuyItemR(creature, success);
            return;

L_Fail:
            Send.NpcShopBuyItemR(creature, false);
        }