RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Time System

Morxeton

Sorceror
Rhexis said:
For example I tried:
[TS SET TIMEFORMAT The time is $hr-ap$:$mn-2$$ap$ on the $da$$nth$ of the $mo$$nth$ month of year $yr$. The moon is $mp$.
and the client cuts off "onth of year $yr$. The moon is $mp$."
I just realized that I forgot to have $nth$ use day or month. Right now $nth$ is just based off of the day. I will update and release a quick version fix shortly.
 

Morxeton

Sorceror
v1.1.11 released:
  • Fixed the $nth$ format variable to now be either based off of day or month. $nth$ can no longer be used. It is now $nth-d$ for day and $nth-m$ for month.
 

Greystar

Wanderer
Ack! Too many updates in to short of time.

*dies*

Thanks though I was really trying to find a way to do alot of this for a long time, but I was also working on my Killable Guards and various other modifications/tweaks at the same time and I couldn't focus on this idea.
 

RANCID77

Wanderer
ACK YOU STOLE MY SYSTEM YOU JERK!!!!....

LoL j/k bro... Just not used to a thread goin this long without someone complaining it was stolen..

Anyways.. Back on subject.. Great job with the updates man.. i still got the first release on my total kickass test server that only has one npc spawned.. Yeah its best server in world.. dont be jealous.. Anywho.. Keep em coming bud.. at this rate the next update should be in what? about 10 mins... Cant wait to see it.. :)
 

Dian

Sorceror
ERRORS ERRORS !!! !!!

OMG THE ERRORS!!!


haha, na.. smooth as expected from a fine piece of work :)


Wonderfull update, Morxeton.. now my wrist watch is Sync'd.. I can let the world start turning again !
 

Dian

Sorceror
wooops, guess I spoke too soon on the error joke..

In game, I decided to test out a few commands.. I ran the command;

[ts set ClockTimeFormat with no variable.. I guess I was hoping it would give me the list of default preset formats.. cause I was too lazy to look at the script.. and shard crashed.. I guess from a null reference.
may happen too, (i will try) with other [ts set commands without the variable to go along with it.

Heres the report, in debug:

Code:
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at Server.TimeSystem.System.SetVariable(String variableName, String variableValue, Boolean restart, Boolean append) in c:\..\..\..\..\Time System.cs:line 2977
   at Server.TimeSystem.System.SetVariable(Mobile mobile, CommandEventArgs e, Boolean append) in c:\..\..\..\Time System.cs:line 1681
   at Server.TimeSystem.System.TimeSystem_OnCommand(CommandEventArgs e) in c:\..\..\..\Time System.cs:line 696
   at Server.Commands.Handle(Mobile from, String text)
   at Server.Mobile.DoSpeech(String text, Int32[] keywords, MessageType type, Int32 hue)
   at Server.Mobiles.PlayerMobile.DoSpeech(String text, Int32[] keywords, MessageType type, Int32 hue) in c:\..\..\..\PlayerMobile.cs:line 1967
   at Server.Network.PacketHandlers.UnicodeSpeech(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns)
   at Server.Network.MessagePump.Slice()
   at Server.Core.Main(String[] args)
 

Morxeton

Sorceror
Dian said:
wooops, guess I spoke too soon on the error joke..

In game, I decided to test out a few commands.. I ran the command;

[ts set ClockTimeFormat with no variable.. I guess I was hoping it would give me the list of default preset formats.. cause I was too lazy to look at the script.. and shard crashed.. I guess from a null reference.
may happen too, (i will try) with other [ts set commands without the variable to go along with it.

Heres the report, in debug:

Code:
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at Server.TimeSystem.System.SetVariable(String variableName, String variableValue, Boolean restart, Boolean append) in c:\..\..\..\..\Time System.cs:line 2977
   at Server.TimeSystem.System.SetVariable(Mobile mobile, CommandEventArgs e, Boolean append) in c:\..\..\..\Time System.cs:line 1681
   at Server.TimeSystem.System.TimeSystem_OnCommand(CommandEventArgs e) in c:\..\..\..\Time System.cs:line 696
   at Server.Commands.Handle(Mobile from, String text)
   at Server.Mobile.DoSpeech(String text, Int32[] keywords, MessageType type, Int32 hue)
   at Server.Mobiles.PlayerMobile.DoSpeech(String text, Int32[] keywords, MessageType type, Int32 hue) in c:\..\..\..\PlayerMobile.cs:line 1967
   at Server.Network.PacketHandlers.UnicodeSpeech(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns)
   at Server.Network.MessagePump.Slice()
   at Server.Core.Main(String[] args)
Problem fixed. Thanks for reporting the bug! I am uploading the new version now.
 

Morxeton

Sorceror
v1.1.12 released:
  • Fixed a bug in setting the TIMEFORMAT or CLOCKTIMEFORMAT without specifying a value would result in a null reference exception.
  • Added a [TS VERSION command to display the version of the time system.
 

Dian

Sorceror
I do have one issue Id like to let you know about..

I have added a few LampPost's in an area. actually, tested it our with all 3 of them, in the default RunUO set.. LampPost1, 2 and 3.

Well.. I ran [ts RepopLightsList and it generated the new list. showed on console the right number of lights I added, compared to previous list. It was dark, and the lamp posts, after a few seconds lit up, one after the other.. but, then one would shut off.. then relight.. and another would do it too.. kind of like, switch on for a few seconds, then off.. then on again.. repeting that.

a couple remained on throughout the period of night.. but a few.. on/off like that.

It seemed to make no difference what LampPost I placed, either.

I tried stoping, restarting and all that as well.. same results.
 

Morxeton

Sorceror
Dian said:
I do have one issue Id like to let you know about..

I have added a few LampPost's in an area. actually, tested it our with all 3 of them, in the default RunUO set.. LampPost1, 2 and 3.

Well.. I ran [ts RepopLightsList and it generated the new list. showed on console the right number of lights I added, compared to previous list. It was dark, and the lamp posts, after a few seconds lit up, one after the other.. but, then one would shut off.. then relight.. and another would do it too.. kind of like, switch on for a few seconds, then off.. then on again.. repeting that.

a couple remained on throughout the period of night.. but a few.. on/off like that.

It seemed to make no difference what LampPost I placed, either.

I tried stoping, restarting and all that as well.. same results.
This happens in the Darkest Hour due to the amount of "evil" in the air. It's a feature that can be disabled by typing [TS SET RANDOMLIGHTOUTAGE false.
 

Dian

Sorceror
Doh, thats right.. I remember reading that now.. sorry man, that actually a really cool feature ;)

Can that be set within certain regions, btw? or not currently..
It would be great to use this in a couple of my ruined cities on my custom map, but not throughout the entire world.. is why I ask.
 

Morxeton

Sorceror
Dian said:
Doh, thats right.. I remember reading that now.. sorry man, that actually a really cool feature ;)

Can that be set within certain regions, btw? or not currently..
It would be great to use this in a couple of my ruined cities on my custom map, but not throughout the entire world.. is why I ask.
Great suggestion. I will look into this :)
 

Dian

Sorceror
Actually.. an even simpler idea would be to just add another group of lights.. or modified BaseLight, that has a bool for using the evil attribute. If the LampPost UseEvil = true; it will flicker.. otherwise, it will act normal. that would be the better way, in fact.. imho.. so you could setup a specific building, for that matter.. no region mods.
 

Dian

Sorceror
Here we go.. seems to work :) what do you think?

All changes are in bold
Time System.cs Mod @ PerformRandomLightOutage method
Code:
private static void PerformRandomLightOutage( BaseLight baseLight )
        {
            int lowNumber = new Random(m_RandomSeed).Next(1, (100 - m_LightOutageChancePerTick) + 1);
            int highNumber = lowNumber + m_LightOutageChancePerTick;

            int randomChance = new Random(m_RandomSeed).Next(1, 101);

            if (randomChance >= lowNumber && randomChance <= highNumber)
            {
		[b]if( baseLight.UseEvil )
		{[/b]
			if (baseLight.Burning)
			{
			        baseLight.Douse();
			}
			else
			{
				baseLight.Ignite();
			}
		[b]}[/b]
            }
        }


BaseLight.cs Mod (serialized properly for a clean install/reboot)
Code:
using System;
using Server;

namespace Server.Items
{
	public abstract class BaseLight : Item
	{
		[b]private bool m_UseEvil;[/b]
		private Timer m_Timer;
		private DateTime m_End;
		private bool m_BurntOut = false;
		private bool m_Burning = false;
		private bool m_Protected = false;
		private TimeSpan m_Duration = TimeSpan.Zero;

		public abstract int LitItemID{ get; }
		
		public virtual int UnlitItemID{ get { return 0; } }
		public virtual int BurntOutItemID{ get { return 0; } }
		
		public virtual int LitSound{ get { return 0x47; } }
		public virtual int UnlitSound{ get { return 0x3be; } }
		public virtual int BurntOutSound{ get { return 0x4b8; } }

		public static readonly bool Burnout = false;

		[b][CommandProperty( AccessLevel.GameMaster )]
		public bool UseEvil
		{
			get{ return m_UseEvil; }
			set{ m_UseEvil = value; }
		}[/b]
			

		[CommandProperty( AccessLevel.GameMaster )]
		public bool Burning
		{
			get { return m_Burning; }
			set
			{
				if ( m_Burning != value )
				{
					m_Burning = true;
					DoTimer( m_Duration );
				}
			}
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public bool BurntOut
		{
			get { return m_BurntOut; }
			set { m_BurntOut = value; }
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public bool Protected
		{
			get { return m_Protected; }
			set { m_Protected = value; }
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public TimeSpan Duration
		{
			get
			{
				if ( m_Duration != TimeSpan.Zero && m_Burning )
				{
					return m_End - DateTime.Now;
				}
				else
					return m_Duration;
			}

			set { m_Duration = value; }
		}

		[Constructable]
		public BaseLight( int itemID ) : base( itemID )
		{
		}

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

		public virtual void PlayLitSound()
		{
			if ( LitSound != 0 )
			{
				Point3D loc = GetWorldLocation();
				Effects.PlaySound( loc, Map, LitSound );
			}					
		}
		
		public virtual void PlayUnlitSound()
		{
			int sound = UnlitSound;

			if ( m_BurntOut && BurntOutSound != 0 )
				sound = BurntOutSound;

			
			if ( sound != 0 )
			{
				Point3D loc = GetWorldLocation();
				Effects.PlaySound( loc, Map, sound );
			}					
		}

		public virtual void Ignite()
		{
			if ( !m_BurntOut )
			{
				PlayLitSound();

				m_Burning = true;
				ItemID = LitItemID;
				DoTimer( m_Duration );
			}
		}

		public virtual void Douse()
		{
			m_Burning = false;
			
			if ( m_BurntOut && BurntOutItemID != 0 )
				ItemID = BurntOutItemID;
			else
				ItemID = UnlitItemID;

			if ( m_BurntOut )
				m_Duration = TimeSpan.Zero;
			else if ( m_Duration != TimeSpan.Zero )
				m_Duration = m_End - DateTime.Now;

			if ( m_Timer != null )
				m_Timer.Stop();

			PlayUnlitSound();
		}

		public virtual void Burn()
		{
			m_BurntOut = true;
			Douse();
		}

		private void DoTimer( TimeSpan delay )
		{
			m_Duration = delay;
			
			if ( m_Timer != null )
				m_Timer.Stop();

			if ( delay == TimeSpan.Zero )
				return;

			m_End = DateTime.Now + delay;

			m_Timer = new InternalTimer( this, delay );
			m_Timer.Start();
		}

		public override void OnDoubleClick( Mobile from )
		{
			if ( m_BurntOut )
				return;

			if ( m_Protected && from.AccessLevel == AccessLevel.Player )
				return;

			if ( !from.InRange( this.GetWorldLocation(), 2 ) )
				return;

			if ( m_Burning )
			{
				if ( UnlitItemID != 0 )
					Douse();
			}
			else
			{
				Ignite();
			}
		}

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

			writer.Write( (int) [b]1[/b] );
			[b]writer.Write( m_UseEvil );[/b]
			writer.Write( m_BurntOut );
			writer.Write( m_Burning );
			writer.Write( m_Duration );
			writer.Write( m_Protected );

			if ( m_Burning && m_Duration != TimeSpan.Zero )
				writer.WriteDeltaTime( m_End );
		}

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

			int version = reader.ReadInt();

			switch ( version )
			{
				[b]case 1:
				{
					m_UseEvil = reader.ReadBool();
					goto case 0;
				}[/b]
				case 0:
				{
					m_BurntOut = reader.ReadBool();
					m_Burning = reader.ReadBool();
					m_Duration = reader.ReadTimeSpan();
					m_Protected = reader.ReadBool();

					if ( m_Burning && m_Duration != TimeSpan.Zero )
						DoTimer( reader.ReadDeltaTime() - DateTime.Now );

					break;
				}
			}
		}

		private class InternalTimer : Timer
		{
			private BaseLight m_Light;

			public InternalTimer( BaseLight light, TimeSpan delay ) : base( delay )
			{
				m_Light = light;
				Priority = TimerPriority.FiveSeconds;
			}

			protected override void OnTick()
			{
				if ( m_Light != null && !m_Light.Deleted )
					m_Light.Burn();
			}
		}
	}
}

*Edited; posted wrong PerformRandomLightOutage method for change.
 

Morxeton

Sorceror
@ Dian
Nice mod. I want to make this an optional edit to BaseLight, so I will be working on it. Thanks for the idea :)
 
First off this system rocks. Second I have a few suggestions of my own :) I think the idea about making it noticeably darker during rain and snow is an excellent idea. I also think that if you tie this in with the weather it would enhance it alot.

If you were to create seasons for the game it would be extremely nice. You may want to make the weather a separate system that ties in with the time system. Seasons are something that britannia never really had though (it should have) I think the seasons might be a little tough though because certain areas like ice isle will always have snow and you cant exactly have it snowing in the desert but if you had a pattern set up it would rock.

I also thought it may be fun to sort of override nightsight during darkest hour or even cause it to dim during night like at champ spawns and then make it override nightsight for darkest hour. This would probably be best as some type of option you can simply toggle for users who are not very good with script edits. anyhow just an idea. You might also want to send a message to players something like " your nightsight begins to falter slightly as the darkness grows..." for the first light level drop and then another for darkest hour something like "your nightsight is no longer strong enough to cut through the darkness..."

I like the lamp posts how they turn on and off and stuff but maybe rather than have them the way they are go by region and have it send a system message to all players within the region saying "you feel a cool wind howl perhaps evil is about us..." and then the lamps for that region would go out. I just think it would add that certain level of detail and set the right mood to make it draw players in a little more.

Just imagine sitting at brit bank or wherever your players gather and during darkest hour your nightsight is no longer strong enough to cut through the darkness just then you receive the message telling you a cool wind howls perhaps evil is about us and all the lights around town go out. yeah its pretty cool :)
 
Top