Пример #1
0
        public virtual void ProcessDelta()
        {
            Mobile m = this;
            MobileDelta delta;
            MobileDelta attrs;

            delta = m.m_DeltaFlags;

            if ( delta == MobileDelta.None )
                return;

            attrs = delta & MobileDelta.Attributes;

            m.m_DeltaFlags = MobileDelta.None;
            m.m_InDeltaQueue = false;

            bool sendHits = false, sendStam = false, sendMana = false, sendAll = false, sendAny = false;
            bool sendIncoming = false, sendNonlocalIncoming = false;
            bool sendUpdate = false, sendRemove = false;
            bool sendPublicStats = false, sendPrivateStats = false;
            bool sendMoving = false, sendNonlocalMoving = false;
            bool sendOPLUpdate = Core.AOS && (delta & MobileDelta.Properties) != 0;

            if ( attrs != MobileDelta.None )
            {
                sendAny = true;

                if ( attrs == MobileDelta.Attributes )
                {
                    sendAll = true;
                }
                else
                {
                    sendHits = ( (attrs & MobileDelta.Hits) != 0 );
                    sendStam = ( (attrs & MobileDelta.Stam) != 0 );
                    sendMana = ( (attrs & MobileDelta.Mana) != 0 );
                }
            }

            if ( (delta & MobileDelta.GhostUpdate) != 0 )
            {
                sendNonlocalIncoming = true;
            }

            if ( (delta & MobileDelta.Hue) != 0 )
            {
                sendNonlocalIncoming = true;
                sendUpdate = true;
                sendRemove = true;
            }

            if ( (delta & MobileDelta.Direction) != 0 )
            {
                sendNonlocalMoving = true;
                sendUpdate = true;
            }

            if ( (delta & MobileDelta.Body) != 0 )
            {
                sendUpdate = true;
                sendIncoming = true;
            }

            /*if ( (delta & MobileDelta.Hue) != 0 )
                {
                    sendNonlocalIncoming = true;
                    sendUpdate = true;
                }
                else if ( (delta & (MobileDelta.Direction | MobileDelta.Body)) != 0 )
                {
                    sendNonlocalMoving = true;
                    sendUpdate = true;
                }
                else*/ if ( (delta & (MobileDelta.Flags | MobileDelta.Noto)) != 0 )
                       {
                           sendMoving = true;
                       }

            if ( (delta & MobileDelta.Name) != 0 )
            {
                sendAll = false;
                sendHits = false;
                sendAny = sendStam || sendMana;
                sendPublicStats = true;
            }

            if ( (delta & (MobileDelta.WeaponDamage | MobileDelta.Resistances | MobileDelta.Stat | MobileDelta.Weight | MobileDelta.Gold | MobileDelta.Armor | MobileDelta.StatCap | MobileDelta.Followers | MobileDelta.TithingPoints)) != 0 )
            {
                sendPrivateStats = true;
            }

            MobileMoving[] cache = m_MovingPacketCache;

            if ( sendMoving || sendNonlocalMoving )
            {
                for ( int i = 0; i < cache.Length; ++i )
                    cache[i] = null;
            }

            NetState ourState = m.m_NetState;

            if ( ourState != null )
            {
                if ( sendUpdate )
                {
                    ourState.Sequence = 0;
                    ourState.Send( new MobileUpdate( m ) );
                    ClearFastwalkStack();
                }

                if ( sendIncoming )
                    ourState.Send( new MobileIncoming( m, m ) );

                if ( sendMoving )
                {
                    int noto = Notoriety.Compute( m, m );

                    ourState.Send( cache[noto] = new MobileMoving( m, noto ) );
                }

                if ( sendPublicStats || sendPrivateStats )
                {
                    ourState.Send( new MobileStatusExtended( m ) );
                }
                else if ( sendAll )
                {
                    ourState.Send( new MobileAttributes( m ) );
                }
                else if ( sendAny )
                {
                    if ( sendHits )
                        ourState.Send( new MobileHits( m ) );

                    if ( sendStam )
                        ourState.Send( new MobileStam( m ) );

                    if ( sendMana )
                        ourState.Send( new MobileMana( m ) );
                }

                if ( sendStam || sendMana )
                {
                    IParty ip = m_Party as IParty;

                    if ( ip != null && sendStam )
                        ip.OnStamChanged( this );

                    if ( ip != null && sendMana )
                        ip.OnManaChanged( this );
                }

                if ( sendOPLUpdate )
                    ourState.Send( OPLPacket );
            }

            sendMoving = sendMoving || sendNonlocalMoving;
            sendIncoming = sendIncoming || sendNonlocalIncoming;
            sendHits = sendHits || sendAll;

            if ( m.m_Map != null && (sendRemove || sendIncoming || sendPublicStats || sendHits || sendMoving || sendOPLUpdate) )
            {
                Mobile beholder;

                IPooledEnumerable eable = m.Map.GetClientsInRange( m.m_Location );

                Packet hitsPacket = null;
                Packet statPacketTrue = null, statPacketFalse = null;
                Packet deadPacket = null;

                foreach ( NetState state in eable )
                {
                    beholder = state.Mobile;

                    if ( beholder != m && beholder.CanSee( m ) )
                    {
                        if ( sendRemove )
                            state.Send( m.RemovePacket );

                        if ( sendIncoming )
                        {
                            state.Send( new MobileIncoming( beholder, m ) );

                            if ( m.IsDeadBondedPet )
                            {
                                if ( deadPacket == null )
                                    deadPacket = new BondedStatus( 0, m.m_Serial, 1 );

                                state.Send( deadPacket );
                            }
                        }

                        if ( sendMoving )
                        {
                            int noto = Notoriety.Compute( beholder, m );

                            MobileMoving p = cache[noto];

                            if ( p == null )
                                cache[noto] = p = new MobileMoving( m, noto );

                            state.Send( p );
                        }

                        if ( sendPublicStats )
                        {
                            if ( m.CanBeRenamedBy( beholder ) )
                            {
                                if ( statPacketTrue == null )
                                    statPacketTrue = new MobileStatusCompact( true, m );

                                state.Send( statPacketTrue );
                            }
                            else
                            {
                                if ( statPacketFalse == null )
                                    statPacketFalse = new MobileStatusCompact( false, m );

                                state.Send( statPacketFalse );
                            }
                        }
                        else if ( sendHits )
                        {
                            if ( hitsPacket == null )
                                hitsPacket = new MobileHitsN( m );

                            state.Send( hitsPacket );
                        }

                        if ( sendOPLUpdate )
                            state.Send( OPLPacket );
                    }
                }

                eable.Free();
            }
        }
Пример #2
0
        public virtual bool Move( Direction d )
        {
            if ( m_Deleted )
                return false;

            BankBox box = FindBankNoCreate();

            if ( box != null && box.Opened )
                box.Close();

            Point3D newLocation = Location;
            Point3D oldLocation = newLocation;

            if ( (m_Direction & Direction.Mask) == (d & Direction.Mask) )
            {
                // We are actually moving (not just a direction change)

                if ( m_Spell != null && !m_Spell.OnCasterMoving( d ) )
                    return false;

                if ( m_Paralyzed || m_Frozen )
                {
                    SendLocalizedMessage( 500111 ); // You are frozen and can not move.

                    return false;
                }

                int newZ;

                if ( CheckMovement( d, out newZ ) )
                {
                    int x = m_Location.m_X, y = m_Location.m_Y;
                    int oldX = x, oldY = y;
                    int oldZ = m_Location.m_Z;

                    switch ( d & Direction.Mask )
                    {
                        case Direction.North:      --y; break;
                        case Direction.Right: ++x; --y; break;
                        case Direction.East:  ++x;      break;
                        case Direction.Down:  ++x; ++y; break;
                        case Direction.South:      ++y; break;
                        case Direction.Left:  --x; ++y; break;
                        case Direction.West:  --x;      break;
                        case Direction.Up:    --x; --y; break;
                    }

                    m_Pushing = false;

                    Map map = m_Map;

                    if ( map != null )
                    {
                        Sector oldSector = map.GetSector( oldX, oldY );
                        Sector newSector = map.GetSector( x, y );
                        ArrayList list;

                        if ( oldSector != newSector )
                        {
                            list = oldSector.Mobiles;

                            for ( int i = 0; i < list.Count; ++i )
                            {
                                Mobile m = (Mobile)list[i];

                                if ( m != this && m.X == oldX && m.Y == oldY && (m.Z + 15) > oldZ && (oldZ + 15) > m.Z && !m.OnMoveOff( this ) )
                                    return false;
                            }

                            list = oldSector.Items;

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

                                if ( item.AtWorldPoint( oldX, oldY ) && (item.Z == oldZ || ((item.Z + item.ItemData.Height) > oldZ && (oldZ + 15) > item.Z)) && !item.OnMoveOff( this ) )
                                    return false;
                            }

                            list = newSector.Mobiles;

                            for ( int i = 0; i < list.Count; ++i )
                            {
                                Mobile m = (Mobile)list[i];

                                if ( m.X == x && m.Y == y && (m.Z + 15) > newZ && (newZ + 15) > m.Z && !m.OnMoveOver( this ) )
                                    return false;
                            }

                            list = newSector.Items;

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

                                if ( item.AtWorldPoint( x, y ) && (item.Z == newZ || ((item.Z + item.ItemData.Height) > newZ && (newZ + 15) > item.Z)) && !item.OnMoveOver( this ) )
                                    return false;
                            }
                        }
                        else
                        {
                            list = oldSector.Mobiles;

                            for ( int i = 0; i < list.Count; ++i )
                            {
                                Mobile m = (Mobile)list[i];

                                if ( m != this && m.X == oldX && m.Y == oldY && (m.Z + 15) > oldZ && (oldZ + 15) > m.Z && !m.OnMoveOff( this ) )
                                    return false;
                                else if ( m.X == x && m.Y == y && (m.Z + 15) > newZ && (newZ + 15) > m.Z && !m.OnMoveOver( this ) )
                                    return false;
                            }

                            list = oldSector.Items;

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

                                if ( item.AtWorldPoint( oldX, oldY ) && (item.Z == oldZ || ((item.Z + item.ItemData.Height) > oldZ && (oldZ + 15) > item.Z)) && !item.OnMoveOff( this ) )
                                    return false;
                                else if ( item.AtWorldPoint( x, y ) && (item.Z == newZ || ((item.Z + item.ItemData.Height) > newZ && (newZ + 15) > item.Z)) && !item.OnMoveOver( this ) )
                                    return false;
                            }
                        }

                        Region region = Region.Find( new Point3D( x, y, newZ ), m_Map );

                        if ( region != null && !region.OnMoveInto( this, d, new Point3D( x, y, newZ ), oldLocation ) )
                            return false;
                    }
                    else
                    {
                        return false;
                    }

                    if ( !InternalOnMove( d ) )
                        return false;

                    if ( m_FwdEnabled && m_NetState != null && m_AccessLevel < m_FwdAccessOverride && (!m_FwdUOTDOverride || (m_NetState.Version != null && m_NetState.Version.Type != ClientType.UOTD)) )
                    {
                        if ( m_MoveRecords == null )
                            m_MoveRecords = new Queue( 6 );

                        while ( m_MoveRecords.Count > 0 )
                        {
                            MovementRecord r = (MovementRecord)m_MoveRecords.Peek();

                            if ( r.Expired() )
                                m_MoveRecords.Dequeue();
                            else
                                break;
                        }

                        if ( m_MoveRecords.Count >= m_FwdMaxSteps )
                        {
                            FastWalkEventArgs fw = new FastWalkEventArgs( m_NetState );
                            EventSink.InvokeFastWalk( fw );

                            if ( fw.Blocked )
                                return false;
                        }

                        TimeSpan delay;

                        if ( Mounted )
                            delay = (d & Direction.Running) != 0 ? m_RunMount : m_WalkMount;
                        else
                            delay = (d & Direction.Running) != 0 ? m_RunFoot : m_WalkFoot;

                        DateTime end;

                        if ( m_MoveRecords.Count > 0 )
                            end = m_EndQueue + delay;
                        else
                            end = DateTime.Now + delay;

                        m_MoveRecords.Enqueue( MovementRecord.NewInstance( end ) );

                        m_EndQueue = end;
                    }

                    m_LastMoveTime = DateTime.Now;
                    newLocation = new Point3D( x, y, newZ );
                }
                else
                {
                    return false;
                }

                DisruptiveAction();
            }

            if ( m_NetState != null )
                m_NetState.Send( MovementAck.Instantiate( m_NetState.Sequence, this ) );//new MovementAck( m_NetState.Sequence, this ) );

            SetLocation( newLocation, false );
            SetDirection( d );

            if ( m_Map != null )
            {
                MobileMoving[] cache = m_MovingPacketCache;

                for ( int i = 0; i < cache.Length; ++i )
                    cache[i] = null;

                IPooledEnumerable eable = m_Map.GetObjectsInRange( m_Location, Core.GlobalMaxUpdateRange );

                foreach ( object o in eable )
                {
                    if ( o == this )
                        continue;

                    if ( o is Mobile )
                    {
                        m_MoveList.Add( o );
                    }
                    else if ( o is Item )
                    {
                        Item item = (Item)o;

                        if ( item.HandlesOnMovement )
                            m_MoveList.Add( item );
                    }
                }

                eable.Free();

                for ( int i = 0; i < m_MoveList.Count; ++i )
                {
                    object o = m_MoveList[i];

                    if ( o is Mobile )
                    {
                        Mobile m = (Mobile)m_MoveList[i];
                        NetState ns = m.NetState;

                        if ( ns != null && Utility.InUpdateRange( m_Location, m.m_Location ) && m.CanSee( this ) )
                        {
                            int noto = Notoriety.Compute( m, this );
                            MobileMoving p = cache[noto];

                            if ( p == null )
                                p = cache[noto] = new MobileMoving( this, noto );

                            ns.Send( p );
                        }

                        m.OnMovement( this, oldLocation );
                    }
                    else if ( o is Item )
                    {
                        ((Item)o).OnMovement( this, oldLocation );
                    }
                }

                if ( m_MoveList.Count > 0 )
                    m_MoveList.Clear();
            }

            return true;
        }