ServUO Version
Publish Unknown
Ultima Expansion
None
in the portion
Effects.SendLocationEffect( p, Map, 0x352D, 16, 4 );

I change the number 16 to 1500 and the bobber stays longer but it only last for around 10 seconds I need it to stay around 20 seconds. I've tried 3000 and it still disappears at 10 seconds. Trying to get the bobber to stay until It comes up with a catch is how I want it to work.





bobber Timmer:
        private static bool ValidateDeepWater( Map map, int x, int y )
        {
            int tileID = map.Tiles.GetLandTile( x, y ).ID;
            bool water = false;

            for ( int i = 0; !water && i < m_WaterTiles.Length; i += 2 )
                water = ( tileID >= m_WaterTiles[i] && tileID <= m_WaterTiles[i + 1] );

            return water;
        }
        
        private void DoEffect( object state )
        {
            if ( Deleted )
                return;

            object[] states = (object[])state;

            Point3D p = (Point3D)states[0];
            int index = (int)states[1];

            states[1] = ++index;

            if ( index == 1 )
            {
//                Effects.SendLocationEffect( p, Map, 0x352D, 16, 4 );
                Effects.SendLocationEffect( p, Map, 0x3C0F, 16, 4 );
                Effects.PlaySound( p, Map, 0x364 );
            }
            else if ( index <= 10 || index == 20 )
            {
                for ( int i = 0; i < 3; ++i )
                {
                    int x, y;

                    switch ( Utility.Random( 8 ) )
                    {
                        default:
                        case 0: x = -1; y = -1; break;
                        case 1: x = -1; y =  0; break;
                        case 2: x = -1; y = +1; break;
                        case 3: x =  0; y = -1; break;
                        case 4: x =  0; y = +1; break;
                        case 5: x = +1; y = -1; break;
                        case 6: x = +1; y =  0; break;
                        case 7: x = +1; y = +1; break;
                    }

                    Effects.SendLocationEffect( new Point3D( p.X + x, p.Y + y, p.Z ), Map, 0x352D, 16, 4 );
                }

                Effects.PlaySound( p, Map, 0x364 );

                if ( index == 20 )
                    FinishEffect( p );
                else
                    this.Z -= 1;
            }
        }
        
        private void FinishEffect( Point3D p )
        {
            Item fish = GiveFish( m_Player.Skills.Fishing.Base / 100 );
            
            if ( fish != null )
            {               
                m_Player.SendMessage( "You empty your catch from the trap." );
                fish.MoveToWorld( m_Player.Location, m_Player.Map );
                    
                Movable = true;
                
                if ( !m_Player.PlaceInBackpack( this ) )
                    MoveToWorld( m_Player.Location, m_Player.Map );
            }
            else if (Utility.RandomDouble() < 0.75)         
            {
                Movable = true;
                
                if ( !m_Player.PlaceInBackpack( this ) )
                    MoveToWorld( m_Player.Location, m_Player.Map );
                    
                    m_Player.SendLocalizedMessage( 1074487 ); // The creatures are too quick for you!
            }   
            else
            {
                this.Delete();
                m_Player.SendMessage( "Your trap is destroyed while trying to pull it from the water." );   
            }
        }
 
Assuming DoEffect is called on a timer with a one second interval, then you should only need to increase the check for the index:
C#:
index == 20

When the index value hits 20, it will stop the effect, change this to 30.
There's more than one place that checks the value.
 
Thanks for the reply.
I tried changing the 20 to 30 that's the duration of bubbles but the bobber is the items # 0x3C0F and when I change the number 16 to say 1000 it increases the length the bobber stays before it disappears but seems to cap out at 10 15 seconds what do the numbers 16 and 4 control?

here is the full script
bobber Timmer:
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Targeting;
using Server.Network;
using Server.Engines.Harvest;

namespace Server.Items
{
    public class LobsterTrap : Item
    {

        private static int[] m_WaterTiles = { 0x00A8, 0x00AB, 0x0136,
                                              0x0137, 0x5797, 0x579C,
                                              0x746E, 0x7485, 0x7490,
                                              0x74AB, 0x74B5, 0x75D5 };
        
        private Mobile m_Player;
        
        [Constructable]
        public LobsterTrap() : base( 0x3C13 )
        {
            Name = "A Lobster Trap";
            Weight = 5.0;
            
        }

        public LobsterTrap( Serial serial ) : base( serial )
        {       
        }
        
        public override void OnDoubleClick( Mobile from )
        {
            if ( !IsChildOf( from.Backpack ) )
            {
                from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
                return;
            }
            else if ( from.Mounted )
            {
                from.SendMessage("You can't use the trap while riding.");
                return;
            }           
                
            from.SendMessage( "Where do you wish to use the trap?" );
            
            from.BeginTarget( -1, true, TargetFlags.None, new TargetCallback( OnTarget ) );
        }
        
        public void OnTarget( Mobile from, object obj )
        {
            m_Player = from;
            
            if ( Deleted )
                return;

            IPoint3D p3D = obj as IPoint3D;

            if ( p3D == null )
                return;

            Map map = from.Map;

            if ( map == null || map == Map.Internal )
                return;

            int x = p3D.X, y = p3D.Y;

            if ( !from.InRange( p3D, 6 ) )
            {
                from.SendMessage( "You need to be closer to the water to use your trap." );
            }
            else if ( FullValidation( map, x, y ) )
            {
                Point3D p = new Point3D( x, y, map.GetAverageZ( x, y ) );

                Movable = false;
                MoveToWorld( p, map );

                from.Animate( 12, 5, 1, true, false, 0 );

                Timer.DelayCall( TimeSpan.FromSeconds( 1.5 ), TimeSpan.FromSeconds( 1.0 ), 20, new TimerStateCallback( DoEffect ), new object[]{ p, 0 } );

                from.SendMessage( "You plunge the trap into the sea..." );
            }
            else
            {
                from.SendMessage( "You can only use this trap in deep water!" );
            }
        }
        
        public static bool FullValidation( Map map, int x, int y )
        {
            bool valid = ValidateDeepWater( map, x, y );

            for ( int j = 1, offset = 5; valid && j <= 5; ++j, offset += 5 )
            {
                if ( !ValidateDeepWater( map, x + offset, y + offset ) )
                    valid = false;
                else if ( !ValidateDeepWater( map, x + offset, y - offset ) )
                    valid = false;
                else if ( !ValidateDeepWater( map, x - offset, y + offset ) )
                    valid = false;
                else if ( !ValidateDeepWater( map, x - offset, y - offset ) )
                    valid = false;
            }

            return valid;
        }

        private static bool ValidateDeepWater( Map map, int x, int y )
        {
            int tileID = map.Tiles.GetLandTile( x, y ).ID;
            bool water = false;

            for ( int i = 0; !water && i < m_WaterTiles.Length; i += 2 )
                water = ( tileID >= m_WaterTiles[i] && tileID <= m_WaterTiles[i + 1] );

            return water;
        }
        
        private void DoEffect( object state )
        {
            if ( Deleted )
                return;

            object[] states = (object[])state;

            Point3D p = (Point3D)states[0];
            int index = (int)states[1];

            states[1] = ++index;

            if ( index == 1 )
            {
//                Effects.SendLocationEffect( p, Map, 0x352D, 16, 4 );
                Effects.SendLocationEffect( p, Map, 0x3C0F, 30, 4 );
                Effects.PlaySound( p, Map, 0x364 );
            }
            else if ( index <= 10 || index == 20 )
            {
                for ( int i = 0; i < 3; ++i )
                {
                    int x, y;

                    switch ( Utility.Random( 8 ) )
                    {
                        default:
                        case 0: x = -1; y = -1; break;
                        case 1: x = -1; y =  0; break;
                        case 2: x = -1; y = +1; break;
                        case 3: x =  0; y = -1; break;
                        case 4: x =  0; y = +1; break;
                        case 5: x = +1; y = -1; break;
                        case 6: x = +1; y =  0; break;
                        case 7: x = +1; y = +1; break;
                    }

                    Effects.SendLocationEffect( new Point3D( p.X + x, p.Y + y, p.Z ), Map, 0x352D, 16, 4 );
                }

                Effects.PlaySound( p, Map, 0x364 );

                if ( index == 20 )
                    FinishEffect( p );
                else
                    this.Z -= 1;
            }
        }
        
        private void FinishEffect( Point3D p )
        {
            Item fish = GiveFish( m_Player.Skills.Fishing.Base / 100 );
            
            if ( fish != null )
            {               
                m_Player.SendMessage( "You empty your catch from the trap." );
                fish.MoveToWorld( m_Player.Location, m_Player.Map );
                    
                Movable = true;
                
                if ( !m_Player.PlaceInBackpack( this ) )
                    MoveToWorld( m_Player.Location, m_Player.Map );
            }
            else if (Utility.RandomDouble() < 0.75)         
            {
                Movable = true;
                
                if ( !m_Player.PlaceInBackpack( this ) )
                    MoveToWorld( m_Player.Location, m_Player.Map );
                    
                    m_Player.SendLocalizedMessage( 1074487 ); // The creatures are too quick for you!
            }   
            else
            {
                this.Delete();
                m_Player.SendMessage( "Your trap is destroyed while trying to pull it from the water." );   
            }
        }   
        
        public Item GiveFish( double skill )
        {
            if ( 0.038 * skill > Utility.RandomDouble() ) return new RockLobster();
            if ( 0.040 * skill > Utility.RandomDouble() ) return new RedRockCrab();
            if ( 0.046 * skill > Utility.RandomDouble() ) return new SpineyLobster();
            if ( 0.052 * skill > Utility.RandomDouble() ) return new SnowCrab();
            if ( 0.058 * skill > Utility.RandomDouble() ) return new Lobster();
            if ( 0.062 * skill > Utility.RandomDouble() ) return new BlueCrab();
            if ( 0.064 * skill > Utility.RandomDouble() ) return new Crab();
            if ( 0.076 * skill > Utility.RandomDouble() ) return new Prawn();//need to add to seafood cooking maybe with stat boost
                
            return null;
        }

        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );

            writer.Write( (int) 0 ); // version
        }

        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );

            int version = reader.ReadInt();
        }
    }
}
 
Last edited:
The numbers are for speed and duration, but that's still not the problem.
The timer itself has a count limit of 20 before it automatically stops, so you need to update that to 30 too.

Line 83
C#:
Timer.DelayCall( TimeSpan.FromSeconds( 1.5 ), TimeSpan.FromSeconds( 1.0 ), 20, new TimerStateCallback( DoEffect ), new object[]{ p, 0 } );
 
Back