Go Back   RunUO - Ultima Online Emulation > RunUO > Script Support

Script Support Get support for modifying RunUO Scripts, or writing your own!

Reply
 
Thread Tools Display Modes
Old 02-07-2010, 05:39 PM   #1 (permalink)
Lurker
 
Join Date: Mar 2009
Posts: 7
Default 3 Fix Questions Help

i have 3 questions i think it would be very easy for you (but not for me -.-),
- How i put a skill delay to use? i need some seconds delay before the player hide his self after he use the skill.

- When i detonate the explosion potion, the countdown start and its ok, but i want after the detonate IF i put the potion on the ground, restart count from 3... atm its working like this: detonate and start with 3, i put on the ground and its make 2 ... 1... and BOOM. i want the countdown restarting when i move!

- When the potion is in countdown and it is in the ground, i want its locked on the ground no player levelaccess can take/move it from the ground to stop the countdown.


many thanks guys for the help, i like runuo but i have to train some @scripting ;P

Last edited by mayalona; 02-07-2010 at 05:42 PM.
mayalona is offline   Reply With Quote
Old 02-09-2010, 05:05 AM   #2 (permalink)
Lurker
 
Join Date: Mar 2009
Posts: 7
Default

someone can help me?
mayalona is offline   Reply With Quote
Old 02-09-2010, 06:12 AM   #3 (permalink)
Forum Novice
 
Thagoras's Avatar
 
Join Date: May 2008
Location: In an endless goto loop
Age: 36
Posts: 558
Default

In answer to your first problem here's a nice tutorial on Timers Scripting for Dummies: Troubling Things That Start With "T" Part 1: Timers

I still use that from time to time.

As to your second question (if I understand it) you want the countdown to start once youve dropped it on the ground? I've taken a snippet from the Item.cs (from the core files)
Code:
		public virtual bool OnDroppedToWorld( Mobile from, Point3D p )
		{
			if( Nontransferable && from.Player && from.AccessLevel <= AccessLevel.GameMaster )
			{
				HandleInvalidTransfer( from );
				return false;
			}

			return true;
		}
which looks like you can just write an override (public override bool OnDroppedToWorld(Mobile from, Point3D p) ) and place your code inside the module.

And for question 3, this doesn't answer your question completely...but this works. You will need to do some modifying. I took this from one of my scripts. Once the item is placed on the ground, nobody else but the person listed as Owner may move it.
Code:
		public override bool OnDragLift( Mobile from )
		{
			if ((from == this.Owner)|| from.AccessLevel >= AccessLevel.GameMaster )
			{
				return base.OnDragLift(from);
			}
			else
			{
				from.SendMessage("This doesn't belong to you");
				return false;
			}
		}
Thagoras is offline   Reply With Quote
Old 02-10-2010, 09:43 AM   #4 (permalink)
Lurker
 
Join Date: Mar 2009
Posts: 7
Default

can i have an example editing my script? how to recall the timer after i drop the potion in the ground? so i can learn! many thanks man

thats the script of baseexplo

Code:
using System;
using System.Collections;
using Server;
using Server.Network;
using Server.Targeting;
using Server.Spells;

namespace Server.Items
{
	public abstract class BaseExplosionPotion : BasePotion
	{
		public abstract int MinDamage { get; }
		public abstract int MaxDamage { get; }

		public override bool RequireFreeHand{ get{ return false; } }

		private static bool LeveledExplosion = false; // Should explosion potions explode other nearby potions?
		private static bool InstantExplosion = false; // Should explosion potions explode on impact?
		private const int   ExplosionRange   = 2;     // How long is the blast radius?

		public BaseExplosionPotion( PotionEffect effect ) : base( 0xF0D, effect )
		{
		}

		public BaseExplosionPotion( Serial serial ) : base( serial )
		{
		}

		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();
		}

		public virtual object FindParent( Mobile from )
		{
			Mobile m = this.HeldBy;

			if ( m != null && m.Holding == this )
				return m;

			object obj = this.RootParent;

			if ( obj != null )
				return obj;

			if ( Map == Map.Internal )
				return from;

			return this;
		}

		private Timer m_Timer;

		private ArrayList m_Users;

		public override void Drink( Mobile from )
		{
			if ( from.Paralyzed || from.Frozen || (from.Spell != null && from.Spell.IsCasting) )
			{
				from.SendLocalizedMessage( 1062725 ); // You can not use a purple potion while paralyzed.
				return;
			}

			ThrowTarget targ = from.Target as ThrowTarget;

			if ( targ != null && targ.Potion == this )
				return;

			from.RevealingAction();

			if ( m_Users == null )
				m_Users = new ArrayList();

			if ( !m_Users.Contains( from ) )
				m_Users.Add( from );

			from.Target = new ThrowTarget( this );

			if ( m_Timer == null )
			{
				from.SendLocalizedMessage( 500236 ); // You should throw it now!
				m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 1.0 ), 4, new TimerStateCallback( Detonate_OnTick ), new object[]{ from, 3 } );
			}
		}

		private void Detonate_OnTick( object state )
		{
			if ( Deleted )
				return;

			object[] states = (object[])state;
			Mobile from = (Mobile)states[0];
			int timer = (int)states[1];

			object parent = FindParent( from );

			if ( timer == 0 )
			{
				Point3D loc;
				Map map;

				if ( parent is Item )
				{
					Item item = (Item)parent;

					loc = item.GetWorldLocation();
					map = item.Map;
				}
				else if ( parent is Mobile )
				{
					Mobile m = (Mobile)parent;

					loc = m.Location;
					map = m.Map;
				}
				else
				{
					return;
				}
                
				Explode( from, true, loc, map );
                
			}
			else
			{
				if ( parent is Item )
					((Item)parent).PublicOverheadMessage( MessageType.Regular, 0x22, false, timer.ToString() );
				else if ( parent is Mobile )
					((Mobile)parent).PublicOverheadMessage( MessageType.Regular, 0x22, false, timer.ToString() );
                
				states[1] = timer - 1;
                
			}
		}

		private void Reposition_OnTick( object state )
		{
			if ( Deleted )
				return;
        
			object[] states = (object[])state;
			Mobile from = (Mobile)states[0];
			IPoint3D p = (IPoint3D)states[1];
			Map map = (Map)states[2];

			Point3D loc = new Point3D( p );
        
			if ( InstantExplosion )
				Explode( from, true, loc, map );
			else
				MoveToWorld( loc, map );
		}

		private class ThrowTarget : Target
		{
			private BaseExplosionPotion m_Potion;

			public BaseExplosionPotion Potion
			{
				get{ return m_Potion; }
			}

			public ThrowTarget( BaseExplosionPotion potion ) : base( 12, true, TargetFlags.None )
			{
				m_Potion = potion;
			}

			protected override void OnTarget( Mobile from, object targeted )
			{
				if ( m_Potion.Deleted || m_Potion.Map == Map.Internal )
					return;

				IPoint3D p = targeted as IPoint3D;

				if ( p == null )
					return;

				Map map = from.Map;

				if ( map == null )
					return;

				SpellHelper.GetSurfaceTop( ref p );

				from.RevealingAction();

				IEntity to;

				if ( p is Mobile )
					to = (Mobile)p;
				else
					to = new Entity( Serial.Zero, new Point3D( p ), map );

				Effects.SendMovingEffect( from, to, m_Potion.ItemID & 0x3FFF, 7, 0, false, false, m_Potion.Hue, 0 );

				if( m_Potion.Amount > 1 )
				{
					Mobile.LiftItemDupe( m_Potion, 1 );
				}
                
				m_Potion.Internalize();

				Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), new TimerStateCallback( m_Potion.Reposition_OnTick ), new object[]{ from, p, map } );
               // Timer.DelayCall(TimeSpan.FromSeconds(1.0), new TimerStateCallback(m_Potion.Reposition_OnTick), new object[] { from, p, map });
               //Timer m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), 4, new TimerStateCallback(m_Potion.Detonate_OnTick), new object[] { from, p, map });
			}
		}

		public void Explode( Mobile from, bool direct, Point3D loc, Map map )
		{
			if ( Deleted )
				return;

			Consume();

			for ( int i = 0; m_Users != null && i < m_Users.Count; ++i )
			{
				Mobile m = (Mobile)m_Users[i];
				ThrowTarget targ = m.Target as ThrowTarget;

				if ( targ != null && targ.Potion == this )
					Target.Cancel( m );
			}

			if ( map == null )
				return;

			Effects.PlaySound( loc, map, 0x207 );
			Effects.SendLocationEffect( loc, map, 0x36BD, 20 );

			//int alchemyBonus = 0;

			//if ( direct )
			//	alchemyBonus = (int)(from.Skills.Alchemy.Value / (Core.AOS ? 5 : 10));

			IPooledEnumerable eable = LeveledExplosion ? map.GetObjectsInRange( loc, ExplosionRange ) : map.GetMobilesInRange( loc, ExplosionRange );
			ArrayList toExplode = new ArrayList();

			int toDamage = 0;

			foreach ( object o in eable )
			{
				if ( o is Mobile )
				{
					toExplode.Add( o );
					++toDamage;
				}
				else if ( o is BaseExplosionPotion && o != this )
				{
					toExplode.Add( o );
				}
			}

			eable.Free();

			int min = Scale( from, MinDamage );
			int max = Scale( from, MaxDamage );

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

				if ( o is Mobile )
				{
					Mobile m = (Mobile)o;

					if ( from == null || (from.CanBeHarmful( m, false )) )
					{
						if ( from != null )
							from.DoHarmful( m );

						int damage = Utility.RandomMinMax( min, max );

						//damage += alchemyBonus;

						if ( !Core.AOS && damage > 40 )
							damage = 40;
						else if ( Core.AOS && toDamage > 2 )
							damage /= toDamage - 1;

						AOS.Damage( m, from, damage, 0, 100, 0, 0, 0 );
					}
				}
				else if ( o is BaseExplosionPotion )
				{
					BaseExplosionPotion pot = (BaseExplosionPotion)o;

					pot.Explode( from, false, pot.GetWorldLocation(), pot.Map );
				}
			}
		}
	}
}
mayalona is offline   Reply With Quote
Old 02-10-2010, 02:05 PM   #5 (permalink)
Forum Novice
 
Thagoras's Avatar
 
Join Date: May 2008
Location: In an endless goto loop
Age: 36
Posts: 558
Default

Had an opportunity to go over the BaseExplosionPotion script. Not an easy script to make do what you wish. Not impossible though.

Seems the biggest issue is when you reposition the thing it stops the timer. I can make it so it can't be picked up (with the method I posted) but this repositions it and stops the timer. I'm thinking, you can still use the method but track down the reposition thing and turn it off. I think this is the method.
Code:
		private void Reposition_OnTick( object state )
		{
			if ( Deleted )
				return;
        
			object[] states = (object[])state;
			Mobile from = (Mobile)states[0];
			IPoint3D p = (IPoint3D)states[1];
			Map map = (Map)states[2];

			Point3D loc = new Point3D( p );
        
			if ( InstantExplosion )
				Explode( from, true, loc, map );
			else
				MoveToWorld( loc, map );
		}
As far as starting the timer when it's dropped. I misunderstood what you meant...well, I mean, in conjunction to the script itself. I had assumed that you literally mean, upon dropping it to the ground. The explosion potion has a targeting method. It's my belief that, to do what you want, you need to move the timer inside the target method. But, this can be tricky too. Give me some time to look at it.
Thagoras is offline   Reply With Quote
Old 02-10-2010, 03:34 PM   #6 (permalink)
Lurker
 
Join Date: Mar 2009
Posts: 7
Default

Oh ok! i wait for your help then...

Just need when i target on a player, and of curse the potion moves in the ground (same tile as the player is), the countdown restart from 3, and the player cant take it from the ground (you know with scavenger its easy to take it and stop the explosion)..
mayalona is offline   Reply With Quote
Old 02-10-2010, 06:11 PM   #7 (permalink)
Forum Novice
 
Thagoras's Avatar
 
Join Date: May 2008
Location: In an endless goto loop
Age: 36
Posts: 558
Default

WOW am I having trouble with this. I thought it was just going to be a simple case. You move it (or even nudge it) and the timer stops...and that's what it's all about.

I Know that this link has something to do with it.Passing parimeters using TimerCallback..

But I'm starting to see that for the moment, this is over my head and if someone else has anything to contribute that would be awesome.

At any rate, if you add this code
Code:
		public override bool OnDragLift( Mobile from )
		{  
			if ( !IsChildOf(from.Backpack) && ( m_Timer != null ) && (from.AccessLevel < AccessLevel.GameMaster) )
			{
				from.SendMessage("You can't pick that up");
				return false;
			}
			else
			{
				return base.OnDragLift(from);
			}
		}
you can't pick it up once the timer has been started...but it seems that m_Timer always remains not null once it's been double clicked. I suppose that you could retarget something. But the timer issue needs to be fixed before you should worry about anything else.

Last edited by Thagoras; 02-10-2010 at 06:16 PM.
Thagoras is offline   Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off



Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0 RC5