Resource icon

David's Conversational Townsperson 1.1a

No permission to download

Zavreyon

Gold Donator
Apr 5, 2015
97
32
31
mtindell submitted a new resource:

David's Conversational Townsperson - Customizable Talking NPCs

This was written for RunUO 2.0 by David, some of you may remember him from RunUO forums, he was a moderator there and genuinely helpful guy. He wrote a lot of the early tutorials also. I know this has been uploaded to some of the RunUO archive sites, but someone asked about it in another thread here at ServUO so I thought I would post it here as well so that when people search here they can find it.

I have tested the script with ServUO 55.1 on Mono 5.18.0.268 and it works without any...
Read more about this resource...
 

Milva

Admin
Moderator
Mar 3, 2013
4,399
537
Donate
Donate money to this user
Agree he was very helpful :) I still have his guard spawner- mob would drop a key
 

Arcadius

Gold Donator
Oct 22, 2016
205
2
39
Crash and burn on this script.

Code:
Server Crash Report
===================

ServUO Version 0.5, Build 6472.26597
Operating System: Microsoft Windows NT 6.2.9200.0
.NET Framework: 4.0.30319.42000
Time: 3/16/2019 4:02:59 AM
Mobiles: 13929
Items: 882518
Exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileNotFoundException: Could not find file 'C:\Users\ted_g\Desktop\ServUO-master reboot\ServUO-master\shardbackup.3-14-2019\Data\SpeechRules.xml'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
   at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials, IWebProxy proxy, RequestCachePolicy cachePolicy)
   at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
   at System.Xml.XmlTextReaderImpl.OpenUrlDelegate(Object xmlResolver)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.CompressedStack.Run(CompressedStack compressedStack, ContextCallback callback, Object state)
   at System.Xml.XmlTextReaderImpl.OpenUrl()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlReader.MoveToContent()
   at System.Data.DataSet.ReadXml(XmlReader reader, XmlReadMode mode, Boolean denyResolving)
   at System.Data.DataSet.ReadXml(String fileName, XmlReadMode mode)
   at Server.Mobiles.Data.SpeechData.LoadData()
   at Server.Mobiles.Data.SpeechData.Initialize()
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Server.ScriptCompiler.Invoke(String method) in c:\Users\Ted Gress\Desktop\ServUO-master reboot\ServUO-master\ServUO-master\Server\ScriptCompiler.cs:line 667
   at Server.Core.Main(String[] args) in c:\Users\Ted Gress\Desktop\ServUO-master reboot\ServUO-master\ServUO-master\Server\Main.cs:line 558

Clients:
- Count: 0
 

PyrO

Well-Known Member
Jan 27, 2015
1,211
114
Well your C:\Users\ted_g\Desktop\ServUO-master reboot\ServUO-master\shardbackup.3-14-2019\Data\SpeechRules.xml file doesnt exist
 

Arcadius

Gold Donator
Oct 22, 2016
205
2
39
Come on PyrO I know that much. The question is what is the functionality of that file and why is it missing from the .rar?
 

Zavreyon

Gold Donator
Apr 5, 2015
97
32
31
readme said:
With version 1.1 the starter speech database is intentionally mis-named to avoid overwriting any current databases. To use the starter database look in the RunUO\Data folder and rename the file “Rename.SpeechRules.XML” to “SpeechRules.XML.”
 

PyrO

Well-Known Member
Jan 27, 2015
1,211
114
or use the empty one and add the rules / speeches with the edtior. Only now looked at the package.
 

Macil

Well-Known Member
Nov 6, 2013
56
3
33
Brilliant! Would it be possible to assign different rules to different unique NPCs so not all NPCs utilize the same rules? For instance, I want a specific NPC to provide specific banter in a tavern when engaging with players, providing them interesting information regarding secrets around the town he is locally found in. But I don't want EVERY NPC Townsperson I create to have access to the same information via their speech.
 

Zavreyon

Gold Donator
Apr 5, 2015
97
32
31
I have not dug that deep into it, but I believe Djeryv's Odyssey server has NPCs that appear to do what you are asking. You will see 2 of them together, and they will gossip about objects and locations that can provide hints. Believe they are in the barfly script, but how easy it would be to unmarry it from the rest of the systems I do not know, haven't tried yet.

There is a much more involved script than both of these however called BaseConvo that utilizes the conversation fragments from the T2A Demo. Basically The server loads those files, which are quite extensive, with various responses based on player notoriety, gender, profession AND the NPCsjob, location and "attitude" for a myriad of questions/keywords. You have to modify a line in each vendor type to have them respond, which is nice because you can exclude some npcs vendors from the system (like bankers in crowded areas) the fragments have keywords for all the locations, major characters from the ultima series, job descriptions, and even some political responses based on the british/blackthorn rivalry. It can be found in the rebirth release, and you will need to make many changes to get it working with ServUO. I had much of it working earlier, but haven't looked at it in quite a while. Custom responses were also possible and a template was included. The fragments themselves also have notes from designer Raph Koster and others that make it an interesting thing to look at in a historial context regardless.
 
Last edited:
  • Like
Reactions: Macil

Macil

Well-Known Member
Nov 6, 2013
56
3
33
Well, I was trying to work backwards from the Townsperson script itself and see how it reads the SpeechRules.xml file in general. Not knowing how to do any C# is really throwing a wrench in that idea for me lol. I can see some lines that reference the SpeechHandler (line 905 to be exact in Townsperson.cs)

But this is all Chinese to me. I have no idea what any of it means and when I open the SpeechDataHandler.cs file, I see this:
Code:
        public static void LoadData()
        {
            SpeechData.blockRequests = true;

            SpeechData.dsSpeechRules.Reset();
            SpeechData.dsSpeechRules.ReadXml("Data\\SpeechRules.xml", XmlReadMode.ReadSchema);

            SpeechData.blockRequests = false;
        }
Townsperson.cs:
Code:
public virtual void SpeechHandler(SpeechResponse sr)
        {
            string m_name = (sr.Speaker.NameMod == null ? sr.Speaker.Name : sr.Speaker.NameMod);
            string m_response = String.Format(sr.Response, this.Name, m_name, this.Region);

            if (!isEmpty(sr.Response))
                Say(m_response);

            if (sr.Animation > 0)
                Animate(sr.Animation, 5, 1, true, false, 0);

            if (sr.Reaction > 0)
            {
                ReactionCallBackState rcbs = new ReactionCallBackState(sr.Speaker, sr.Reaction);
                Timer.DelayCall(TimeSpan.FromMilliseconds(1800), new TimerStateCallback(ReactionCallBack), rcbs);
            }

            if (Logging == LogLevel.Basic || Logging == LogLevel.Debug)
                TownspersonLogging.WriteLine(this, "Responding to Speech Event: \"{0}\"", m_response);

            if (!isEmpty(sr.Reward))
            {
                if (Logging >= LogLevel.Basic)
                    TownspersonLogging.WriteLine(sr.Speaker, "{0} in {1} Creating {2}", this.Name, this.Region, sr.Reward);

                Type type = SpawnerType.GetType(sr.Reward);

                try
                {
                    object o = Activator.CreateInstance(type);

                    if (o is Item)
                    {
                        Item item = (Item)o;
                        sr.Speaker.AddToBackpack(item);
                    }
                    else if (o is Mobile)
                    {
                        Mobile mob = (Mobile)o;
                        mob.MoveToWorld(this.Location, this.Map);
                    }
                }
                catch
                {
                    TownspersonLogging.WriteLine(sr.Speaker, "{0} Exception Caught creating {1}", this.Name, sr.Reward);
                    sr.Speaker.SendMessage("Exception Caught creating " + sr.Reward); // debugging
                }

            }

            if (!isEmpty(sr.DelObject))
            {
                if (Logging >= LogLevel.Basic)
                    TownspersonLogging.WriteLine(sr.Speaker, "{0} in {1} Deleting {2}", this.Name, this.Region, sr.DelObject);

                Type type = SpawnerType.GetType(sr.DelObject);

                bool ActionTaken = false;

                try
                {
                    for (int i = 0; i < sr.Speaker.Items.Count; ++i)
                    {
                        Item item = (Item)sr.Speaker.Items[i];

                        if (item.GetType() == type)
                        {
                            item.Consume();
                            ActionTaken = true;
                            break;
                        }
                    }
                    if (!ActionTaken)
                    {
                        sr.Speaker.Backpack.ConsumeTotal(type, 1, true);
                    }
                }
                catch
                {
                    TownspersonLogging.WriteLine(sr.Speaker, "{0} Exception Caught consuming {1}", this.Name, sr.DelObject);
                    sr.Speaker.SendMessage("Exception Caught consuming " + sr.DelObject); // debugging
                }
            }
        }
        #endregion
Now, if only I can add some if's or something to this where it says something like: if Tavernperson.cs use this file "SpeechRulesTavernPerson.xml" instead. But I don't know how to do that. lol

Any ideas?