/// <summary>
        /// The parse action set.
        /// </summary>
        /// <param name="actions">
        /// The actions.
        /// </param>
        /// <exception cref="Exception">
        /// </exception>
        private void ParseActionSet(List <AOAction> actions)
        {
            bool flag = this.br.ReadInt32() != 36;

            if (flag)
            {
                throw new Exception("Why am I here?");
            }

            int arg_3D_0 = 1;
            int num      = this.br.Read3F1();
            int num2     = arg_3D_0;

            checked
            {
                while (true)
                {
                    int arg_160_0 = num2;
                    int num3      = num;
                    if (arg_160_0 > num3)
                    {
                        break;
                    }

                    int actionNum = this.br.ReadInt32();

                    AOAction aoa = new AOAction();
                    aoa.ActionType = (ActionType)Enum.ToObject(typeof(ActionType), actionNum);

                    int numreqs = this.br.Read3F1();
                    List <Requirement> cookedreqs = this.ReadReqs(numreqs);
                    foreach (Requirement REQ in cookedreqs)
                    {
                        aoa.Requirements.Add(REQ);
                    }

                    if (actions == null)
                    {
                        actions = new List <AOAction>();
                    }

                    actions.Add(aoa);
                    cookedreqs.Clear();
                    num2++;
                }
            }
        }
        /// <summary>
        /// </summary>
        /// <param name="page">
        /// </param>
        /// <param name="item">
        /// </param>
        /// <returns>
        /// </returns>
        private AOAction getAction(IInventoryPage page, IItem item)
        {
            AOAction action = null;

            // TODO: Add special check for social page
            if ((page is ArmorInventoryPage) || (page is ImplantInventoryPage))
            {
                action = item.ItemActions.SingleOrDefault(x => x.ActionType == ActionType.ToWear);
                if (action == null)
                {
                    return(new AOAction());
                }
            }

            if (page is WeaponInventoryPage)
            {
                action = item.ItemActions.SingleOrDefault(x => x.ActionType == ActionType.ToWield);
                if (action == null)
                {
                    return(new AOAction());
                }
            }

            if (page is PlayerInventoryPage)
            {
                // No checks needed for unequipping
                return(new AOAction());
            }

            if (page is SocialArmorInventoryPage)
            {
                // TODO: Check for side, sex, breed conditionals
                return(new AOAction());
            }

            if (action == null)
            {
                throw new NotSupportedException(
                          "No suitable action found for equipping to this page: " + page.GetType());
            }

            return(action);
        }
示例#3
0
        /// <summary>
        /// </summary>
        public void CreateInterpolatedRequirements()
        {
            if (this.templateLow.Quality == this.templateHigh.Quality)
            {
                this.actions = this.templateLow.Actions;
                this.events  = this.templateLow.Events;
                return;
            }

            float factor = (this.Quality - this.templateLow.Quality)
                           / (this.templateHigh.Quality - this.templateLow.Quality);

            if (this.actions == null)
            {
                if (this.Quality == this.templateLow.Quality)
                {
                    this.actions = this.templateLow.Actions;
                }
                else if (this.Quality == this.templateHigh.Quality)
                {
                    this.actions = this.templateHigh.Actions;
                }
                else
                {
                    // We need to create the interpolated actions first
                    this.actions = new List <AOAction>();
                    foreach (AOAction action in this.templateLow.Actions)
                    {
                        AOAction temp = this.templateLow.Actions.Single(x => x.ActionType == action.ActionType).Copy();

                        AOAction highActions = this.templateHigh.Actions.Single(x => x.ActionType == action.ActionType);
                        AOAction lowActions  = action;
                        for (int reqnum = 0; reqnum < highActions.Requirements.Count; reqnum++)
                        {
                            temp.Requirements[reqnum].Value =
                                Convert.ToInt32(
                                    factor
                                    * (highActions.Requirements[reqnum].Value - lowActions.Requirements[reqnum].Value));
                        }

                        this.actions.Add(temp);
                    }
                }
            }

            if (this.events == null)
            {
                // We need to create interpolated events first
                if (this.Quality == this.templateLow.Quality)
                {
                    this.events = this.templateLow.Events;
                }
                else if (this.Quality == this.templateHigh.Quality)
                {
                    this.events = this.templateHigh.Events;
                }
                else
                {
                    this.events = new List <Event>();

                    for (int evnum = 0; evnum < this.templateLow.Events.Count; evnum++)
                    {
                        Event temp = this.templateLow.Events[evnum].Copy();
                        for (int funcnum = 0; funcnum < this.templateLow.Events[evnum].Functions.Count; funcnum++)
                        {
                            for (int reqnum = 0;
                                 reqnum < this.templateLow.Events[evnum].Functions[funcnum].Requirements.Count;
                                 reqnum++)
                            {
                                temp.Functions[funcnum].Requirements[reqnum].Value =
                                    Convert.ToInt32(
                                        factor
                                        * (this.templateHigh.Events[evnum].Functions[funcnum].Requirements[reqnum].Value
                                           - this.templateLow.Events[evnum].Functions[funcnum].Requirements[reqnum]
                                           .Value)
                                        + this.templateLow.Events[evnum].Functions[funcnum].Requirements[reqnum].Value);
                            }

                            for (int argnum = 0;
                                 argnum < this.templateLow.Events[evnum].Functions[funcnum].Arguments.Values.Count;
                                 argnum++)
                            {
                                if (temp.Functions[funcnum].Arguments.Values[argnum].IsTypeOf <int>() == true)
                                {
                                    temp.Functions[funcnum].Arguments.Values[argnum] =
                                        Convert.ToInt32(
                                            factor
                                            * (this.templateHigh.Events[evnum].Functions[funcnum].Arguments.Values[
                                                   argnum].AsInt32()
                                               - this.templateLow.Events[evnum].Functions[funcnum].Arguments.Values[
                                                   argnum].AsInt32())
                                            + this.templateLow.Events[evnum].Functions[funcnum].Arguments.Values[argnum]
                                            .AsInt32());
                                }
                                else if (temp.Functions[funcnum].Arguments.Values[argnum].IsTypeOf <float>() == true)
                                {
                                    temp.Functions[funcnum].Arguments.Values[argnum] = factor
                                                                                       * (this.templateHigh.Events[evnum
                                                                                          ].Functions[funcnum]
                                                                                          .Arguments.Values[argnum]
                                                                                          .AsSingle()
                                                                                          - this.templateLow.Events[
                                                                                              evnum].Functions[funcnum]
                                                                                          .Arguments.Values[argnum]
                                                                                          .AsSingle())
                                                                                       + this.templateLow.Events[evnum]
                                                                                       .Functions[funcnum].Arguments
                                                                                       .Values[argnum].AsSingle();
                                }
                            }
                        }

                        this.events.Add(temp);
                    }
                }
            }
        }
        /// <summary>
        /// </summary>
        /// <param name="message">
        /// </param>
        /// <param name="client">
        /// </param>
        protected override void Read(ContainerAddItemMessage message, IZoneClient client)
        {
            bool noAppearanceUpdate = false;

            /* Container ID's:
             * 0065 Weaponpage
             * 0066 Armorpage
             * 0067 Implantpage
             * 0068 Inventory (places 64-93)
             * 0069 Bank
             * 006B Backpack
             * 006C KnuBot Trade Window
             * 006E Overflow window
             * 006F Trade Window
             * 0073 Socialpage
             * 0767 Shop Inventory
             * 0790 Playershop Inventory
             * DEAD Trade Window (incoming) It's bank now (when you put something into the bank)
             */

            IInventoryPage sendingPage = Pool.Instance.GetObject <IInventoryPage>(
                message.Identity,
                new Identity()
            {
                Type     = (IdentityType)message.Identity.Instance,
                Instance = (int)message.SourceContainer.Type
            });
            int      fromPlacement = message.SourceContainer.Instance;
            Identity toIdentity    = message.Target;
            int      toPlacement   = message.TargetPlacement;

            // Where and what does need to be moved/added?
            IItem itemFrom = sendingPage[fromPlacement];

            // Receiver of the item (IInstancedEntity, can be mostly all from NPC, Character or Bag, later even playfields)
            // Turn 0xDEAD into C350 if instance is the same
            if (toIdentity.Type == IdentityType.IncomingTradeWindow)
            {
                toIdentity.Type = IdentityType.CanbeAffected;
            }

            IItemContainer itemReceiver =
                client.Controller.Character.Playfield.FindByIdentity(toIdentity) as IItemContainer;

            if (itemReceiver == null)
            {
                throw new ArgumentOutOfRangeException(
                          "No Entity found: " + message.Target.Type.ToString() + ":" + message.Target.Instance);
            }

            // On which inventorypage should the item be added?
            IInventoryPage receivingPage;

            if ((toPlacement == 0x6f) && (message.Target.Type == IdentityType.IncomingTradeWindow))
            {
                receivingPage = itemReceiver.BaseInventory.Pages[(int)IdentityType.Bank];
            }
            else
            {
                receivingPage = itemReceiver.BaseInventory.PageFromSlot(toPlacement);
            }

            // Get standard page if toplacement cant be found (0x6F for next free slot)
            // TODO: If Entities are not the same (other player, bag etc) then always add to the standard page
            if ((receivingPage == null) || (itemReceiver.GetType() != client.Controller.Character.GetType()))
            {
                receivingPage = itemReceiver.BaseInventory.Pages[itemReceiver.BaseInventory.StandardPage];
            }

            if (receivingPage == null)
            {
                throw new ArgumentOutOfRangeException("No inventorypage found.");
            }

            if (toPlacement == 0x6f)
            {
                toPlacement = receivingPage.FindFreeSlot();
            }

            // Is there already a item?
            IItem itemTo;

            try
            {
                itemTo = receivingPage[toPlacement];
            }
            catch (Exception)
            {
                itemTo = null;
            }

            // Calculating delay for equip/unequip/switch gear
            int delay = 20;

            client.Controller.Character.DoNotDoTimers = true;
            IItemSlotHandler equipTo     = receivingPage as IItemSlotHandler;
            IItemSlotHandler unequipFrom = sendingPage as IItemSlotHandler;

            noAppearanceUpdate =
                !((equipTo is WeaponInventoryPage) || (equipTo is ArmorInventoryPage) ||
                  (equipTo is SocialArmorInventoryPage));
            noAppearanceUpdate &=
                !((unequipFrom is WeaponInventoryPage) || (unequipFrom is ArmorInventoryPage) ||
                  (unequipFrom is SocialArmorInventoryPage));

            if (equipTo != null)
            {
                if (itemTo != null)
                {
                    if (receivingPage.NeedsItemCheck)
                    {
                        AOAction action = this.getAction(sendingPage, itemFrom);

                        if (action.CheckRequirements(client.Controller.Character))
                        {
                            UnEquip.Send(client, receivingPage, toPlacement);
                            if (!noAppearanceUpdate)
                            {
                                // Equipmentpages need delays
                                // Delay when equipping/unequipping
                                // has to be redone, jumping breaks the equiping/unequiping
                                // and other messages have to be done too
                                // like heartbeat timer, damage from environment and such

                                delay = (itemFrom.GetAttribute(211) == 1234567890 ? 20 : itemFrom.GetAttribute(211))
                                        + (itemTo.GetAttribute(211) == 1234567890 ? 20 : itemTo.GetAttribute(211));
                            }

                            Thread.Sleep(delay * 10); // social has to wait for 0.2 secs too (for helmet update)

                            client.Controller.Character.Send(message);
                            equipTo.HotSwap(sendingPage, fromPlacement, toPlacement);
                            Equip.Send(client, receivingPage, toPlacement);
                        }
                    }
                }
                else
                {
                    if (receivingPage.NeedsItemCheck)
                    {
                        if (itemFrom == null)
                        {
                            throw new NullReferenceException("itemFrom can not be null, possible inventory error");
                        }

                        AOAction action = this.getAction(receivingPage, itemFrom);

                        if (action.CheckRequirements(client.Controller.Character))
                        {
                            if (!noAppearanceUpdate)
                            {
                                // Equipmentpages need delays
                                // Delay when equipping/unequipping
                                // has to be redone, jumping breaks the equiping/unequiping
                                // and other messages have to be done too
                                // like heartbeat timer, damage from environment and such

                                delay = itemFrom.GetAttribute(211);
                                if ((equipTo is SocialArmorInventoryPage) || (delay == 1234567890))
                                {
                                    delay = 20;
                                }

                                Thread.Sleep(delay * 10);
                            }

                            if (sendingPage == receivingPage)
                            {
                                // Switch rings for example
                                UnEquip.Send(client, sendingPage, fromPlacement);
                            }

                            client.Controller.Character.Send(message);
                            equipTo.Equip(sendingPage, fromPlacement, toPlacement);
                            Equip.Send(client, receivingPage, toPlacement);
                        }
                    }
                }
            }
            else
            {
                if (unequipFrom != null)
                {
                    // Send to client first
                    if (!noAppearanceUpdate)
                    {
                        // Equipmentpages need delays
                        // Delay when equipping/unequipping
                        // has to be redone, jumping breaks the equiping/unequiping
                        // and other messages have to be done too
                        // like heartbeat timer, damage from environment and such

                        delay = itemFrom.GetAttribute(211);
                        if ((unequipFrom is SocialArmorInventoryPage) || (delay == 1234567890))
                        {
                            delay = 20;
                        }

                        Thread.Sleep(delay * 10);
                    }

                    UnEquip.Send(client, sendingPage, fromPlacement);
                    unequipFrom.Unequip(fromPlacement, receivingPage, toPlacement);
                    client.Controller.Character.Send(message);
                }
                else
                {
                    // No equipment page involved, just send ContainerAddItemMessage back
                    message.TargetPlacement = receivingPage.FindFreeSlot();
                    IItem item = sendingPage.Remove(fromPlacement);
                    receivingPage.Add(message.TargetPlacement, item);
                    client.Controller.Character.Send(message);
                }
            }

            client.Controller.Character.DoNotDoTimers = false;

            // Apply item functions before sending the appearanceupdate message
            client.Controller.Character.CalculateSkills();

            /*
             * if (!noAppearanceUpdate)
             * {
             *  AppearanceUpdateMessageHandler.Default.Send(client.Controller.Character);
             * }
             */
        }