Ejemplo n.º 1
0
        /// <summary>
        /// This is raised by Player.HandleActionUseItem, and is wrapped in ActionChain.<para />
        /// The actor of the ActionChain is the player using the item.<para />
        /// The item should be in the players possession.
        ///
        /// The OnUse method for this class is to use a contract to add a tracked quest to our quest panel.
        /// This gives the player access to information about the quest such as starting and ending NPC locations,
        /// and shows our progress for kill tasks as well as any timing information such as when we can repeat the
        /// quest or how much longer we have to complete it in the case of at timed quest.   Og II
        /// </summary>
        public override void UseItem(Player player, ActionChain actionChain)
        {
            if (UseCreateContractId == null)
            {
                var spellTable = DatManager.PortalDat.SpellTable;
                if (!spellTable.Spells.ContainsKey((uint)SpellDID))
                {
                    return;
                }

                var spellBase = DatManager.PortalDat.SpellTable.Spells[(uint)SpellDID];
                var spell     = DatabaseManager.World.GetCachedSpell((uint)SpellDID);

/*
 *              ////These if statements are to catch spells with an apostrophe in the dat file which throws off the client in reading it from the dat.
 *              if (spell.MetaSpellId == 3810)
 *                  castMessage = "The gem casts Asheron's Benediction on you";
 *              if (spell.MetaSpellId == 3811)
 *                  castMessage = "The gem casts Blackmoor's Favor on you";
 *              if (spell.MetaSpellId == 3953)
 *                  castMessage = "The gem casts Carraida's Benediction on you";
 *              if (spell.MetaSpellId == 4024)
 *                  castMessage = "The gem casts Asheron's Lesser Benediction on you";
 */

                player.CreateItemSpell(Guid, (uint)SpellDID);

                ////session.Player.HandleActionRemoveItemFromInventory(Guid.Full, (uint)ContainerId, 1); This is commented out to aid in testing. Will be uncommented later.
                player.SendUseDoneEvent();
                return;
            }

            ContractTracker contractTracker = new ContractTracker((uint)UseCreateContractId, player.Guid.Full)
            {
                Stage                = 0,
                TimeWhenDone         = 0,
                TimeWhenRepeats      = 0,
                DeleteContract       = 0,
                SetAsDisplayContract = 1
            };

            if (CooldownId != null && player.LastUseTracker.TryGetValue(CooldownId.Value, out var lastUse))
            {
                var timeRemaining = lastUse.AddSeconds(CooldownDuration ?? 0.00).Subtract(DateTime.Now);
                if (timeRemaining.Seconds > 0)
                {
                    ChatPacket.SendServerMessage(player.Session, "You cannot use another contract for " + timeRemaining.Seconds + " seconds", ChatMessageType.Broadcast);
                    player.SendUseDoneEvent();
                    return;
                }
            }

            // We need to see if we are tracking this quest already.   Also, I cannot be used on world, so I must have a container id
            if (!player.TrackedContracts.ContainsKey((uint)UseCreateContractId) && ContainerId != null)
            {
                player.TrackedContracts.Add((uint)UseCreateContractId, contractTracker);

                // This will track our use for each contract using the shared cooldown server side.
                if (CooldownId != null)
                {
                    // add or update.
                    if (!player.LastUseTracker.ContainsKey(CooldownId.Value))
                    {
                        player.LastUseTracker.Add(CooldownId.Value, DateTime.Now);
                    }
                    else
                    {
                        player.LastUseTracker[CooldownId.Value] = DateTime.Now;
                    }
                }

                GameEventSendClientContractTracker contractMsg = new GameEventSendClientContractTracker(player.Session, contractTracker);
                player.Session.Network.EnqueueSend(contractMsg);
                ChatPacket.SendServerMessage(player.Session, "You just added " + contractTracker.ContractDetails.ContractName, ChatMessageType.Broadcast);

                // TODO: Add sending the 02C2 message UpdateEnchantment.   They added a second use to this existing system
                // so they could show the delay on the client side - it is not really an enchantment but the they overloaded the use. Og II
                // Thanks Slushnas for letting me know about this as well as an awesome pcap that shows it all in action.

                // TODO: there is a lot of work to do here.   I am stubbing this in for now to send the right message.   Lots of magic numbers at the moment.
                Debug.Assert(CooldownId != null, "CooldownId != null");
                Debug.Assert(CooldownDuration != null, "CooldownDuration != null");
                //const ushort layer = 0x10000; // FIXME: we need to track how many layers of the exact same spell we have in effect.
                const ushort layer = 1;
                //const uint spellCategory = 0x8000; // FIXME: Not sure where we get this from
                var spellBase = new SpellBase(0, CooldownDuration.Value, 0, -666);
                // cooldown not being used in network packet?
                var gem = new Enchantment(player, spellBase, spellBase.Duration, layer, /*CooldownId.Value,*/ (uint)EnchantmentTypeFlags.Cooldown);
                player.Session.Network.EnqueueSend(new GameEventMagicUpdateEnchantment(player.Session, gem));

                // Ok this was not known to us, so we used the contract - now remove it from inventory.
                // HandleActionRemoveItemFromInventory is has it's own action chain.
                player.TryRemoveItemFromInventoryWithNetworking(this, 1);
            }
            else
            {
                ChatPacket.SendServerMessage(player.Session, "You already have this quest tracked: " + contractTracker.ContractDetails.ContractName, ChatMessageType.Broadcast);
            }

            // No mater any condition we need to send the use done event to clear the hour glass from the client.
            player.SendUseDoneEvent();
        }