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); } }
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); } }