I am using Dupre's Tents, and have a question about the Addons and constructors. In the code below, is there a way to add x to the u constructor? It is not possible to do so before the variable x is added. Is there another way? I have set up TentCampFirePit with a TentDestroyer variable, but need a way to connect the two, so that I can have TentCapFirePit call methods in TentDestroyer (partially to refresh a timer I have added). Any help greatly appreciated.


Code:
						TentWalls v = new TentWalls();
						v.Location = from.Location; 
						v.Map = from.Map; 

						TentRoof w = new TentRoof(); 
						w.Location = from.Location; 
						w.Map = from.Map; 

						TentFloor y = new TentFloor(); 
						y.Location = from.Location; 
						y.Map = from.Map; 

						TentTrim z = new TentTrim(); 
						z.Location = from.Location; 
						z.Map = from.Map;
				
						//TentVerifier tentverifier = new TentVerifier();
						//from.AddToBackpack (tentverifier);
						
						SecureTent chest = new SecureTent((PlayerMobile)from);
						chest.Location = new Point3D( from.X -1, from.Y-1, from.Z ); 
						chest.Map = from.Map; 

						
						TentCampFirePit u = new TentCampFirePit( null );
						u.Location = new Point3D( from.X+6, from.Y, from.Z );  
						u.Map = from.Map; 

						TentDestroyer x = new TentDestroyer(v,w,y,z,(PlayerMobile)from, (SecureTent) chest, u ); 
						x.Location = new Point3D( from.X-1, from.Y, from.Z );  
						x.Map = from.Map;
 
so for this

TentCampFirePit u = new TentCampFirePit( null );
u.Location = new Point3D( from.X+6, from.Y, from.Z );
u.Map = from.Map;

null is a placeholder for x?

If I understand what you mean, you could add this to the constructor of TentCampFirePit
Timer.DelayCall(TimeSpan.FromSeconds(1.0), TentDestroyer.Method , contructor for method if you need one);

sometimes using TimeSpan.Zero works better and looks better but it depends on what you're doing with it.

if you need to do multiple method parameters

[ posted by @Voxpire Stone delay help! ]
.NET 2.0
Code:
Timer.DelayCall(TimeSpan.FromSeconds(10), delegate()
{
    if (from != null && !from.Deleted && from.Blessed && from.AccessLevel == AccessLevel.Player)
    {
        from.Blessed = false;
        from.YellowHealthbar = false;
        from.Delta(MobileDelta.Noto);
    }
});

Note the 'delegate', this allows you to define an anonymous function in placement of declaring an instance member in the class to handle it.

Delegates can also be replaced with Lambda expressions if using .NET 4.0:
Code:
Timer.DelayCall(TimeSpan.FromSeconds(10), () =>
{
    if (from != null && !from.Deleted && from.Blessed && from.AccessLevel == AccessLevel.Player)
    {
        from.Blessed = false;
        from.YellowHealthbar = false;
        from.Delta(MobileDelta.Noto);
    }
});
 
Thanks for the prompt response and explanation! Yes, null is a placeholder for x. I am not quite sure I understand.

Basically, the code I posted is from the TentDeed. It places those items when d-clicked. Originally, they were permanent until the TentDestroyer (bedroll graphic) was d-clicked again, but I added a timer to it. Now all of the items/addons are deleted either via using the TentDestroyer or when the timer runs out.

The TentCampFirePit works similarly to a normal Campfire. It allows the camp to be secured for logout, and the radius of the fire's lightsource dimishes as the TentCampFirePit's timer progresses. I made it so that d-clicking the TentCampFirePit and targeting 10 logs or boards resets the timer, and thus the lightsource radius.

I compromised a bit since posting this thread, and added a gump that is triggered when the TentDestroyer is d-clicked, and gives a choice to either Refresh the campsite or Pack Up the tent. There are some other issues I need to iron out, but it works.

My ultimate goal was something a bit more organic, namely to have the TentDestroyer timer refresh when the TentCampFirePit's timer is reset via the logs/boards via the RefershTent method. The issue, as you noted is that the TentCampFirePit is not connected to an instance of TentDestroyer. Unless I misunderstand (very possible, bordering on highly likely) this needs to happen to the instance of TentDestroyer. Can I use a delegate here?

Now that I think about it, perhaps it would be easier to call TentCampFirePit from TentDestroyer.

I will post the scripts i am working with. Note, I am (obviously..:) not any of the authors affiliated with these scripts. The times are in seconds for testing purposes.

TentDestroyer
Code:
//==============================================//
// Created by Dupre					//
// Thanks to:						//
// Zippy							//
// Ike							//
// Ignacio							//
//								//
// For putting up with a 'tard like me :)		//
//								//
//==============================================//
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Gumps;
using System.Collections;

namespace Server.Items
{
	public class TentDestroyer : BaseAddon
	{


		[CommandProperty( AccessLevel.GameMaster )]
		public DateTime DeleteTime{ get{ return m_DeleteTime; } }	

		public int TentStatus
		{
			get
			{
				DateTime start = DeleteTime - TimeSpan.FromSeconds( 140.0 );;

				if ( DateTime.Now - start < TimeSpan.FromSeconds( 1.0 ) )
					return 1043010; // This structure is like new.

				if ( DateTime.Now - start < TimeSpan.FromSeconds( 20.0 ) )
					return 1043011; // This structure is slightly worn.

				if ( DateTime.Now - start < TimeSpan.FromSeconds( 40.0 ) )
					return 1043012; // This structure is somewhat worn.

				if ( DateTime.Now - start < TimeSpan.FromSeconds( 60.0 ) )
					return 1043013; // This structure is fairly worn.

				if ( DateTime.Now - start < TimeSpan.FromSeconds( 120.0 ) )
					return 1043014; // This structure is greatly worn.

				return 1043015; // This structure is in danger of collapsing.
			}
		}
		
		[Constructable]
		public TentDestroyer( TentWalls tentwalls,TentRoof tentroof,TentFloor tentfloor,TentTrim tenttrim, PlayerMobile player, SecureTent chest) :
		this ( tentwalls, tentroof, tentfloor, tenttrim, player, chest, null )
		{
		}
	
		[Constructable]
		public TentDestroyer( TentWalls tentwalls,TentRoof tentroof,TentFloor tentfloor,TentTrim tenttrim, PlayerMobile player, SecureTent chest, TentCampFirePit tentcampfirepit)
		{
			Name = "A tent carrying bag";
			m_Player = player;
			m_TentRoof = tentroof;
			m_TentWalls = tentwalls;
			m_TentFloor = tentfloor;
			m_TentTrim = tenttrim;
			m_Chest = chest;
			m_TentCampFirePit = tentcampfirepit;
			
			m_DeleteTime = DateTime.Now + TimeSpan.FromSeconds( 140.0 );
			
			m_Timer = new DeleteTimer( this, m_DeleteTime );
			m_Timer.Start();
			
			//m_TentCampFirePit = new TentCampFirePit( this );
			//Point3D relLoc = new Point3D( m_TentCampFirePit.X + this.X, this.Y, this.Z );
			//m_TentCampFirePit.MoveToWorld( relLoc, this.Map );


			
			this.ItemID = 2648; // 2645;
			this.Visible = true;
			Hue = 1801; // 1072;
			
			
			
		}
		private TentRoof m_TentRoof;
		private TentWalls m_TentWalls;
		private TentTrim m_TentTrim;
		private TentFloor m_TentFloor;
		private PlayerMobile m_Player;
		private SecureTent m_Chest;
		private TentCampFirePit m_TentCampFirePit;
		private DateTime m_DeleteTime;
		private Timer m_Timer;

		public PlayerMobile Player
		{
			get{ return m_Player; }
		}
		
		public override void OnDoubleClick( Mobile from )
		{

			
			from.SendGump (new TentRepackGump(this,from));
					
		}
		
		public override void OnSingleClick( Mobile from )
		{
			LabelTo( from, this.TentStatus );
			
		}

		public override void OnDelete()
		{
			if ( m_TentFloor != null ) // m_TentFloor
			{
				m_TentFloor.Delete();
			}
			else
			{
				Console.WriteLine("m_TentFloor was null");
			}
			
			if ( m_TentTrim != null ) // m_TentTrim
			{
				m_TentTrim.Delete();
			}
			else
			{
				Console.WriteLine("m_TentTrim was null");
			}
			
			if ( m_TentWalls != null ) // m_TentWalls
			{
				m_TentWalls.Delete();
			}
			else
			{
				Console.WriteLine("m_TentWalls was null");
			}
			
			if ( m_TentRoof != null )  // m_TentRoof
			{
				m_TentRoof.Delete();
			}
			else
			{
				Console.WriteLine("m_TentRoof was null");
			}
			
			if ( m_Chest != null ) // m_Chest
			{

				
				m_Chest.Delete();
				
						
			}
			else
			{
				Console.WriteLine("m_Chest was null");
			}
			
			if ( m_TentCampFirePit != null ) // m_TentVerifier
			{
				m_TentCampFirePit.Delete();
				
			}
			else
			{
			//	Console.WriteLine("m_TentVerifier was null - this is okay to see if you had tent verifiers before. Comment this line out after all are cleared.");
			}		
			
		}

		public void RefreshTent()
		{
			m_Timer.Stop();
			m_DeleteTime = DateTime.Now + TimeSpan.FromSeconds( 140.0 );
			m_Timer = new DeleteTimer( this, m_DeleteTime );
			m_Timer.Start();	

	
		}

		public void RepackTent( Mobile from )
		{

			if (m_Player==from )
			{
				if ( m_Chest != null && m_Chest.Items.Count > 0 )
				{
					from.SendMessage( "You must remove the items from the travel backpack before packing up your tent." );
				}
				else
				{
					
					
					this.Delete();
					from.AddToBackpack( new TentDeed() );
					from.SendMessage( "You pack up your tent and place it in your backpack." );

				}
			}
			else
			{
				from.SendMessage( "You don't appear to own this tent." );
			}


		}


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

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.Write( (int) 1 ); // version
			writer.Write( m_TentTrim );
			writer.Write( m_TentFloor );
			writer.Write( m_TentWalls );
			writer.Write( m_TentRoof );
			writer.Write( m_Player );
			writer.Write( m_Chest );
			writer.Write( m_TentCampFirePit );
			writer.WriteDeltaTime( m_DeleteTime );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			int version = reader.ReadInt();

			m_TentTrim = (TentTrim)reader.ReadItem();
			m_TentFloor = (TentFloor)reader.ReadItem();
			m_TentWalls = (TentWalls)reader.ReadItem();
			m_TentRoof = (TentRoof)reader.ReadItem();
			m_Player = (PlayerMobile)reader.ReadMobile();
			m_Chest = (SecureTent)reader.ReadItem();
			m_TentCampFirePit = (TentCampFirePit)reader.ReadItem();
			m_DeleteTime = reader.ReadDeltaTime();
			
		}

		private class DeleteTimer : Timer
		{
			private Item m_Item;

			public DeleteTimer( Item item, DateTime time ) : base( time - DateTime.Now )
			{
				m_Item = item;
				Priority = TimerPriority.OneSecond;
			}

			protected override void OnTick()
			{
						
				
				TentDeed tentd = new TentDeed();				
				tentd.Location = new Point3D( m_Item.X, m_Item.Y, m_Item.Z );
				tentd.Map = m_Item.Map;
				m_Item.Delete();

			}
		}		
		
	}
}

TendCampFirePit
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Network;
using Server.Mobiles;
using Server.Targeting;

namespace Server.Items
{
	public enum TentCampFirePitStatus
	{
		Burning,
		Extinguishing,
		Off,
		Low
	}

	public class TentCampFirePit : Item
	{

		private TentDestroyer m_TentDestroyer;		

		public static readonly int SecureRange = 7;

		private static readonly Hashtable m_Table = new Hashtable();

		public static TentCampFirePitEntry GetEntry( Mobile player )
		{
			return (TentCampFirePitEntry) m_Table[player];
		}

		public static void RemoveEntry( TentCampFirePitEntry entry )
		{
			m_Table.Remove( entry.Player );
			entry.Fire.m_Entries.Remove( entry );
		}

		private Timer m_Timer;
		private DateTime m_Created;

		private ArrayList m_Entries;

		public TentCampFirePit( TentDestroyer tentdestroyer) : base( 0x0FAC )
		{

			m_TentDestroyer = tentdestroyer;
			Movable = false;
			Light = LightType.Circle300;

			m_Entries = new ArrayList();
			Status = TentCampFirePitStatus.Burning;
	
			m_Created = DateTime.Now;
			m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 1.0 ), new TimerCallback( OnTick ) );
		}

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

		[CommandProperty( AccessLevel.GameMaster )]
		public DateTime Created
		{
			get{ return m_Created; }
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public TentCampFirePitStatus Status
		{
			get
			{
				//switch ( this.ItemID )
				//{
				//	case 0xDE3:
				//		return TentCampFirePitStatus.Burning;

				//	case 0xDE9:
				//		return TentCampFirePitStatus.Extinguishing;

				//	default:
				//		return TentCampFirePitStatus.Off;
				
			DateTime nowtime = DateTime.Now;
			TimeSpan agetime = nowtime - this.Created;

			
			//if ( agetime >= TimeSpan.FromSeconds( 20.0 ) )
			//	return TentCampFirePitStatus.Off;
			if ( agetime >= TimeSpan.FromSeconds( 20.0 ) )
				return TentCampFirePitStatus.Low;
			else if ( agetime >= TimeSpan.FromSeconds( 15.0 ) )
				return TentCampFirePitStatus.Extinguishing;
			else if ( agetime >= TimeSpan.FromSeconds( 0.5 ) )
				return TentCampFirePitStatus.Burning;
			else
				return TentCampFirePitStatus.Low;
			
				
				}
			//}
			set
			{
				if ( this.Status == value )
					return;

				switch ( value )
				{
					case TentCampFirePitStatus.Burning:
						this.Light = LightType.Circle300;
						break;

					case TentCampFirePitStatus.Extinguishing:
						this.Light = LightType.Circle225;
						break;

					case TentCampFirePitStatus.Low:
						this.Light = LightType.Circle150;
						break;

					default:
						
						this.Light = LightType.Circle150;			
						ClearEntries();
						break;
				}
			}
		}

		private void OnTick()
		{
			DateTime now = DateTime.Now;
			TimeSpan age = now - this.Created;

			//if ( age >= TimeSpan.FromMinutes( 10.0 ) )
			//	this.Delete();
			if ( age >= TimeSpan.FromSeconds( 20.0 ) )
				{
				this.Status = TentCampFirePitStatus.Low;
				this.Light = LightType.Circle150;		
				}
			else if ( age >= TimeSpan.FromSeconds( 15.0 ) )
				{
				this.Status = TentCampFirePitStatus.Extinguishing;
				this.Light = LightType.Circle225;	
				}
			else if ( age >= TimeSpan.FromSeconds( 0.5 ) )
				{
				this.Status = TentCampFirePitStatus.Burning;
				this.Light = LightType.Circle300;	
				}	

			if ( this.Status == TentCampFirePitStatus.Off || this.Deleted )
				return;

			foreach ( TentCampFirePitEntry entry in new ArrayList( m_Entries ) )
			{
				if ( !entry.Valid || entry.Player.NetState == null )
				{
					RemoveEntry( entry );
				}
				else if ( !entry.Safe && now - entry.Start >= TimeSpan.FromSeconds( 30.0 ) )
				{
					entry.Safe = true;
					entry.Player.SendLocalizedMessage( 500621 ); // The camp is now secure.
				}
			}

			IPooledEnumerable eable = this.GetClientsInRange( SecureRange );

			foreach ( NetState state in eable )
			{
				PlayerMobile pm = state.Mobile as PlayerMobile;

				if ( pm != null && GetEntry( pm ) == null )
				{
					TentCampFirePitEntry entry = new TentCampFirePitEntry( pm, this );

					m_Table[pm] = entry;
					m_Entries.Add( entry );

					pm.SendLocalizedMessage( 500620 ); // You feel it would take a few moments to secure your camp.
				}
			}

			eable.Free();
		}

		private void ClearEntries()
		{
			if ( m_Entries == null )
				return;

			foreach ( TentCampFirePitEntry entry in new ArrayList( m_Entries ) )
			{
				RemoveEntry( entry );
			}
		}

		public override void OnAfterDelete()
		{
			if ( m_Timer != null )
				m_Timer.Stop();

			ClearEntries();
		}

		public void RekindleFire( )
		{
			m_Created = DateTime.Now;
			
		}
		
		public override void OnDoubleClick( Mobile from )
		{
			from.Target = new InternalTarget( this );
			
		}

		private class InternalTarget : Target
		{
			private TentCampFirePit m_Item;
		

		public InternalTarget( TentCampFirePit item ) : base( 1, false, TargetFlags.None )
			{
				m_Item = item;
			}

		protected override void OnTarget( Mobile from, object targeted )
			{
				if ( m_Item.Deleted ) return;

				Item targ = targeted as Item;		
					
				
				if ( targ is Log || targ is Board )
				{
					if ( targ.Amount < 10 )
					{
						from.SendMessage("You require at least 10 logs to rekindle this fire.");
					}
					else
					{	
						targ.Amount = targ.Amount -= 10;		
						from.SendMessage("You rekindle the fire.");
						m_Item.RekindleFire();	
					}					

	
				}

				else
					from.SendMessage("You can only rekindle the fire with logs or boards.");

			}	
		}

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

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

			writer.Write( m_TentDestroyer );
			writer.WriteDeltaTime( m_Created );
		}

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

			int version = reader.ReadInt();

			m_TentDestroyer = (TentDestroyer)reader.ReadItem();
			m_Created = reader.ReadDeltaTime();

			//if ( m_TentDestroyer == null )
			//	Delete();
			
		}
	}

	public class TentCampFirePitEntry
	{
		private PlayerMobile m_Player;
		private TentCampFirePit m_Fire;
		private DateTime m_Start;
		private bool m_Safe;

		public PlayerMobile Player{ get{ return m_Player; } }
		public TentCampFirePit Fire{ get{ return m_Fire; } }
		public DateTime Start{ get{ return m_Start; } }

		public bool Valid
		{
			get{ return !Fire.Deleted && Fire.Status != TentCampFirePitStatus.Off && Player.Map == Fire.Map && Player.InRange( Fire, TentCampFirePit.SecureRange ); }
		}

		public bool Safe
		{
			get{ return Valid && m_Safe; }
			set{ m_Safe = value; }
		}

		public TentCampFirePitEntry( PlayerMobile player, TentCampFirePit fire )
		{
			m_Player = player;
			m_Fire = fire;
			m_Start = DateTime.Now;
			m_Safe = false;
		}
	}
}
[doublepost=1503523593][/doublepost]Also, I had a question about Deserialization. When I restart the server the timer seems to continue, and the Status changes, but the TentDestroyer never deletes. I have tried adding Delete(); in a few places, and also calling the RefreshTent method, but then it requires that all TentDestroyers currently in the world be deleted each time the server is restarted. It also causes the server to crash when you try to refresh the tent using the TentDestroyer after a server restart.

Any suggestions?
 
Last edited:
Back