|
||
|
|||||||
| Script Support Get support for modifying RunUO Scripts, or writing your own! |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 (permalink) |
|
Newbie
Join Date: Apr 2007
Posts: 47
|
I have purple potions almost fully functional to the way I want them to run on my RunUO 1.0 server. There is a random countdown timer that functions properly, and a delay timer between each use of a purple potion. My problem is that because of the delay timer between each use, if the target is cancelled, the original potion cannot be selected again because it is still a purple potion. Please understand that my coding skill is basically nill as I just started to learn it when I decided to try out making a server about 3 days ago. Here is a copy of the code:
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 virtual double Delay { get { return 5.0; } }
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.BeginAction( typeof( BaseExplosionPotion ) ) )
{
Timer.DelayCall( TimeSpan.FromSeconds( Delay ), new TimerStateCallback( ReleaseExplosionLock ), from );
}else{
from.SendMessage("You must wait before throwing another explosion potion!" );
return;
}
if ( Core.AOS && (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)
from.Target = new ThrowTarget( this );
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 );
if ( m_Timer == null )
{
from.SendLocalizedMessage( 500236 ); // You should throw it now!
m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 0.75 ), TimeSpan.FromSeconds( 1.0 ), 5, new TimerStateCallback( Detonate_OnTick ), new object[]{ from, Utility.RandomMinMax(3, 4) } );
}
}
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 );
m_Potion.Internalize();
Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), new TimerStateCallback( m_Potion.Reposition_OnTick ), new object[]{ from, p, map } );
}
}
public void Explode( Mobile from, bool direct, Point3D loc, Map map )
{
if ( Deleted )
return;
Delete();
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 || (SpellHelper.ValidIndirectTarget( from, m ) && 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 );
}
}
}
private static void ReleaseExplosionLock( object state )
{
((Mobile)state).EndAction( typeof( BaseExplosionPotion ) );
}
}
}
Last edited by Hyfigh; 09-29-2008 at 09:53 AM. |
|
|
|
|
|
#2 (permalink) |
|
Master of the Internet
|
This is how I did it in my Hybrid-style BaseExplosionPotion.cs:
Code:
if (from is PlayerMobile)
{
PlayerMobile pm = from as PlayerMobile;
if (DateTime.Now - pm.LastExplo < TimeSpan.FromSeconds(5.0))
{
if (m_Timer != null)
{
from.Target = new ThrowTarget(this);
return;
}
pm.LocalOverheadMessage(0, 0x22, false, "You must wait 5 before using another explosion potion.");
return;
}
pm.LastExplo = DateTime.Now;
}
__________________
go fish |
|
|
|
|
|
#3 (permalink) | |
|
Newbie
Join Date: Apr 2007
Posts: 47
|
OK, I changed my script to remove my old timer (I did back it up though) and added yours. I get a bunch of errors though.
Quote:
Now I am running RunUO 1.0, and something tells me that line of coding is for 2.0 as I do not see a namespace of Server.PlayerMobile in namespaces folder. Edit: Added the fact that its 1.0 to the OP. |
|
|
|
|
|
|
#5 (permalink) | |
|
Newbie
Join Date: Apr 2007
Posts: 47
|
Understood.
Now it provides me an Error for LastExplo. Quote:
|
|
|
|
|
|
|
#6 (permalink) |
|
Master of the Internet
|
You weren't supposed to use my whole block of code. I handle my explosion potion lock differently than you do. I highlighted the important bit in red and pasted the rest so you could get an idea of where to place it.
__________________
go fish |
|
|
|
|
|
#7 (permalink) |
|
Newbie
Join Date: Apr 2007
Posts: 47
|
Awesome. I appreciate the help. I found where to put the line. Since I couldn't find the fix through my searches, here's what I did:
Code:
public override void Drink( Mobile from )
{
if ( from.BeginAction( typeof ( BaseExplosionPotion ) ) )
{
Timer.DelayCall( TimeSpan.FromSeconds( Delay ), new TimerStateCallback( ReleaseExplosionLock ), from );
}else{
if ( m_Timer != null )
{
from.Target = new ThrowTarget ( this );
return;
}
from.SendMessage("You must wait before throwing another explosion potion!" );
return;
}
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|