Пример #1
0
        public static void HandleContract(Session session, params string[] parameters)
        {
            if (!(parameters?.Length > 0))
            {
                return;
            }
            if (!uint.TryParse(parameters[0], out var contractId))
            {
                return;
            }

            ContractTracker contractTracker = new ContractTracker(contractId, session.Player.Guid.Full)
            {
                Stage                = 0,
                TimeWhenDone         = 0,
                TimeWhenRepeats      = 0,
                DeleteContract       = 0,
                SetAsDisplayContract = 1
            };

            if (!session.Player.TrackedContracts.ContainsKey(contractId))
            {
                session.Player.TrackedContracts.Add(contractId, contractTracker);
            }

            GameEventSendClientContractTracker contractMsg = new GameEventSendClientContractTracker(session, contractTracker);

            session.Network.EnqueueSend(contractMsg);
            ChatPacket.SendServerMessage(session, "You just added " + contractTracker.ContractDetails.ContractName, ChatMessageType.Broadcast);
        }
Пример #2
0
 public override void Unpack(BinaryReader reader)
 {
     base.Unpack(reader);
     ContractTracker.Unpack(reader);
     DeleteContract       = reader.ReadBool32();
     SetAsDisplayContract = reader.ReadBool32();
 }
Пример #3
0
        /// <summary>
        /// This method is part of the contract tracking functions.   This is used to remove or abandon a contract.
        /// The method validates the id passed from the client against the portal.dat file, then sends the appropriate
        /// response to the client to remove the item from the quest panel. Og II
        /// </summary>
        /// <param name="contractId">This is the contract id passed to us from the client that we want to remove.</param>
        public void HandleActionAbandonContract(uint contractId)
        {
            ContractTracker contractTracker = new ContractTracker(contractId, Guid.Full)
            {
                Stage                = 0,
                TimeWhenDone         = 0,
                TimeWhenRepeats      = 0,
                DeleteContract       = 1,
                SetAsDisplayContract = 0
            };

            GameEventSendClientContractTracker contractMsg = new GameEventSendClientContractTracker(Session, contractTracker);

            /* todo fix for new EF model
             * AceContractTracker contract = new AceContractTracker();
             * if (TrackedContracts.ContainsKey(contractId))
             *  contract = TrackedContracts[contractId].SnapShotOfAceContractTracker();
             *
             * TrackedContracts.Remove(contractId);
             * LastUseTracker.Remove((int)contractId);
             * AceObject.TrackedContracts.Remove(contractId);
             *
             * DatabaseManager.Shard.DeleteContract(contract, deleteSuccess =>
             * {
             *  if (deleteSuccess)
             *      log.Info($"ContractId {contractId:X} successfully deleted");
             *  else
             *      log.Error($"Unable to delete contractId {contractId:X} ");
             * });
             *
             * Session.Network.EnqueueSend(contractMsg);*/
        }
Пример #4
0
        public GameEventSendClientContractTracker(Session session, CharacterPropertiesContractRegistry contract) : base(GameEventType.SendClientContractTracker, GameMessageGroup.UIQueue, session)
        {
            var contractTracker = new ContractTracker(session.Player, contract);

            Writer.Write(contractTracker);
            Writer.Write(Convert.ToUInt32(contractTracker.DeleteContract));
            Writer.Write(Convert.ToUInt32(contractTracker.SetAsDisplayContract));
        }
        /// <summary>
        /// This message is used to both add and remove quests in your quest panel.   The first use case, the add is stright forward
        /// and is sent in response to an onUse of a contract from your inventory. F7B1 0036 - Inventory_UseEvent
        /// The second use case is the abandon quest.   This sends a F7B1 0316  Social_AbandonContract in this case you send back the contract id
        /// you got in the message from the client and pass back a 1 in the deleteContract parameter. Og II
        /// </summary>
        /// <param name="session">Our player session used for getting message recipient guid and the correct message sequence.</param>
        /// <param name="contractTracker">This class contains all of the information we need to send the client about the contract. </param>

        public GameEventSendClientContractTracker(Session session, ContractTracker contractTracker)
            : base(GameEventType.SendClientContractTracker, GameMessageGroup.Group09, session)
        {
            Writer.Write(contractTracker.Version);
            Writer.Write(contractTracker.ContractId);
            Writer.Write(contractTracker.Stage);
            Writer.Write(contractTracker.TimeWhenDone);
            Writer.Write(contractTracker.TimeWhenRepeats);
            Writer.Write(contractTracker.DeleteContract);
            Writer.Write(contractTracker.SetAsDisplayContract);
        }
Пример #6
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);

                string castMessage = "The gem casts " + spell.Name + " on you";
                ////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";
                }
                castMessage += "."; // If not refreshing/surpassing/less than active spell, which I will check for in the very near future when I get the active enchantment list implemented.

                player.Session.Network.EnqueueSend(new GameMessageSystemChat(castMessage, ChatMessageType.Magic));
                player.PlayParticleEffect((PlayScript)spellBase.TargetEffect, player.Guid);
                const ushort layer = 1; // FIXME: This will be tracked soon, once a list is made to track active enchantments
                var          gem   = new Enchantment(player, SpellDID.Value, (double)spell.Duration, layer, spell.Category);
                player.Session.Network.EnqueueSend(new GameEventMagicUpdateEnchantment(player.Session, gem));

                // add to enchantment registry
                player.EnchantmentManager.Add(gem, false);

                ////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();
        }
Пример #7
0
        public void ActOnUseContract(Player player)
        {
            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);
                    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;
                    }
                }

                player.Session.Network.EnqueueSend(new GameEventSendClientContractTracker(player.Session, contractTracker));
                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, layer, /*CooldownId.Value,*/ EnchantmentMask.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.TryConsumeFromInventoryWithNetworking(this, 1);
            }
            else
            {
                ChatPacket.SendServerMessage(player.Session, "You already have this quest tracked: " + contractTracker.ContractDetails.ContractName, ChatMessageType.Broadcast);
            }
        }
Пример #8
0
        /// <summary>
        /// This is raised by Player.HandleActionUseItem.<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)
        {
            // TODO: verify use requirements

            if (UseCreateContractId == null)
            {
                //var spell = new Spell((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(this, (uint)SpellDID);

                if ((GetProperty(PropertyBool.UnlimitedUse) ?? false) == false)
                {
                    player.TryConsumeFromInventoryWithNetworking(this);
                }

                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, player.Guid.Full, spellBase, spellBase.Duration, layer, /*CooldownId.Value,*/ EnchantmentMask.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.TryConsumeFromInventoryWithNetworking(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();
        }
Пример #9
0
 public Contract()
 {
     _signees = new List<Signee>();
     _tracker = new ContractTracker();
 }
Пример #10
0
 public override void Pack(BinaryWriter writer)
 {
     ContractTracker.Pack(writer);
     writer.WriteBool32(DeleteContract);
     writer.WriteBool32(SetAsDisplayContract);
 }