Beispiel #1
0
        public override void DropItem(Item dropped)
        {
            if (GetFlag(CorpseFlag.Instanced))
            {
                List <Container> corpses = new List <Container>();

                for (int i = 0; i < this.Items.Count; i++)
                {
                    InstancedCorpse corpse = this.Items[i] as InstancedCorpse;

                    if (corpse != null)
                    {
                        corpses.Add(corpse);
                    }
                }

                if (corpses.Count > 0)
                {
                    corpses[Utility.Random(corpses.Count)].DropItem(dropped);
                }
                else
                {
                    dropped.Delete();
                }
            }
            else
            {
                base.DropItem(dropped);
            }
        }
Beispiel #2
0
        public override void DisplayTo(Mobile to)
        {
            if (GetFlag(CorpseFlag.Instanced) && to.AccessLevel < AccessLevel.GameMaster)                 // Staff always see the main corpse
            {
                InstancedCorpse corpse = GetInstancedCorpse(to);

                if (corpse != null)
                {
                    corpse.DisplayTo(to);
                }
            }
            else
            {
                base.DisplayTo(to);
            }
        }
Beispiel #3
0
        public void AddCarvedItem(Item carved, Mobile carver)
        {
            if (GetFlag(CorpseFlag.Instanced))
            {
                InstancedCorpse corpse = GetInstancedCorpse(carver);

                if (corpse != null)
                {
                    corpse.DropItem(carved);
                }
            }
            else
            {
                this.DropItem(carved);
            }
        }
Beispiel #4
0
        private void UnsplitLoot_Callback()
        {
            SetFlag(CorpseFlag.Instanced, false);

            ArrayList corpses = new ArrayList(this.Items);

            for (int i = 0; i < corpses.Count; i++)
            {
                InstancedCorpse corpse = corpses[i] as InstancedCorpse;

                if (corpse != null)
                {
                    corpse.OnUnsplitLoot();
                }
            }
        }
Beispiel #5
0
        private InstancedCorpse GetInstancedCorpse(Mobile m)
        {
            InstancedCorpse shared = null;

            for (int i = 0; i < this.Items.Count; i++)
            {
                InstancedCorpse corpse = this.Items[i] as InstancedCorpse;

                if (corpse != null)
                {
                    if (corpse.IsOwner(m))                         // we have precedence over the instance we own
                    {
                        return(corpse);
                    }

                    if (corpse.IsAccessibleTo(m))
                    {
                        shared = corpse;
                    }
                }
            }

            return(shared);
        }
Beispiel #6
0
        public void AssignInstancedLoot()
        {
            /*
             * As per OSI tests:
             *  - Each entity (player or party) gets their own instanced corpse.
             *  - Even if no items are in the corpse or only one instance is created.
             *  - Each instanced corpse is a 'virtual' container that is actually inside the real corpse.
             *  - When a player opens an instanced corpse, it displays to him the instance he owns.
             */

            if ( m_Owner.IsPlayer )
                return; // Loot does not instance for players

            if ( m_Owner is BaseCreature && ( (BaseCreature) m_Owner ).Controlled )
                return; // Same for player's pets

            if ( m_Aggressors.Count == 0 )
                return; // Do not instantiate if nobody has looting rights

            // First of all, classify the items already existing inside the corpse

            List<Item> m_Stackables = new List<Item>();
            List<Item> m_Unstackables = new List<Item>();

            for ( int i = 0; i < this.Items.Count; i++ )
            {
                Item item = (Item) this.Items[i];

                if ( item.Stackable )
                    m_Stackables.Add( item );
                else
                    m_Unstackables.Add( item );
            }

            // Randomize the attacker's list

            Mobile[] attackers = Utility.Shuffle( m_Aggressors.ToArray() );

            // Create the instances for each player

            InstancedCorpse[] corpses = new InstancedCorpse[attackers.Length];

            for ( int i = 0; i < attackers.Length; i++ )
            {
                Party p = Party.Get( attackers[i] );

                if ( p != null )
                {
                    for ( int j = 0; j < i; j++ )
                    {
                        if ( p == Party.Get( attackers[j] ) )
                        {
                            corpses[j].AddLooter( attackers[i] );
                            corpses[i] = corpses[j]; // Players in the same party share the same instanced corpse

                            break;
                        }
                    }
                }

                if ( corpses[i] == null )
                    corpses[i] = new InstancedCorpse( this, attackers[i] );
            }

            // stackables first, for the remaining stackables, have those be randomly added after

            for ( int i = 0; i < m_Stackables.Count; i++ )
            {
                Item item = m_Stackables[i];

                if ( item.Amount >= attackers.Length )
                {
                    int amountPerAttacker = ( item.Amount / attackers.Length );
                    int remainder = ( item.Amount % attackers.Length );

                    for ( int j = 0; j < ( ( remainder == 0 ) ? corpses.Length - 1 : corpses.Length ); j++ )
                    {
                        Item splitItem = Mobile.LiftItemDupe( item, item.Amount - amountPerAttacker );

                        corpses[j].TryDropItem( splitItem );

                        // What happens to the remaining portion? TEMP FOR NOW UNTIL OSI VERIFICATION: Treat as Single Item.
                    }

                    if ( remainder == 0 )
                    {
                        corpses[corpses.Length - 1].TryDropItem( item );
                        // Add in the original item (which has an equal amount as the others) to the instance for the last attacker, cause it wasn't added above.
                    }
                    else
                    {
                        m_Unstackables.Add( item );
                    }
                }
                else
                {
                    // What happens in this case? TEMP FOR NOW UNTIL OSI VERIFICATION: Treat as Single Item.
                    m_Unstackables.Add( item );
                }
            }

            for ( int i = 0; i < m_Unstackables.Count; i++ )
            {
                // Randomly distribute unstackable items

                corpses[i % corpses.Length].TryDropItem( m_Unstackables[i] );
            }

            // Resend rummaged items to their owner's instance
            if ( m_Owner is BaseCreature )
            {
                BaseCreature bcOwner = m_Owner as BaseCreature;

                foreach ( KeyValuePair<Item, Mobile> kvp in bcOwner.RummagedItems )
                {
                    InstancedCorpse corpse = GetInstancedCorpse( kvp.Value );

                    if ( corpse != null )
                        corpse.DropItem( kvp.Key );
                }
            }

            SetFlag( CorpseFlag.Instanced, true );

            m_UnsplitTimer = Timer.DelayCall( InstancedCorpseTime, new TimerCallback( UnsplitLoot_Callback ) );
        }
Beispiel #7
0
        public void AssignInstancedLoot()
        {
            /*
             * As per OSI tests:
             *  - Each entity (player or party) gets their own instanced corpse.
             *  - Even if no items are in the corpse or only one instance is created.
             *  - Each instanced corpse is a 'virtual' container that is actually inside the real corpse.
             *  - When a player opens an instanced corpse, it displays to him the instance he owns.
             */

            if (m_Owner.IsPlayer)
            {
                return;                 // Loot does not instance for players
            }
            if (m_Owner is BaseCreature && ((BaseCreature)m_Owner).Controlled)
            {
                return;                 // Same for player's pets
            }
            if (m_Aggressors.Count == 0)
            {
                return;                 // Do not instantiate if nobody has looting rights
            }
            // First of all, classify the items already existing inside the corpse

            List <Item> m_Stackables   = new List <Item>();
            List <Item> m_Unstackables = new List <Item>();

            for (int i = 0; i < this.Items.Count; i++)
            {
                Item item = (Item)this.Items[i];

                if (item.Stackable)
                {
                    m_Stackables.Add(item);
                }
                else
                {
                    m_Unstackables.Add(item);
                }
            }

            // Randomize the attacker's list

            Mobile[] attackers = Utility.Shuffle(m_Aggressors.ToArray());

            // Create the instances for each player

            InstancedCorpse[] corpses = new InstancedCorpse[attackers.Length];

            for (int i = 0; i < attackers.Length; i++)
            {
                Party p = Party.Get(attackers[i]);

                if (p != null)
                {
                    for (int j = 0; j < i; j++)
                    {
                        if (p == Party.Get(attackers[j]))
                        {
                            corpses[j].AddLooter(attackers[i]);
                            corpses[i] = corpses[j];                             // Players in the same party share the same instanced corpse

                            break;
                        }
                    }
                }

                if (corpses[i] == null)
                {
                    corpses[i] = new InstancedCorpse(this, attackers[i]);
                }
            }

            // stackables first, for the remaining stackables, have those be randomly added after

            for (int i = 0; i < m_Stackables.Count; i++)
            {
                Item item = m_Stackables[i];

                if (item.Amount >= attackers.Length)
                {
                    int amountPerAttacker = (item.Amount / attackers.Length);
                    int remainder         = (item.Amount % attackers.Length);

                    for (int j = 0; j < ((remainder == 0) ? corpses.Length - 1 : corpses.Length); j++)
                    {
                        Item splitItem = Mobile.LiftItemDupe(item, item.Amount - amountPerAttacker);

                        corpses[j].TryDropItem(splitItem);

                        // What happens to the remaining portion? TEMP FOR NOW UNTIL OSI VERIFICATION: Treat as Single Item.
                    }

                    if (remainder == 0)
                    {
                        corpses[corpses.Length - 1].TryDropItem(item);
                        // Add in the original item (which has an equal amount as the others) to the instance for the last attacker, cause it wasn't added above.
                    }
                    else
                    {
                        m_Unstackables.Add(item);
                    }
                }
                else
                {
                    // What happens in this case? TEMP FOR NOW UNTIL OSI VERIFICATION: Treat as Single Item.
                    m_Unstackables.Add(item);
                }
            }

            for (int i = 0; i < m_Unstackables.Count; i++)
            {
                // Randomly distribute unstackable items

                corpses[i % corpses.Length].TryDropItem(m_Unstackables[i]);
            }

            // Resend rummaged items to their owner's instance
            if (m_Owner is BaseCreature)
            {
                BaseCreature bcOwner = m_Owner as BaseCreature;

                foreach (KeyValuePair <Item, Mobile> kvp in bcOwner.RummagedItems)
                {
                    InstancedCorpse corpse = GetInstancedCorpse(kvp.Value);

                    if (corpse != null)
                    {
                        corpse.DropItem(kvp.Key);
                    }
                }
            }

            SetFlag(CorpseFlag.Instanced, true);

            m_UnsplitTimer = Timer.DelayCall(InstancedCorpseTime, new TimerCallback(UnsplitLoot_Callback));
        }