I think I'll take a look at integrating the PV system into the task scheduler, and then I'll most likely think about a couple more random spawning ideas I have - for instance, I have a vague idea how we can spawn random blues and random reds at random using an automated script, but not yet sure if the idea will pan out :)

would you be using the randomencounters engine? its super easy to use and works quite well. if you've played adventures you might have seen a random red or blue pop up randomly in dungeons already.

there are lots of encouters possible with the system.
Post automatically merged:

This autodefend was posted here a while ago, and someone from odyssey had it working ... i'm getting an error on load - any way to fix this? I have no idea what hashset means

1588424965278.png
 

Attachments

  • AutoDefend.cs
    3.2 KB · Views: 7
Last edited:
oh... random encounters is super easy to use... check the xml file in custom/systems/randomencounters and just edit that...

<Region type="Dungeon" name="default">
<Encounter p=".1" distance="10">
<Mobile pick="SpawnHelper"/>
</Encounter>

here there's a 10% chance on tick (tick interval is set in the main .cs file) that the system will spawn a spawnhelper if the player is in a dungeon.
super easy and it's really well explained in the xml file.

you can add those random spawns super easily with this.
 
Ah, that's really cool! :) Thanks for the tip!
As for AutoDefend, to compile it, you'd need to edit Data/Assemblies.cfg and add an extra assembly reference to it:

System.Core.dll

Then it'll compile happily :)
 
It's a part of .NET Framework, so you don't actually need to download it or put it anywhere and stuff, just add a link to it to Assemblies.cfg and it should then work automagically :)
 
made a change to the way powerscrolls are used:

right now if you're at 100 and you use a +25 scroll you can go directly to 125.
I thought that was a little too easy... so now you need to use a +105 before you can upgrade to a +110 before you can upgrade to a +115 .. etc.

so to get to 125 you will need to use all 5 powerscrolls. i'm trying to make end-game harder to reach to make sure the game stays challenging at late levels specifically because my characters do not have a skillcap.

it's an option in myserversettings for those who don't want this :D
Post automatically merged:

and as a note on skillcap - people have usually created new characters because they wanted to do something but didn't have enough room in their skillcap to do it... so they create a new character. I find that system very unnatural and counter-intuitive to how i want my characters to be. If i want my character to be a warrior, i should be able to do whatever i want with my warrior, as long as it fits with my warrior's personality.

It doesn't mean i just have one character - if i want to create an evil thief character, i'll create an evil thief character - it goes against my noble warrior so it wouldn't make sense for my warrior to be a thief as well.. in this manner my characters are based on what i want them to be, not on some artificial skillcap barrier that makes no sense.

It does bring up the issue of balancing however - if you can have a chivalry/bushido/swords/bard character... that's why i've been busy adding very hard late-game content into the game. soloing a champ spawn should really only be possible for a 10xGM character. on OSI shards you needed 3-4 characters to complete a spawn.

I hear there is a titan quest that adds to the skillcap. If someone could point me to the .cs file that defines the reward i'll edit it to add statcap, or a very rare item instead. as far as I know that's the only issue in unlimited skillcap from the original odyssey.

:D
 
Last edited:
I believe the problem with the invisible buildings has to do with the fact that you haven't updated the client with Finaltwist's changed .mul files. Which actually brings up the importance of having a separate patched Adventures client download that would already have the correct .mul files in it, as Djeryv said - might be a good idea to consider :)
Exactly what my problem was. You'd think with 20 years of playing this game I could have figured this out. Thanks!
 
Sounds like interesting changes to match the playstyle you've chosen for the server, Final! :)

I don't know why we need to have artificial restrictions, like housing restricted, and item decay. right now if i want to live somewhere i pick a home with no npc and just put chests there and voila, that's my home! "buying" the house allows you more options, like chests that have over 400 stone weight...

The only thing im worried about for item decay is that each item has a timer attached (i think) to it. so if you have 6000 items in the world, that's 6000 timers. Ill look at the core itemdecay script to see if i can't just disable that straight up so that it doesn't require a timer.
Post automatically merged:

Exactly what my problem was. You'd think with 20 years of playing this game I could have figured this out. Thanks!

i hope you like the new additions to the odyssey - its still a work in progress and we encourage you to add your own (and share with us!!).
 
And in the meantime, I updated my Player Vendor system a little bit more. Haven't moved the timers into the scheduler yet, but the change I made now is pretty interesting, I think: now the Player Vendor will remember the last 5 sales (by default, there's an option in PlayerVendor.cs that toggles it) and may report on it when you say the vendor's name and the word "report". For example, if the vendor's name is Calder, you can say "Calder report" (or "Calder please report on sales" :)), and the vendor will list the last sales that were made, if there were any (up to 5 last sales). This allows you to see what was purchased last, since those timer ticks are rare enough and are easily missed unless you stay home for a long enough period of time to see what's happening.

I also updated the part in MyServerSettings.cs which deals with the Player Vendor system to make it a bit more descriptive (however, I feel like I'd need an explanatory book similar to the ones Djeryv made, or just add it to one of the books, possibly the tavern one).

C#:
        // ******************************************************************************************************************************************
        // This section defines whether the simulated Player Vendor system is active or not, as well as defines
        // its properties. Simulated Player Vendor system allows to use player vendors in solo mode. The "virtual"
        // bot sales will be simulated at certain time periods. Recent sales can be viewed (up to 5 by default) by
        // talking and naming the vendor by name and saying the word "report", e.g. if the vendor's name is Calder,
        // saying "Calder report" will make the given vendor named Calder report on recent sales, if there were any.

        public static bool EnableSimulatedPVSales() // If enabled, Player Vendors will try to randomly "sell" items to virtual bot adventurers every 10 minutes (by default), see additional settings in Mobiles/PlayerVendor.cs.
        {
            return true;
        }

        public static bool EnableRandomPVAdvertisements() // If enabled, Player Vendors will randomly shout advertisement lines based on sold item names and descriptions
        {
            return true;
        }

        public static bool PVChargeForServicePerUODay() // If enabled, Player Vendors will charge a certain amount of money (dependent on the total price of the items for sale) for their services every UO day
        {
            return true;
        }
        // ******************************************************************************************************************************************


Post automatically merged:

Btw, removing the decay timers on items completely will make it impossible to "wipe" the world clean by resetting those timers and making the game despawn the objects, so maybe some kind of an alternative solution would be preferable, I don't know...
 

Attachments

  • PlayerVendor.cs
    80.7 KB · Views: 3
Last edited:
And in the meantime, I updated my Player Vendor system a little bit more. Haven't moved the timers into the scheduler yet, but the change I made now is pretty interesting, I think: now the Player Vendor will remember the last 5 sales (by default, there's an option in PlayerVendor.cs that toggles it) and may report on it when you say the vendor's name and the word "report". For example, if the vendor's name is Calder, you can say "Calder report" (or "Calder please report on sales" :)), and the vendor will list the last sales that were made, if there were any (up to 5 last sales). This allows you to see what was purchased last, since those timer ticks are rare enough and are easily missed unless you stay home for a long enough period of time to see what's happening.

I also updated the part in MyServerSettings.cs which deals with the Player Vendor system to make it a bit more descriptive (however, I feel like I'd need an explanatory book similar to the ones Djeryv made, or just add it to one of the books, possibly the tavern one).

C#:
        // ******************************************************************************************************************************************
        // This section defines whether the simulated Player Vendor system is active or not, as well as defines
        // its properties. Simulated Player Vendor system allows to use player vendors in solo mode. The "virtual"
        // bot sales will be simulated at certain time periods. Recent sales can be viewed (up to 5 by default) by
        // talking and naming the vendor by name and saying the word "report", e.g. if the vendor's name is Calder,
        // saying "Calder report" will make the given vendor named Calder report on recent sales, if there were any.

        public static bool EnableSimulatedPVSales() // If enabled, Player Vendors will try to randomly "sell" items to virtual bot adventurers every 10 minutes (by default), see additional settings in Mobiles/PlayerVendor.cs.
        {
            return true;
        }

        public static bool EnableRandomPVAdvertisements() // If enabled, Player Vendors will randomly shout advertisement lines based on sold item names and descriptions
        {
            return true;
        }

        public static bool PVChargeForServicePerUODay() // If enabled, Player Vendors will charge a certain amount of money (dependent on the total price of the items for sale) for their services every UO day
        {
            return true;
        }
        // ******************************************************************************************************************************************


Post automatically merged:

Btw, removing the decay timers on items completely will make it impossible to "wipe" the world clean by resetting those timers and making the game despawn the objects, so maybe some kind of an alternative solution would be preferable, I don't know...


will incorporate the playervendor changes!!

As for item decay, fear not... from what i can tell it's a core mod - so i'd have to edit the runuo core (which i don't want to do). I can't find a "baseitem" file that sets the parameters for new items. so i have to resort to putting the item timer to one year. not the best solution, but oh well.
 
Yeah, agreed!

If you want a descriptive text for the Player Vendor system, you can modify this line in SpeechText.cs (the "Banker" line) so that the Banker can explain the PV system if talked to:

C#:
            else if ( sConversation == "Banker"){ sText = "Welcome to our bank, " + sYourName +". My name is " + sMyName + ", and if you need to have some currency converted, I can help you with that. Usually, merchants do not deal in anything other than gold coins. Adventurers often come across coins from the old days. Coins like copper and silver are not too uncommon when one is looking. We usually take the copper and silver, melt it down, and sell it to local blacksmiths. We will trade you 1 gold coin for every 5 silver coins you bring to us. We will also trade 1 gold coin for every 10 copper coins you bring us. This may sound unfair, but you will not find another way to part with those coins. Simply give us a stack of coins and we will convert it for you. You may also put the coins in your bank box, double click the stack, and they will be converted as well. If you happen to find piles of jewels, we will convert those for you as well since the local jeweler often comes by to barter for them. You will know when you find these as they are the size of most coins but vary in color. Don't mistake jewels for gems like diamonds and sapphires. Jewels are found in piles like coins. For every jewel you bring here, we will give you 2 gold for each.<br><br>We also deal in some types of stones and crystals you may stumble upon. Gold nuggets are something we can turn into coins for you, and we do not mean gold ore. Gold nuggets have a shimmering glow to them. You may also find gemstones, which are different than jewels or common stones like diamonds. We will give you 2 gold coins for each of your gemstones as we use that currency with some other kingdoms far away. Crystals are another form of currency that we sometimes use with beings from other planes of existence, so we are greatly interested in them since they are very hard to find. Some claim they have mined for them in the Mines of Morinia, but nobody seems to return to tell the truth of such tales. They are shimmering red in color and we will gladly give you 5 gold for each crystal you find.<br><br>This may sound a little odd, but there are coins we are seeing that are bright green in color. Adventurers claim they find them in some ancient castle that fell from the sky centuries ago. If you find these coins, we will gladly give you 3 gold for each one you find. They are quite rare so the chances of you finding them are unlikely. One more thing, do you need a safe for your home? We sell safes that let you access your bank account from your home. They cost a great amount of gold, but we sell them nonetheless.<br><br>If you own a house and purchase a Contract of Employment, you will be able to place a vendor at your house who can trade your items to passing adventurers. You will need to change your house from Private to Public if you would like to place a vendor. Then, you can place the items you want to sell in the vendor's inventory and type in the price you would like to try to sell the item for, optionally followed by a description. Then, you will need to wait and see if the item sells. The vendor will randomly advertise the items you have and will also announce any items that sell. If you missed the announcement of a sale, you can ask your vendor to report on the recent sales by naming the vendor and saying the word 'report', for example, 'Calder report' if your vendor is named Calder. If the item is overpriced, it won't sell quickly or at all, and you may need to take it back and assign a lower price for it. Vendors charge a small sum of money every day for their services. You are advised to give some gold to the vendor up front so that he can be paid properly and on time."; }
 
this is the convo file for the banker... you'd have to break that down into keywords, like copper/gold/coin/jewel/bankbox, etc.

i agree it's a good idea - all the baseconvo datasets needs ot be upgraded since most of them deal with the typical UO world...

another project to think about !
 

Attachments

  • banker.rar
    1.3 KB · Views: 0
Yeah, true. Also, it might be possible to hook up the original Odyssey speech gumps to a certain keyword, so that the original self-describing character of the game can be preserved. Not sure if It's an easy enough undertaking, but I'll try to take a look :)
 
that's fairly easy, in my latest distro in baseconvo on the onspeech method i check if the person is saying "buy" or "sell", and if so, i open the buy/sell gump.
it would be easy to have the same routine check if the npc has a "talk" gump, and if so, if the speech has "explain" then you open the "talk" gump.

:D

i'm all for immersion
 
So I'm having a blast so far with this but I have one big question: is there a way to get any of the UO mapping software (UOAM, Cartographer, Mapper, etc) to work here? I can get the UO Position System from Razor working but it's a little primitive. I like making personal notes on the map and whatnot.

If not then I think I'll have to get my note sheet out...hehe

edit: I can get UO Cartographer to display the map but not track me. Fiddling with it as we speak.
 
Last edited:
So I'm having a blast so far with this but I have one big question: is there a way to get any of the UO mapping software (UOAM, Cartographer, Mapper, etc) to work here? I can get the UO Position System from Razor working but it's a little primitive. I like making personal notes on the map and whatnot.

If not then I think I'll have to get my note sheet out...hehe

edit: I can get UO Cartographer to display the map but not track me. Fiddling with it as we speak.

If you use the uoclassic client you can see "worldmap" in the toolbar - use that to see the entire map. You can add markers but i'm not sure how (i think it has to be done in a file... but you can read the instructions on that in the UO classic project page most likely)
 
If you use the uoclassic client you can see "worldmap" in the toolbar - use that to see the entire map. You can add markers but i'm not sure how (i think it has to be done in a file... but you can read the instructions on that in the UO classic project page most likely)

Hi, some examples of map markers. Exctract the zip file in: CLASSICUOFOLDER/Data/Client/
then right click on the world map and reload markers.

The csv format is:
longitude, latitude, text to show, icon (from MapIcons folder), facet map, text color, zoom factor required in order to see the marker.

To add more locations simply take the coordinates directly from the world map, and add to the file.
 

Attachments

  • markers.zip
    947.7 KB · Views: 15
Hi, some examples of map markers. Exctract the zip file in: CLASSICUOFOLDER/Data/Client/
then right click on the world map and reload markers.

The csv format is:
longitude, latitude, text to show, icon (from MapIcons folder), facet map, text color, zoom factor required in order to see the marker.

To add more locations simply take the coordinates directly from the world map, and add to the file.
wow thanks!

Why isn't there an option to add a marker directly ingame? would be a needed feature i would guess?
I'll have a looksy at the file and mark a few places. very useful this.
 
@Finaltwist: Regarding hooking up the explain keyword to NPCs to display the original gump - I'm thinking that something like this within each vendor NPC class's OnSpeech method would allow to simulate popping up the explanatory speech gump, I tested it and it seems to work fine:

C#:
                if ((Insensitive.Contains(e.Speech, "vendor") || Insensitive.StartsWith(e.Speech, this.Name)) && Insensitive.Contains(e.Speech, "explain")) {
                    new SpeechGumpEntry(e.Mobile, this).OnClick();
                    return;
                }

This would have to go into OnSpeech under the if (!e.Handled......) conditional :)
 
i know you'r using the original odyssey, so it might work for you, but in my fork i need to include it in the baseconvo.cs file else it doesn't work under certain circumstances.

Here's the baseconvo onspeech method, which i've amended to check for "vendor sell" and "vendor buy"

C#:
        public override void OnSpeech( SpeechEventArgs e )
        {
            Mobile pc = e.Mobile;
            if ( base.HandlesOnSpeech( pc ) )
                base.OnSpeech( e );
            
            if ( Enabled && !e.Handled && !e.Blocked && pc != null && pc.Player && pc.Alive && (int)GetDistanceToSqrt( pc ) < 4 && InLOS( pc ) && pc != ControlMaster )
            {
                
                if ( this is BaseVendor && ( e.HasKeyword( 0x14D ) || e.HasKeyword( 0x3C ) || e.HasKeyword( 0x177 ) || e.HasKeyword( 0x171 ) ) )
                {
                    if ( e.HasKeyword( 0x14D ) ) // *vendor sell*
                    {
                        e.Handled = true;
                            
                        ((BaseVendor)this).VendorSell( pc );

                    }
                    else if ( e.HasKeyword( 0x3C ) ) // *vendor buy*
                    {
                        e.Handled = true;
                        
                        ((BaseVendor)this).VendorBuy( pc );
                    }
                    else if ( e.HasKeyword( 0x177 ) ) // *sell*
                    {
                        e.Handled = true;
                            
                        ((BaseVendor)this).VendorSell( pc );

                    }
                    else if ( e.HasKeyword( 0x171 ) ) // *buy*
                    {
                        e.Handled = true;
                        
                        ((BaseVendor)this).VendorBuy( pc );
                    }
                    else
                    {
                        base.OnSpeech( e );
                    }
                }

i could add the method in there, but what about vendors that don't have "talk"? you need to put in a check there don't you? to check if the vendor has a talk entry, and if it does, then load it?
 
Nope, I tested it on your fork and it worked perfectly fine, unless I'm missing something big time in my testing. I tried it with the Banker and with the Tavernkeeper (or whatever his name was), seemed to work just fine for me. I don't think it should be in BaseConvo - the problem is, as you mentioned, is that not every NPC deriving from BaseConvo has a "Talk" entry, so there is no easy way to check from BaseConvo if the derived classes have that or not (you'd need to devise some kind of mechanism to accomplish that). I don't really see under which circumstances it wouldn't work for you if you put this inside the OnSpeech method of NPCs deriving from BaseConvo that specifically have the "Talk" option (and thus they have a SpeechGumpEntry in their class). If they don't have one, you just don't put that in, because they don't have an associated gump. Here's an example Banker.cs to use as a reference ;)
 

Attachments

  • Banker.cs
    9.6 KB · Views: 4
okay.. try sayhing "hi" to the banker, and then "where am i?" and then, "explain"

in my testing, when someone engaged in a convo the "vendor buy" didn't work, that's why i had to put it in baseconvo
Post automatically merged:

Gadget (or anyone else)... could really use some help with this system - i've creating an investment system that provides interest on money deposited on an hourly basis (based on djeryv's timers). the interest system works, but i'm having issues with the interest bag and the investment check items.

logic: have an investment bag, once in a bankbox, you can add money to it. the money gets converted into an investmentcheck
the interest system provides interest to any investment checks in the world every hour.
the investmentcheck is not movable, and once double clicked, gives the money back to the person

can you help???? i've added comments to explain what im trying to do.
 

Attachments

  • InvestmentCheck.cs
    2.5 KB · Views: 2
  • InterestBag.cs
    2.1 KB · Views: 2
Last edited:
okay.. try sayhing "hi" to the banker, and then "where am i?" and then, "explain"

logic: have an investment bag, once in a bankbox, you can add money to it. the money gets converted into an investmentcheck
the interest system provides interest to any investment checks in the world every hour.
the investmentcheck is not movable, and once double clicked, gives the money back to the person

can you help???? i've added comments to explain what im trying to do.

Very interesting! It would be possible to use player's luck as a multiplier for investment profit and losses (maybe random losses over time)?
 
Ok, I just tested that exact scenario ("hi", "where am I?", then "NAME explain" - yes, you have to type the NPC's name for it to work under that condition check that I implemented, but it can be changed, I'll try that next) - and it worked just fine :)
I'll try to take a look at the scripts you attached soon, not sure if I'll be able to figure them out, but I'll try :) I'm not really too great at coding for UO yet, but I'm also learning ^^;
Post automatically merged:

If I change my check so that it only tests for the keyword "explain" in the speech and not for the vendor's name, it also works fine (I can just type "explain", for example), but it has the unfortunate side effect that if several vendors are present at once in the nearest vicinity, all of them will open their explanation gumps at once. Which is why I originally wrote it that way where you have to name the vendor by name so that a specific vendor provides the explanation :)

But yes, this approach correctly overrides the BaseConvo conversation when the "Explain" keyword is mentioned. The possible downside is that you don't even need to be in the conversation for it to work - you can just type the name followed by "explain" (or just "explain" if you code it that way, but see the caveat above), but the upside is that it works independently from BaseConvo and doesn't need a convoluted mechanism to check for the presence of the SpeechGumpEntry inside a derived class from the base class :)
Post automatically merged:

Tried looking at the investment system code, I think it'll take me a while to figure it out... There are many logic errors in the code, not sure how easy it would be to patch it up :( I'm not very good with understanding how it should function logic-wise, I may need to check the bank box code or something like that to determine how certain things should work :/
Post automatically merged:

Actually, btw, not sure if hooking up the explanation gump to the BaseConvo or to the NPC's OnSpeech method is all that critical - there's still the single-click Talk gump entry, which you can click and it pops up the original gump, so... probably a better goal might be actually tweaking the convo definition files to match the lore of Ultima Odyssey world, but I'm not sure :)
 
Last edited:
Very interesting! It would be possible to use player's luck as a multiplier for investment profit and losses (maybe random losses over time)?

well the investment system is still in its infancy, because i don't know how to get the scripts to compile properly! i have a few ideas for it...
Post automatically merged:

Ok, I just tested that exact scenario ("hi", "where am I?", then "NAME explain" - yes, you have to type the NPC's name for it to work under that condition check that I implemented, but it can be changed, I'll try that next) - and it worked just fine :)
I'll try to take a look at the scripts you attached soon, not sure if I'll be able to figure them out, but I'll try :) I'm not really too great at coding for UO yet, but I'm also learning ^^;
Post automatically merged:

If I change my check so that it only tests for the keyword "explain" in the speech and not for the vendor's name, it also works fine (I can just type "explain", for example), but it has the unfortunate side effect that if several vendors are present at once in the nearest vicinity, all of them will open their explanation gumps at once. Which is why I originally wrote it that way where you have to name the vendor by name so that a specific vendor provides the explanation :)

But yes, this approach correctly overrides the BaseConvo conversation when the "Explain" keyword is mentioned. The possible downside is that you don't even need to be in the conversation for it to work - you can just type the name followed by "explain" (or just "explain" if you code it that way, but see the caveat above), but the upside is that it works independently from BaseConvo and doesn't need a convoluted mechanism to check for the presence of the SpeechGumpEntry inside a derived class from the base class :)
Post automatically merged:

Tried looking at the investment system code, I think it'll take me a while to figure it out... There are many logic errors in the code, not sure how easy it would be to patch it up :( I'm not very good with understanding how it should function logic-wise, I may need to check the bank box code or something like that to determine how certain things should work :/
Post automatically merged:

Actually, btw, not sure if hooking up the explanation gump to the BaseConvo or to the NPC's OnSpeech method is all that critical - there's still the single-click Talk gump entry, which you can click and it pops up the original gump, so... probably a better goal might be actually tweaking the convo definition files to match the lore of Ultima Odyssey world, but I'm not sure :)

okay i'll merge this into the vendors... have you identified which ones have the "speechgump"? i imagine there are quite a few of them...
As far as the context menu goes, i'm a proponent to removing it! I have the buy/sell removable in the myserversettings, could just be tied to that...

for example, if i ever get the investment bag script to work, im going to incorporate that into the baseconvo text for a banker - e.g. when someone says "interest bag" or "interest" or "investment" they will explain what everything is and how it works.... it's a much more organic method of explaining things to players than a speechgump, right?

for exmaple, i can see your playervendor being that way... instead of explaining things in myserversettings, why not create a new speech database called "playervendor" and populate it with a few keywords and explanations? e.g. how do you sell my things? etc. have a look at the data/convo folder
 
Yeah, sure, sounds like an interesting idea! So far, I can see that the town crier, the vendors, and some of the quest NPCs have those speech gumps, you can actually do a search inside the files for SpeechGumpEntry to determine which ones exactly have it. Here's the output for a search like that, showing all the files that reference SpeechGumpEntry.

C#:
Crafting/Guild/GuildCarpentry.cs
Crafting/Guild/GuildFletching.cs
Crafting/Guild/GuildHammer.cs
Crafting/Guild/GuildSewing.cs
Crafting/Guild/GuildTinkering.cs
Crafting/Shoppes/MerchantCrate.cs
Custom/Mobiles/Blues/BlueGuard.cs
Items/Boards/PatchBoard.cs
Items/Explorers/CamperTent.cs
Items/Maps/MapRanger.cs
Mobiles/NPCs/Chuckles.cs
Mobiles/NPCs/DeathKnightDemon.cs
Mobiles/NPCs/Guilds/AlchemistGuildmaster.cs
Mobiles/NPCs/Guilds/ArcherGuildmaster.cs
Mobiles/NPCs/Guilds/AssassinGuildmaster.cs
Mobiles/NPCs/Guilds/CartographersGuildmaster.cs
Mobiles/NPCs/Guilds/DruidGuildmaster.cs
Mobiles/NPCs/Guilds/LibrarianGuildmaster.cs
Mobiles/NPCs/Guilds/NecromancerGuildmaster.cs
Mobiles/NPCs/Healers/EvilHealer.cs
Mobiles/NPCs/Healers/Healer.cs
Mobiles/NPCs/Healers/WanderingHealer.cs
Mobiles/NPCs/Priest.cs
Mobiles/NPCs/Special/Courier.cs
Mobiles/NPCs/Special/Devon.cs
Mobiles/NPCs/Special/EpicCharacter.cs
Mobiles/NPCs/Special/Garth.cs
Mobiles/NPCs/Special/GodOfCourage.cs
Mobiles/NPCs/Special/Roscoe.cs
Mobiles/NPCs/Special/Xardok.cs
Mobiles/NPCs/Teachers/Teacher_Exalted.cs
Mobiles/NPCs/Teachers/Teacher_Legendary.cs
Mobiles/NPCs/Teachers/Teacher_Mythical.cs
Mobiles/NPCs/Teachers/Teacher_Power.cs
Mobiles/NPCs/Teachers/Teacher_Wonderous.cs
Mobiles/NPCs/Town/Citizens.cs
Mobiles/NPCs/Town/Citizens.cs.bak
Mobiles/NPCs/TownGuards.cs
Mobiles/NPCs/Vendors/Alchemist.cs
Mobiles/NPCs/Vendors/Alchemist.cs.bak
Mobiles/NPCs/Vendors/AnimalTrainer.cs
Mobiles/NPCs/Vendors/Architect.cs
Mobiles/NPCs/Vendors/Armorer.cs
Mobiles/NPCs/Vendors/Artist.cs
Mobiles/NPCs/Vendors/Baker.cs
Mobiles/NPCs/Vendors/Banker.cs
Mobiles/NPCs/Vendors/Bard.cs
Mobiles/NPCs/Vendors/Barkeeper.cs
Mobiles/NPCs/Vendors/Blacksmith.cs
Mobiles/NPCs/Vendors/Bowyer.cs
Mobiles/NPCs/Vendors/Cook.cs
Mobiles/NPCs/Vendors/Druid.cs
Mobiles/NPCs/Vendors/DruidTree.cs
Mobiles/NPCs/Vendors/DrunkenPirate.cs
Mobiles/NPCs/Vendors/Enchanter.cs
Mobiles/NPCs/Vendors/Farmer.cs
Mobiles/NPCs/Vendors/Furtrader.cs
Mobiles/NPCs/Vendors/GypsyLady.cs
Mobiles/NPCs/Vendors/Herbalist.cs
Mobiles/NPCs/Vendors/HolyMage.cs
Mobiles/NPCs/Vendors/InnKeeper.cs
Mobiles/NPCs/Vendors/Jester.cs
Mobiles/NPCs/Vendors/KeeperOfChivalry.cs
Mobiles/NPCs/Vendors/LeatherWorker.cs
Mobiles/NPCs/Vendors/Mage.cs
Mobiles/NPCs/Vendors/Mapmaker.cs
Mobiles/NPCs/Vendors/NecroMage.cs
Mobiles/NPCs/Vendors/Necromancer.cs
Mobiles/NPCs/Vendors/Provisioner.cs
Mobiles/NPCs/Vendors/Ranger.cs
Mobiles/NPCs/Vendors/Sage.cs
Mobiles/NPCs/Vendors/Scribe.cs
Mobiles/NPCs/Vendors/Shepherd.cs
Mobiles/NPCs/Vendors/Shipwright.cs
Mobiles/NPCs/Vendors/StoneCrafter.cs
Mobiles/NPCs/Vendors/Tailor.cs
Mobiles/NPCs/Vendors/Tanner.cs
Mobiles/NPCs/Vendors/TavernKeeper.cs
Mobiles/NPCs/Vendors/Thief.cs
Mobiles/NPCs/Vendors/Undertaker.cs
Mobiles/NPCs/Vendors/VarietyDealer.cs
Mobiles/NPCs/Vendors/Veterinarian.cs
Mobiles/NPCs/Vendors/Weaponsmith.cs
Mobiles/NPCs/Vendors/Weaver.cs
Mobiles/NPCs/Vendors/Witches.cs
Quests/Fishing/FishingQuestBoard.cs
Quests/Standard/StandardQuestBoard.cs
Server/Conversations/SpeechText.cs

And it's most likely possible to make the context entries a toggle in MyServerSettings, so that if someone wants them back, it's still possible :) The "explain" type Talk gumps would be very hard to do with keywords though, not only are they huge, but also it'd be a bit confusing to the player which keywords might trigger which explanations. Simpler things can be done that way though, I agree about PV being that way, I'll take a look :)
 
Yeah, sure, sounds like an interesting idea! So far, I can see that the town crier, the vendors, and some of the quest NPCs have those speech gumps, you can actually do a search inside the files for SpeechGumpEntry to determine which ones exactly have it. Here's the output for a search like that, showing all the files that reference SpeechGumpEntry.

C#:
Crafting/Guild/GuildCarpentry.cs
Crafting/Guild/GuildFletching.cs
Crafting/Guild/GuildHammer.cs
Crafting/Guild/GuildSewing.cs
Crafting/Guild/GuildTinkering.cs
Crafting/Shoppes/MerchantCrate.cs
Custom/Mobiles/Blues/BlueGuard.cs
Items/Boards/PatchBoard.cs
Items/Explorers/CamperTent.cs
Items/Maps/MapRanger.cs
Mobiles/NPCs/Chuckles.cs
Mobiles/NPCs/DeathKnightDemon.cs
Mobiles/NPCs/Guilds/AlchemistGuildmaster.cs
Mobiles/NPCs/Guilds/ArcherGuildmaster.cs
Mobiles/NPCs/Guilds/AssassinGuildmaster.cs
Mobiles/NPCs/Guilds/CartographersGuildmaster.cs
Mobiles/NPCs/Guilds/DruidGuildmaster.cs
Mobiles/NPCs/Guilds/LibrarianGuildmaster.cs
Mobiles/NPCs/Guilds/NecromancerGuildmaster.cs
Mobiles/NPCs/Healers/EvilHealer.cs
Mobiles/NPCs/Healers/Healer.cs
Mobiles/NPCs/Healers/WanderingHealer.cs
Mobiles/NPCs/Priest.cs
Mobiles/NPCs/Special/Courier.cs
Mobiles/NPCs/Special/Devon.cs
Mobiles/NPCs/Special/EpicCharacter.cs
Mobiles/NPCs/Special/Garth.cs
Mobiles/NPCs/Special/GodOfCourage.cs
Mobiles/NPCs/Special/Roscoe.cs
Mobiles/NPCs/Special/Xardok.cs
Mobiles/NPCs/Teachers/Teacher_Exalted.cs
Mobiles/NPCs/Teachers/Teacher_Legendary.cs
Mobiles/NPCs/Teachers/Teacher_Mythical.cs
Mobiles/NPCs/Teachers/Teacher_Power.cs
Mobiles/NPCs/Teachers/Teacher_Wonderous.cs
Mobiles/NPCs/Town/Citizens.cs
Mobiles/NPCs/Town/Citizens.cs.bak
Mobiles/NPCs/TownGuards.cs
Mobiles/NPCs/Vendors/Alchemist.cs
Mobiles/NPCs/Vendors/Alchemist.cs.bak
Mobiles/NPCs/Vendors/AnimalTrainer.cs
Mobiles/NPCs/Vendors/Architect.cs
Mobiles/NPCs/Vendors/Armorer.cs
Mobiles/NPCs/Vendors/Artist.cs
Mobiles/NPCs/Vendors/Baker.cs
Mobiles/NPCs/Vendors/Banker.cs
Mobiles/NPCs/Vendors/Bard.cs
Mobiles/NPCs/Vendors/Barkeeper.cs
Mobiles/NPCs/Vendors/Blacksmith.cs
Mobiles/NPCs/Vendors/Bowyer.cs
Mobiles/NPCs/Vendors/Cook.cs
Mobiles/NPCs/Vendors/Druid.cs
Mobiles/NPCs/Vendors/DruidTree.cs
Mobiles/NPCs/Vendors/DrunkenPirate.cs
Mobiles/NPCs/Vendors/Enchanter.cs
Mobiles/NPCs/Vendors/Farmer.cs
Mobiles/NPCs/Vendors/Furtrader.cs
Mobiles/NPCs/Vendors/GypsyLady.cs
Mobiles/NPCs/Vendors/Herbalist.cs
Mobiles/NPCs/Vendors/HolyMage.cs
Mobiles/NPCs/Vendors/InnKeeper.cs
Mobiles/NPCs/Vendors/Jester.cs
Mobiles/NPCs/Vendors/KeeperOfChivalry.cs
Mobiles/NPCs/Vendors/LeatherWorker.cs
Mobiles/NPCs/Vendors/Mage.cs
Mobiles/NPCs/Vendors/Mapmaker.cs
Mobiles/NPCs/Vendors/NecroMage.cs
Mobiles/NPCs/Vendors/Necromancer.cs
Mobiles/NPCs/Vendors/Provisioner.cs
Mobiles/NPCs/Vendors/Ranger.cs
Mobiles/NPCs/Vendors/Sage.cs
Mobiles/NPCs/Vendors/Scribe.cs
Mobiles/NPCs/Vendors/Shepherd.cs
Mobiles/NPCs/Vendors/Shipwright.cs
Mobiles/NPCs/Vendors/StoneCrafter.cs
Mobiles/NPCs/Vendors/Tailor.cs
Mobiles/NPCs/Vendors/Tanner.cs
Mobiles/NPCs/Vendors/TavernKeeper.cs
Mobiles/NPCs/Vendors/Thief.cs
Mobiles/NPCs/Vendors/Undertaker.cs
Mobiles/NPCs/Vendors/VarietyDealer.cs
Mobiles/NPCs/Vendors/Veterinarian.cs
Mobiles/NPCs/Vendors/Weaponsmith.cs
Mobiles/NPCs/Vendors/Weaver.cs
Mobiles/NPCs/Vendors/Witches.cs
Quests/Fishing/FishingQuestBoard.cs
Quests/Standard/StandardQuestBoard.cs
Server/Conversations/SpeechText.cs

And it's most likely possible to make the context entries a toggle in MyServerSettings, so that if someone wants them back, it's still possible :) The "explain" type Talk gumps would be very hard to do with keywords though, not only are they huge, but also it'd be a bit confusing to the player which keywords might trigger which explanations. Simpler things can be done that way though, I agree about PV being that way, I'll take a look :)

hmm... that's a "make work" project - adding the option to every npc... that's a lot!

wouldn't it be easier to merge that in baseconvo onspeech and just do a check somehow if the vendor has a speechgump? that way one routine applies the change to all the npcs at once.
 
Yeah, something like that would be a less cluttering solution with no code duplication, but I can't think of a way yet as to how to implement that... I'll let you know if I think of something though! ;)
 
Oh, that's a nice find! It might be workable if you detect SpeechGumpEntry via mobile.HasGump, but you'd still need to access that SpeechGumpEntry somehow to call its OnClick method or devise some kind of alternative way to call it (which might be tricky since it's unique for each NPC, has unique parameters and stuff...)
 
Unfortunately, that approach won't work since Banker is not a property of BaseVendor, and I don't think you can access a subclass within Banker from the base class BaseVendor that easily, but I'll try to think of something during the day that might work... It's a little trickier than it seems, unfortunately. What might be possible is an overridable method might be created in BaseVendor that would call the SpeechGumpEntry if it exists or return false if it doesn't, then that can be overridden in all the derived NPC classes to call its relevant SpeechGumpEntry methods, but that's still a lot of work since it would imply a change to each NPC class :/ Can't yet think of a way to make this work in a simpler fashion, but I'm not that great at OOP design, unfortunately, so most likely I'm just missing some kind of a hopefully obvious solution here :(
 
Ok, I tried to figure out what is possible when it comes to handling the entire "Talk" gump from BaseConvo via the "explain" keyword. Here's an example of how it can be done (note that you'll still need to write all the class names and stuff for each NPC type, since each NPC has its own SpeechGumpEntry subclass, but at least you'll be doing it in one place) - this goes into OnSpeech in BaseConvo, under the same check where the other keywords like "buy", "sell", etc. reside:

C#:
                if (Insensitive.Contains(e.Speech, "explain"))
                {
                    if (this is Banker) { new Banker.SpeechGumpEntry(e.Mobile, this).OnClick(); e.Handled = true; }
                    else if (this is Blacksmith) { new Blacksmith.SpeechGumpEntry(e.Mobile, this).OnClick(); e.Handled = true; }
                }

You'll need to continue this with more "else if" branches, obviously, for each NPC. This is most surely not the best approach from the point of view of OOP design, but it works and it's centralized in BaseConvo :)
Post automatically merged:

Here's a modified BaseConvo which lists every single vendor NPC in that code (but other NPCs are not listed yet).
Post automatically merged:

And here's the second version of BaseConvo which also lists other (non-vendor) NPCs that also have a Talk gump.
Post automatically merged:

Also, you may want to use a more robust detection of the keyword, e.g. so that it's prefixed by the word "vendor" or the vendor's name, to avoid it firing accidentally in other situations, e.g.:

if ((Insensitive.StartsWith("vendor") || Insensitive.StartsWith(this.Name)) && Insensitive.Contains(e.Speech, "explain"))

Something like that :)
 

Attachments

  • BaseConvo.cs
    28.1 KB · Views: 1
  • BaseConvo.cs
    31.3 KB · Views: 1
Last edited:
or (basevendor)this.speechgump? I n
Ok, I tried to figure out what is possible when it comes to handling the entire "Talk" gump from BaseConvo via the "explain" keyword. Here's an example of how it can be done (note that you'll still need to write all the class names and stuff for each NPC type, since each NPC has its own SpeechGumpEntry subclass, but at least you'll be doing it in one place) - this goes into OnSpeech in BaseConvo, under the same check where the other keywords like "buy", "sell", etc. reside:

C#:
                if (Insensitive.Contains(e.Speech, "explain"))
                {
                    if (this is Banker) { new Banker.SpeechGumpEntry(e.Mobile, this).OnClick(); e.Handled = true; }
                    else if (this is Blacksmith) { new Blacksmith.SpeechGumpEntry(e.Mobile, this).OnClick(); e.Handled = true; }
                }

You'll need to continue this with more "else if" branches, obviously, for each NPC. This is most surely not the best approach from the point of view of OOP design, but it works and it's centralized in BaseConvo :)
Post automatically merged:

Here's a modified BaseConvo which lists every single vendor NPC in that code (but other NPCs are not listed yet).
Post automatically merged:

And here's the second version of BaseConvo which also lists other (non-vendor) NPCs that also have a Talk gump.
Post automatically merged:

Also, you may want to use a more robust detection of the keyword, e.g. so that it's prefixed by the word "vendor" or the vendor's name, to avoid it firing accidentally in other situations, e.g.:

if ((Insensitive.StartsWith("vendor") || Insensitive.StartsWith(this.Name)) && Insensitive.Contains(e.Speech, "explain"))

Something like that :)

good work!

wouldn't it be possible to define a variable and define it to be the npc's type at the beginning of the method, and simply copy that in in the method?
C#:
e.g.
Mobile npctype = [npc type];

after detection of explain
new npctype.SpeechGumpEntry(e.Mobile, this).OnClick(); e.Handled = true; }
    if nospeechgump, base.onspeech?

well, you did all the work anyways, so might as well use what you used! I"m learning so was just a question :D :D
Post automatically merged:

i think i'll have "npc name" added to the keyword search since youre right it can cause issues in an environment with a lot of npcs. also, i can add this in "message of the day" on new player login that way people are ware of the feature.
Post automatically merged:

getting an error on mine (why aren't you getting this error? - we have identical baseconvos!)

1588594019986.png

head.cs has the startswith method, and only uses one argument, however Insensitive requires two string arguments apparently

1588594072351.png
 
Last edited:
Yeah, that line was mockup code, you're correct that it needs two parameters - Insensitive.StartsWith(e.Speech, this.Name) or whatever - not at my PC now, so can't check if this is 100% correct, but hopefully you get the idea - it's similar to Equals in syntax.

Sadly, that other idea won't work, SpeechGumpEntry is a subclass (and a subclass unique to each NPC class), so you can't reference it through an object variable like that...

Btw, took me less than 5 min to make that code block above with some Vim and regular expressions magic :))
 
well well done, i'm fixing the baseconvo now and figured out how to fix it. :D

i'll make a quick mention of this in the message of the day gump for those who are new. it's a good addition to the game!

new working version (will test ingame)
 

Attachments

  • BaseConvo.cs
    31.4 KB · Views: 2
Yep, glad you'll find it useful! I'll take a look at a PlayerVendor update soon :) Are you planning an update after this aspect of BaseConvo is covered?
 

Active Shards

Donations

Total amount
$50.00
Goal
$1,000.00
Back