Example #1
0
        public void ActOnUse(WorldObject activator, bool confirmed)
        {
            if (!(activator is Player player))
            {
                return;
            }

            if (player.IsBusy || player.Teleporting)
            {
                player.Session.Network.EnqueueSend(new GameEventWeenieError(player.Session, WeenieError.YoureTooBusy));
                return;
            }

            if (!string.IsNullOrWhiteSpace(UseSendsSignal))
            {
                player.CurrentLandblock?.EmitSignal(player, UseSendsSignal);
                return;
            }

            // handle rare gems
            if (RareId != null && player.GetCharacterOption(CharacterOption.ConfirmUseOfRareGems) && !confirmed)
            {
                var msg     = $"Are you sure you want to use {Name}?";
                var confirm = new Confirmation_Custom(player.Guid, () => ActOnUse(activator, true));
                player.ConfirmationManager.EnqueueSend(confirm, msg);
                return;
            }

            if (RareUsesTimer)
            {
                var currentTime = Time.GetUnixTime();

                var timeElapsed = currentTime - player.LastRareUsedTimestamp;

                if (timeElapsed < RareTimer)
                {
                    // TODO: get retail message
                    var remainTime = (int)Math.Ceiling(RareTimer - timeElapsed);
                    player.Session.Network.EnqueueSend(new GameMessageSystemChat($"You may use another timed rare in {remainTime}s", ChatMessageType.Broadcast));
                    return;
                }

                player.LastRareUsedTimestamp = currentTime;

                // local broadcast usage
                player.EnqueueBroadcast(new GameMessageSystemChat($"{player.Name} used the rare item {Name}", ChatMessageType.Broadcast));
            }

            if (SpellDID.HasValue)
            {
                var spell = new Server.Entity.Spell((uint)SpellDID);

                TryCastSpell(spell, player, this);
            }

            if (UseCreateContractId > 0)
            {
                if (!player.ContractManager.Add(UseCreateContractId.Value))
                {
                    return;
                }
                else // this wasn't in retail, but the lack of feedback when using a contract gem just seems jarring so...
                {
                    player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{Name} accepted. Click on the quill icon in the lower right corner to open your contract tab to view your active contracts.", ChatMessageType.Broadcast));
                }
            }

            if (UseCreateItem > 0)
            {
                //if (DatabaseManager.World.GetCachedWeenie(UseCreateItem.Value) is null)
                //{
                //    player.Session.Network.EnqueueSend(new GameEventCommunicationTransientString(player.Session, "Unable to create object, WCID is not in database !")); // custom error
                //    return;
                //}

                var playerFreeInventorySlots = player.GetFreeInventorySlots();
                var playerFreeContainerSlots = player.GetFreeContainerSlots();
                var playerAvailableBurden    = player.GetAvailableBurden();

                var playerOutOfInventorySlots    = false;
                var playerOutOfContainerSlots    = false;
                var playerExceedsAvailableBurden = false;

                var amount = UseCreateQuantity ?? 1;

                var itemStacks = player.PreCheckItem(UseCreateItem.Value, amount, playerFreeContainerSlots, playerFreeInventorySlots, playerAvailableBurden, out var itemEncumberance, out bool itemRequiresBackpackSlot);

                if (itemRequiresBackpackSlot)
                {
                    playerFreeContainerSlots -= itemStacks;
                    playerAvailableBurden    -= itemEncumberance;

                    playerOutOfContainerSlots = playerFreeContainerSlots < 0;
                }
                else
                {
                    playerFreeInventorySlots -= itemStacks;
                    playerAvailableBurden    -= itemEncumberance;

                    playerOutOfInventorySlots = playerFreeInventorySlots < 0;
                }

                playerExceedsAvailableBurden = playerAvailableBurden < 0;

                if (playerOutOfInventorySlots || playerOutOfContainerSlots || playerExceedsAvailableBurden)
                {
                    if (playerExceedsAvailableBurden)
                    {
                        player.Session.Network.EnqueueSend(new GameEventCommunicationTransientString(player.Session, "You are too encumbered to use that!"));
                    }
                    else if (playerOutOfInventorySlots)
                    {
                        player.Session.Network.EnqueueSend(new GameEventCommunicationTransientString(player.Session, "You do not have enough pack space to use that!"));
                    }
                    else //if (playerOutOfContainerSlots)
                    {
                        player.Session.Network.EnqueueSend(new GameEventCommunicationTransientString(player.Session, "You do not have enough container slots to use that!"));
                    }
                    return;
                }

                if (itemStacks > 0)
                {
                    while (amount > 0)
                    {
                        var item = WorldObjectFactory.CreateNewWorldObject(UseCreateItem.Value);

                        if (item is Stackable)
                        {
                            // amount contains a max stack
                            if (item.MaxStackSize <= amount)
                            {
                                item.SetStackSize(item.MaxStackSize);
                                amount -= item.MaxStackSize.Value;
                            }
                            else // not a full stack
                            {
                                item.SetStackSize(amount);
                                amount -= amount;
                            }
                        }
                        else
                        {
                            amount -= 1;
                        }

                        player.TryCreateInInventoryWithNetworking(item);
                    }
                }
                else
                {
                    player.Session.Network.EnqueueSend(new GameEventCommunicationTransientString(player.Session, $"Unable to use {Name} at this time!"));
                    return;
                }
            }

            if ((GetProperty(PropertyBool.UnlimitedUse) ?? false) == false)
            {
                player.TryConsumeFromInventoryWithNetworking(this, 1);
            }
        }
Example #2
0
        public void ActOnUse(WorldObject activator, bool confirmed)
        {
            if (!(activator is Player player))
            {
                return;
            }

            if (player.IsBusy || player.Teleporting || player.suicideInProgress)
            {
                player.SendWeenieError(WeenieError.YoureTooBusy);
                return;
            }

            if (player.IsJumping)
            {
                player.SendWeenieError(WeenieError.YouCantDoThatWhileInTheAir);
                return;
            }

            if (!string.IsNullOrWhiteSpace(UseSendsSignal))
            {
                player.CurrentLandblock?.EmitSignal(player, UseSendsSignal);
                return;
            }

            // handle rare gems
            if (RareId != null && player.GetCharacterOption(CharacterOption.ConfirmUseOfRareGems) && !confirmed)
            {
                var msg     = $"Are you sure you want to use {Name}?";
                var confirm = new Confirmation_Custom(player.Guid, () => ActOnUse(activator, true));
                player.ConfirmationManager.EnqueueSend(confirm, msg);
                return;
            }

            if (RareUsesTimer)
            {
                var currentTime = Time.GetUnixTime();

                var timeElapsed = currentTime - player.LastRareUsedTimestamp;

                if (timeElapsed < RareTimer)
                {
                    // TODO: get retail message
                    var remainTime = (int)Math.Ceiling(RareTimer - timeElapsed);
                    player.Session.Network.EnqueueSend(new GameMessageSystemChat($"You may use another timed rare in {remainTime}s", ChatMessageType.Broadcast));
                    return;
                }
            }

            if (UseUserAnimation != MotionCommand.Invalid)
            {
                // some gems have UseUserAnimation and UseSound, similar to food
                // eg. 7559 - Condensed Dispel Potion

                // the animation is also weird, and differs from food, in that it is the full animation
                // instead of stopping at the 'eat/drink' point... so we pass 0.5 here?

                player.ApplyConsumable(UseUserAnimation, () => UseGem(player), 0.5f);
            }
            else
            {
                UseGem(player);
            }
        }