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!

Making Vendor live own life...

Galfaroth

Wanderer
Hmmm... I remind something... Orcs and wisps are saying randomily something... even if you don't move ... Maybe this can help us... AND orcs and wisps don't lagg the serv...
 

Galfaroth

Wanderer
That's what I found in both scripts:

public override InhumanSpeech SpeechType{ get{ return InhumanSpeech.Orc; } }
public override InhumanSpeech SpeechType{ get{ return InhumanSpeech.Wisp; } }

Maybe for vendors we need to only make InhumanSpeech (or HumanSpeech) and problem is solved...

No way.. inhumanspeech (scripts/misc) uses OnMovement, OnDeath, OnDamage... that does not give us anything.
 

rsmiller21

Wanderer
However, if you look into InhumanSpeech.cs you will see that everything that is said is compleatly random and wont make any sense. And the trigger is:

Code:
public void OnMovement( Mobile mob, Mobile mover, Point3D oldLocation )

The same method I used before. One question I have for you is, why do you want vendors to talk even if the player isn't there? If a tree falls in the forest and no one is there, does it make a sound?
 

Packer898

Knight
The speech is handled in basecreature.cs.
Code:
		public override bool HandlesOnSpeech( Mobile from )
		{
			InhumanSpeech speechType = this.SpeechType;

			if ( speechType != null && (speechType.Flags & IHSFlags.OnSpeech) != 0 && from.InRange( this, 3 ) )
				return true;

			return ( m_AI != null && m_AI.HandlesOnSpeech( from ) && from.InRange( this, m_iRangePerception ) );
		}

		public override void OnSpeech( SpeechEventArgs e )
		{
			InhumanSpeech speechType = this.SpeechType;

			if ( speechType != null && speechType.OnSpeech( this, e.Mobile, e.Speech ) )
				e.Handled = true;
			else if ( !e.Handled && m_AI != null && e.Mobile.InRange( this, m_iRangePerception ) )
				m_AI.OnSpeech( e );
		}

I still dont see anyhting different here then what the code above gave you. It still check to make sure something is in range before executing this.
 

Packer898

Knight
rsmiller21 said:
However, if you look into InhumanSpeech.cs you will see that everything that is said is compleatly random and wont make any sense. And the trigger is:

Code:
public void OnMovement( Mobile mob, Mobile mover, Point3D oldLocation )

The same method I used before. One question I have for you is, why do you want vendors to talk even if the player isn't there? If a tree falls in the forest and no one is there, does it make a sound?

LOL I've already made this point to him. He seems to think that Orcs and Wisps just chit-chat back and forth when no one is around. If it was true would be completely useless and a resource hogg. Anyway if that is what he wants to do the only way I can think to do this would be thru the OnThink method.
 

Galfaroth

Wanderer
All right, they don't have to... But imagine this situation: Player is in town... He is tailoring. When tailoring, player isn't moving. Vendors talked only when he get into the shop, then they've just lost their voices... I want to player see that they are talking infinity... So if we can do function like: if npc is in player range 5 trigger talk, everything will be all right... But none know how to do that...
 

rsmiller21

Wanderer
Packer :)

Ok, here we are. This snippet will respond to vendors and players. You can add more sayings by changing the Random number and adding more cases. This has been tested and works. Just throw it into and vendor, not basevendor:

Code:
private DateTime m_NextTalk;
		private string m_name;
		public DateTime NextTalk{ get{ return m_NextTalk; } set{ m_NextTalk = value; } }
   
		public override void OnMovement( Mobile m, Point3D oldLocation )
		{
			if( m is BaseVendor )
			{
				if ( DateTime.Now >= m_NextTalk && InRange( m, 4 ) && InLOS( m ) ) // check if it's time to talk & if mobile in range & in los.
				{
					m_name = m.Name;
					switch ( Utility.Random( 4 )) //the amount of lines you have it to choose from
					{
						case 0: Say(m_name + ", how are you doing today?"); break; //line 1
						case 1: Say("I hate that guy don't you " + m_name + " ?"); break; //line 2
						case 3: Say("I wonder what I am going to have for dinner."); break; //line 3
					};
					m_NextTalk = (DateTime.Now + TimeSpan.FromSeconds( 10 )); //channge the number 10 to the min amount of seconds to wait between talks.
				}
			}

			if( m is PlayerMobile )
			{
				if ( DateTime.Now >= m_NextTalk && InRange( m, 4 ) && InLOS( m ) ) // check if it's time to talk & if mobile in range & in los.
				{
					m_name = m.Name;
					switch ( Utility.Random( 4 )) //the amount of lines you have it to choose from
					{
						case 0: Say(m_name + ", how are you doing today?"); break; //line 1
						case 1: Say("What can I do for you " + m_name + " ?"); break; //line 2
						case 3: Say("I wonder what I am going to have for dinner."); break; //line 3
					};
					m_NextTalk = (DateTime.Now + TimeSpan.FromSeconds( 10 )); //channge the number 10 to the min amount of seconds to wait between talks.
				}
			}
		}

This however, should work the way you want regardless if anyone is present. The only trigger is the movement. This code is tested and works as well:

Code:
private DateTime m_NextTalk;
		private string m_name;
		public DateTime NextTalk{ get{ return m_NextTalk; } set{ m_NextTalk = value; } }
   
		public override void OnMovement( Mobile m, Point3D oldLocation )
		{
			if( m is BaseVendor )
			{
				if ( DateTime.Now >= m_NextTalk && InRange( m, 500 ) ) // check if it's time to talk & if mobile in range & in los.
				{
					m_name = m.Name;
					switch ( Utility.Random( 8 )) //the amount of lines you have it to choose from
					{
						case 0: Say(m_name + ", how are you doing today?"); break; //line 1
						case 1: Say("I hate that guy don't you " + m_name + " ?"); break; //line 2
						case 3: Say("I wonder what I am going to have for dinner."); break; //line 3
					};
					m_NextTalk = (DateTime.Now + TimeSpan.FromSeconds( 10 )); //channge the number 10 to the min amount of seconds to wait between talks.
				}
			}
}
 

Packer898

Knight
I've already stated you could use the OnThink method to check if a playermobile is in ##Range then talk if not then it wont do anything. Regardless this is still gonna be a memory hog because you would check the OnThink of every NPC that uses this everytime it executes regardless if there is a playermobile near or not.

THis wont work youll have to change it to suit your needs but youll get the general idea.
Code:
		public override void OnThink( Mobile from)
		{
			if ( from is PlayerMobile )
			{
				PlayerMobile pm = (PlayerMobile)from;
				
				if ( from.InRange( this, 4 ) )
				{
					//Speech goes here
				}

      		}

      		base.OnThink();
		}
 

Galfaroth

Wanderer
And maybe that is it - vendors move very often, so trigger is always on, when player is close... I have to test it... and Packer done what i wanted... but need to check differences and lag.
 

Packer898

Knight
rsmiller21 said:
Packer :)

Ok, here we are. This snippet will respond to vendors and players. You can add more sayings by changing the Random number and adding more cases. This has been tested and works. Just throw it into and vendor, not basevendor:

Code:
private DateTime m_NextTalk;
		private string m_name;
		public DateTime NextTalk{ get{ return m_NextTalk; } set{ m_NextTalk = value; } }
   
		public override void OnMovement( Mobile m, Point3D oldLocation )
		{
			if( m is BaseVendor )
			{
				if ( DateTime.Now >= m_NextTalk && InRange( m, 4 ) && InLOS( m ) ) // check if it's time to talk & if mobile in range & in los.
				{
					m_name = m.Name;
					switch ( Utility.Random( 4 )) //the amount of lines you have it to choose from
					{
						case 0: Say(m_name + ", how are you doing today?"); break; //line 1
						case 1: Say("I hate that guy don't you " + m_name + " ?"); break; //line 2
						case 3: Say("I wonder what I am going to have for dinner."); break; //line 3
					};
					m_NextTalk = (DateTime.Now + TimeSpan.FromSeconds( 10 )); //channge the number 10 to the min amount of seconds to wait between talks.
				}
			}

			if( m is PlayerMobile )
			{
				if ( DateTime.Now >= m_NextTalk && InRange( m, 4 ) && InLOS( m ) ) // check if it's time to talk & if mobile in range & in los.
				{
					m_name = m.Name;
					switch ( Utility.Random( 4 )) //the amount of lines you have it to choose from
					{
						case 0: Say(m_name + ", how are you doing today?"); break; //line 1
						case 1: Say("What can I do for you " + m_name + " ?"); break; //line 2
						case 3: Say("I wonder what I am going to have for dinner."); break; //line 3
					};
					m_NextTalk = (DateTime.Now + TimeSpan.FromSeconds( 10 )); //channge the number 10 to the min amount of seconds to wait between talks.
				}
			}
		}

This however, should work the way you want regardless if anyone is present. The only trigger is the movement. This code is tested and works as well:

Code:
private DateTime m_NextTalk;
		private string m_name;
		public DateTime NextTalk{ get{ return m_NextTalk; } set{ m_NextTalk = value; } }
   
		public override void OnMovement( Mobile m, Point3D oldLocation )
		{
			if( m is BaseVendor )
			{
				if ( DateTime.Now >= m_NextTalk && InRange( m, 500 ) ) // check if it's time to talk & if mobile in range & in los.
				{
					m_name = m.Name;
					switch ( Utility.Random( 8 )) //the amount of lines you have it to choose from
					{
						case 0: Say(m_name + ", how are you doing today?"); break; //line 1
						case 1: Say("I hate that guy don't you " + m_name + " ?"); break; //line 2
						case 3: Say("I wonder what I am going to have for dinner."); break; //line 3
					};
					m_NextTalk = (DateTime.Now + TimeSpan.FromSeconds( 10 )); //channge the number 10 to the min amount of seconds to wait between talks.
				}
			}
}

Very nice. It should work and do what he needs based on whether a player is around and in-range. Of course if he is still wanting them to talk when no one is around or when the mobile doesnt move then he is still in the same position as before. But this would atleast use very little resources and not lag up the server ;)
 

Axle

Wanderer
Why do you want to waste system resources for a vendor that talks to himself. OnMovement is what you want to trigger the timer, no sense in running a timer when nobody is present to see the results. If you want them to speak at different times, offset their individual speak timer intervals and spread them out.
 

rsmiller21

Wanderer
This works, add two vendors. Space them apart if you want. It relies on at LEAST one other vendor or a player to be within a space of 500 of the vendor. If you ran this in a town full of vendors and players then it would work great. If you ran this in a town full of vendor and NO players this would work. If you had only two vendors in a town spaced 499 spaces apart this would work.
 

rsmiller21

Wanderer
Yeah, Axle, this goes against one of the biggest rules of game programming.
"If the player doesn't see it or hear it does he really care?"
No...
 

siran

Sorceror
Don't all basecreatures (of which are vendors) already use an OnThink method, which is repeatedly executed? Why not just add something like this:

Code:
public override void OnThink ()
{
     if (Utility.RandomBool ())
          // Insert talking logic here
     base.OnThink ();
}
 

Packer898

Knight
siran said:
Don't all basecreatures (of which are vendors) already use an OnThink method, which is repeatedly executed? Why not just add something like this:

Code:
public override void OnThink ()
{
     if (Utility.RandomBool ())
          // Insert talking logic here
     base.OnThink ();
}

Actually no. If you look in basevendor.cs they use OnDragDrop, OnSingleCLick etc...

They dont use the OnThink method probably for all the reasons we stated above.
 

daat99

Moderator
Staff member
Packer898 said:
Actually no. If you look in basevendor.cs they use OnDragDrop, OnSingleCLick etc...

They dont use the OnThink method probably for all the reasons we stated above.
Actually yes.
BaseVendor is a class that is derived from BaseCreature.
BaseCreature use th OnThink method and as a derived class BaseVendor use it as well.

However as far as I know the OnThink method is only called if there's a player in a certain range from the mobile and not always.
 

Packer898

Knight
Ahhh daat99... I didnt think to check its parent class =( Anyway daat whats your input on what to use here? How much would adding the check to OnThink hurt the performance for him?
 
Top