Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » Finished MUD Scripts
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Sat Feb 11, 2006 7:47 pm   

Walk Location System
 
The point of this system is to allow you to type 'walk something or another' and it will try to figure what you meant and go to the right place.

It works by checking through your zonenames and shortIDs to determine possible matches. When only 1 type of match is found and in the case of IDs they all have the same name it will then calculate up a shortest route and issue the walk. During each of the various steps it populates up variables for future retrievals so the first bunch of times you use it there are going to be many extra calculations, but after that it is quite fast.

I also included an unfinished 'walkroom' alias that uses the same basic method to locate possible matches for roomnames. I haven't finished it since I really have no idea what would make it truly useful.

If anyone has any suggestions about the roomnames or anything else let me know.
Code:
#CLASS {AutoWalker}
#ALIAS walk {DestList="";ZoneDest="";ShortDest="";#NOOP %-1;#IF (%numzones!=%numitems(@ZonesList)) {#SHOW Loading ZonesList;#LOOP %numzones {#ADDITEM ZonesList {%zonename(%i)}}};DestTemp=@ZonesList;DestTemp3=1;#WHILE (@DestTemp3<=%numparam) {#WHILE (@DestTemp) {DestTemp2=%pop(DestTemp);#IF (%pos(%lower(%param(@DestTemp3)),%lower(@DestTemp2))) {#ADDITEM ZoneDest {@DestTemp2}} {#DELITEM ZoneDest {@DestTemp2}}};DestTemp=@ZoneDest;#ADD DestTemp3 1};#IF (@ZoneDest) {#SHOW Found Zone:@ZoneDest};DestTemp=%mapquery("IDName = '%-1'");#IF (@DestTemp="") {DestTemp3=1;#WHILE (@DestTemp3<=%numparam) {DestTemp=%mapquery(%concat("IDName LIKE '~%",%param(@DestTemp3),"~%'"));#IF (@DestTemp) {DestTemp2=%replace(%eval(%concat("%roomid(",%replace(@DestTemp,"|",")_%roomid("),")")),"_","|");#IF (@ShortDest.numbers) {#FORALL @ShortDest.numbers {#IF (%ismember(%i,@DestTemp)=0) {#DELNITEM ShortDest.shorts {%ismember(%i,@ShortDest.numbers)};#DELITEM ShortDest.numbers {%i}}}};#IF (@DestTemp3=1) {#ADDKEY ShortDest shorts {@DestTemp2};#ADDKEY ShortDest numbers {@DestTemp}}} {#ADDKEY ShortDest.numbers {};#ADDKEY ShortDest.shorts {}};#ADD DestTemp3 1}} {DestTemp2=%replace(%eval(%concat("%roomid(",%replace(@DestTemp,"|",")_%roomid("),")")),"_","|");#ADDKEY ShortDest shorts {@DestTemp2};#ADDKEY ShortDest numbers {@DestTemp}};#IF (@ShortDest.numbers) {#SHOW Found Short:@ShortDest.shorts};#IF (%numitems(@ZoneDest)=1) {#IF (@ShortDest.shorts="") {#SHOW Locating Zone;DestList=%db(@ZoneBorders,@ZoneDest);DestTemp=%mapquery(%concat("ZoneID = ",%zonenum(@ZoneDest)));DestTemp3=@DestTemp;#IF (@DestList="") {#IF (@DestTemp="") {#SHOW No rooms in zone:@ZoneDest} {#SHOW Locating zone borders.;#WHILE (@DestTemp) {DestTemp2=%roomexit(%item(@DestTemp,1));#FORALL @DestTemp2 {#IF (%len("%i")=1) {#IF (%roomlink(%item(@DestTemp,1),@DirConvertS(%i))=-2) {#DELITEM DestTemp2 {%i}} {#IF (%ismember(%roomlink(%item(@DestTemp,1),@DirConvertS(%i)),@DestTemp3)) {#DELITEM DestTemp2 {%i}}}} {#IF (%ismember(%item(%roomportal(%item(@DestTemp,1),"%i"),2),@DestTemp3)) {#DELITEM DestTemp2 {%i}}}};#IF (@DestTemp2="") {#DELNITEM DestTemp 1} {#ADDITEM DestList {%pop(DestTemp)}}};#ADDKEY ZoneBorders {@ZoneDest} {@DestList}}};#IF (%ismember(%roomnum(),@DestTemp3)) {#SHOW Alredy in zone @ZoneDest;DestList=%roomnum}}} {#IF (@ZoneDest="") {#IF (@ShortDest.shorts) {DestTemp=%item(@ShortDest.shorts,1);#DELITEM ShortDest.shorts {@DestTemp};#IF (@ShortDest.shorts="") {DestList=@ShortDest.numbers;#IF (%ismember(%roomnum,@DestList)) {#SHOWP Already at @DestTemp location,;#DELITEM DestList {%roomnum};#IF (@DestList!="") {#SHOW " walking to another."} {DestList=%roomnum;#SHOW " and that is the only one."}}}}}};#IF (@DestList="") {#SHOW Query did not result in good destination list} {#IF (%numitems(@DestList)=1) {#IF (@DestList!=%roomnum) {#WALK @DestList}} {#SHOW Narrowing @DestList down with find closest method.;DestTemp=@DestList;DestTemp3="";#ADDKEY DestTemp3 {best} {999};#WHILE (@DestTemp) {DestTemp2=%pathexpand(%walk(%item(@DestTemp,1)));#IF (%numitems(@DestTemp2)<@DestTemp3.best) {#DELITEM DestTemp {@DestTemp3.location};#ADDKEY DestTemp3 best {%numitems(@DestTemp2)};#ADDKEY DestTemp3 location {%item(@DestTemp,1)}} {#DELNITEM DestTemp 1}};#WALK @DestTemp3.location}}}
#ALIAS walkroom {DestList="";NameDest="";DestTemp=%mapquery("Name = '%-1'");#IF (@DestTemp="") {DestTemp3=1;#WHILE (@DestTemp3<=%numparam) {DestTemp=%mapquery(%concat("Name LIKE '~%",%param(@DestTemp3),"~%'"));#IF (@DestTemp) {DestTemp2=%replace(%eval(%concat("%roomname(",%replace(@DestTemp,"|",")_%roomname("),")")),"_","|");#IF (@NameDest.numbers) {#FORALL @NameDest.numbers {#IF (%ismember(%i,@DestTemp)=0) {#DELNITEM NameDest.names {%ismember(%i,@NameDest.numbers)};#DELITEM NameDest.numbers {%i}}}};#IF (@DestTemp3=1) {#ADDKEY NameDest names {@DestTemp2};#ADDKEY NameDest numbers {@DestTemp}}} {#ADDKEY NameDest.numbers {};#ADDKEY NameDest.names {}};#ADD DestTemp3 1}} {DestTemp2=%replace(%eval(%concat("%roomname(",%replace(@DestTemp,"|",")_%roomname("),")")),"_","|");#ADDKEY NameDest names {@DestTemp2};#ADDKEY NameDest numbers {@DestTemp}};#IF (@NameDest.numbers) {#SHOW Found Name:@NameDest.names};#IF (@DestList="") {#SHOW Query did not result in good destination list} {#IF (%numitems(@DestList)=1) {#WALK @DestList} {#SHOW Narrow list down.}}}
#VAR DestList {} {}
#VAR ZonesList {}
#VAR DestTemp {} {}
#VAR DestTemp2 {} {}
#VAR DestTemp3 {} {}
#VAR ZoneDest {} {}
#VAR ShortDest {} {}
#VAR NameDest {} {}
#VAR ZoneBorders {}
#CLASS 0
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
ZealousAnonymous
Wanderer


Joined: 06 Jan 2006
Posts: 70

PostPosted: Fri Mar 03, 2006 8:17 am   
 
Im gonna give this a try and see how it works!
Reply with quote
ZealousAnonymous
Wanderer


Joined: 06 Jan 2006
Posts: 70

PostPosted: Fri Mar 03, 2006 8:23 am   
 
Neat script. I do a findroom function that pumps out a list of rooms mxp clickable by zone name and such. But I like this.
Reply with quote
ZealousAnonymous
Wanderer


Joined: 06 Jan 2006
Posts: 70

PostPosted: Fri Mar 03, 2006 8:30 am   
 
I use

#CALL %mapfilter(%concat([Name] LIKE '%-1%')
#IF (%numrooms( ) > 50) {
#echo %ansi( gray, black)far to many rooms match, it may be an unmapped room
#CALL %mapfilter("")
#ABORT 1
}
#IF (%numrooms( ) = 0) {
#echo %ansi( gray, black)Not Mapped!
#CALL %mapfilter("")
#ABORT 1
}
#LOOP 1,%numrooms( ) {#echo %ansi( gray, black)Room: %mapvnum( %i)}
#CALL %mapfilter("")

For room names and then it pumps them out.
Reply with quote
Vitae
Enchanter


Joined: 17 Jun 2005
Posts: 673
Location: New York

PostPosted: Fri Jun 23, 2006 2:24 pm   
 
Vijilante,
How would I use this if all I use are room names?
Or can someone show me how to take the room names and convert them into short ids? (prefer not this way because i don't want my map to open slower than it already does. I don't have ANY room descs, just room names and it can take up to 2 minutes to open this 10K room map)

Tho, I think I'm finding an error:
I went and set a 4 room block with the shortid of The Gemstone.
I type:
walk The Gemstone
Loading ZonesList
Found Short:The Gemstone|The Gemstone|The Gemstone|The Gemstone
Narrowing 3131|3132|3133|3134 down with find closest method.
d
s
... etc etc etc ...
The Gemstone
Exits: s, n, w

YAY!!!!

walk The Gemstone
Loading ZonesList
Found Short:The Gemstone|The Gemstone|The Gemstone|The Gemstone
Narrowing 3131|3132|3133|3134 down with find closest method.

no movement

walk The Gemstone
Loading ZonesList
Found Short:The Gemstone|The Gemstone|The Gemstone|The Gemstone
Narrowing 3131|3132|3133|3134 down with find closest method.

again no movement

dunno, but i think the exclude current room part is broken....
_________________
http://www.Aardwolf.com
Reply with quote
Vitae
Enchanter


Joined: 17 Jun 2005
Posts: 673
Location: New York

PostPosted: Fri Jun 23, 2006 3:19 pm   
 
Also, another small quirk.:
#IF (%numzones!=%numitems( @ZonesList)) {
#SHOW Loading ZonesList
#LOOP %numzones {#ADDITEM ZonesList {%zonename( %i)}}
}

Everytime I ran the walk it would ALWAYS show the Loading ZoneList and I didn't understand why:

#show %numzones
215

#show %numitems( @ZonesList)
198

err...what?

#LOOP %numzones {#show {%zonenum( %i) - %zonename( %i)}}
208 - Winterfell
209 - Midgaard
210 - Wood Elves of Nalondir
211 - Midgaard
212 - Midgaard

213 - Yggdrasil: The World Tree
214 - Yurgach Domain
215 - Clan Seekers

YIKES!!

And here are all zones from 208 on.
208 = Winterfell
210 = Wood Elves of Nalondir
213 = Yggdrasil: The World Tree
214 = Yurgach Domain
215 = Clan Seekers
216 = Clan Crusaders
220 = Dortmund
221 = Cougarian Queendom
222 = Giants Pet Store
223 = Zoological Park
224 = Forest of Li'Dnesh
225 = Marshlands of Agroth
226 = Land of Legends
227 = Lasertag
228 = Clan Perdition
231 = Wobbly Woes of Woobleville
232 = Gallowshill
233 = Raganatittu
234 = Clan Watchmen
235 = Cradlebrook
236 = Snuckles Village
237 = Misty Shores of Yarr


So, something in something is screwy cause from 216 to 237 nothing is even considered.
_________________
http://www.Aardwolf.com
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Tue Jul 04, 2006 12:09 am   
 
Sorry for the long delay in getting back to you. The only think I can think of to correct the problem with zone searching is changing the %zonenum function to %zonevnum and without looking it up in the help I am not sure that will have any benefit. I have seen some odd circumstances were the script fails reporting that the query did not produce a good result, but on next execution it runs perfectly.

I will say this odd item, I run a master and child window setup that actually has the mapper operated off the child window. My setup makes a strong attempt to operate between the windows transparaently through a few triggers. The script I posted was peeled out of that, and has odd bugs even in my 'stable' system. My goal is more to post very functional scripts that get people thinking about solutions then to provide a perfect solution. I personally love just typing 'walk mana' and having that be enough for it to find the entrance to the zone named Manara. Preform the necessary steps to get there is just icing on my cake...and in the case of my setup the icing is really thick to handle the whole thing between 2 windows.

I would suggest waiting some until I actually get everything adjusted for CMud then I will provide a new package in that system.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Vitae
Enchanter


Joined: 17 Jun 2005
Posts: 673
Location: New York

PostPosted: Tue Jul 04, 2006 3:57 pm   
 
yeah, changed the zonenum to zonevnum and still have the same errors
constant rebuilding of the zone list and will not leave the gemstone room to travel to one of the others.

Loading ZonesList
Found Short:Gemstone|Gemstone|Gemstone|Gemstone
Narrowing 3131|3132|3133|3134 down with find closest method.
Loading ZonesList
Found Short:Gemstone|Gemstone|Gemstone|Gemstone
Narrowing 3131|3132|3133|3134 down with find closest method.
Loading ZonesList
Found Short:Gemstone|Gemstone|Gemstone|Gemstone
Narrowing 3131|3132|3133|3134 down with find closest method.

Oh well :-)

Either way, thinking this is more in depth than i really want.
All I'd really need is once in a zone that it would work only IN that zone.
Most zones will not have a same named room between them, but most zones will have the same room name several times.
Like underdarks The Gemstone. there's 4 rooms of that name in UD, but no where else.

I'll try to pick apart your code and see what I come up with :-)
_________________
http://www.Aardwolf.com
Reply with quote
Gnord
Beginner


Joined: 05 Jul 2006
Posts: 15

PostPosted: Fri Jul 14, 2006 7:50 am   
 
This is pretty cool.

using Vijilante's code (1st post) I get:


< 466h/466H 123v/124V Pos: standing >
<> walk inn <- My input
Loading ZonesList
Found Zone:Mini Zones (Arlik's Inn)
Found Short:Inn|Inn|Inn|Inn|Inn|Inn|Inn|Inn|Inn|Inn|Inn|Inn|Inn|Inn|Inn|Inn|inn|Inn|Inn|Inn|inn|Inn|Inn
Query did not result in good destination list

A stray cat enters from the north.

< 466h/466H 123v/124V Pos: standing >
<> walk bank <- My input
Loading ZonesList
Found Short:Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|Bank|bank
Query did not result in good destination list

So obviously I have a few too many of those keywords, heh.

Using ZealousAnonymous's code (4th post) I get:

< 466h/466H 124v/124V Pos: standing >
<> walk2 inn <- My input
Room: 23743
Room: 23894
Room: 25999
Room: 34200
Room: 55162
Room: 71206
Room: 71207
Room: 71386
Room: 71665
Room: 87640
Room: 89001
Room: 89002
Room: 89003


< 466h/466H 124v/124V Pos: standing >
<> walk2 bank <- My input
Room: 25954
Room: 27459
Room: 27839
Room: 31076
Room: 33694
Room: 39615
Room: 39616
Room: 39617
Room: 39618
Room: 39619
Room: 39620
Room: 39775
Room: 39776

Scary.
So, do you guys think you could come up with the speedwalking paths to each location, determine which one has the shortest path, and then speedwalk to that room?
Reply with quote
Danlo
Magician


Joined: 28 Nov 2003
Posts: 313
Location: Australia

PostPosted: Tue Mar 06, 2007 1:44 pm   
 
I don't know if anyone is still reading this finished script, but I made a script to convert my maps to a database, then use that database to find the rooms. The big bonus of this script, is that all rooms by the same name are stored in a single record, so your maps can be reduced to a much smaller size. I have included the script below:

Script to convert maps to database (Database contains first column of RoomName and second column of RoomVnum):
Code:

#LOOP %numrooms {#var MapVnum {%mapvnum(%i)}
#if (!%null(%roomname(@mapvnum)) & %roomcost(@mapvnum)<1000) {
#var QueryResult {%query(&RoomName = %roomname(@mapvnum),All)}
#if (!%null(@QueryResult)) {
#var DBRec {@QueryResult}
#DBGet @DbRec
#DBPut @DBRec RoomName %roomname(@mapvnum) RoomVnum %additem(@mapvnum,&RoomVnum)} {#NEW "" RoomName=%roomname(@mapvnum) RoomVnum=@mapvnum}}}

Further notes on use: I have included a check on the roomcost to determine whether the room is flagged DoNotEnter. You can remove this check if you want to include those rooms in the DB, or increase the value to anything just short of the DoNotEnter mv cost value if some of your rooms have a cost greater than 1000.

Scripts to search database, find the closest room by the name, and go to it:
Code:

#ALIAS locate {Tellstring=%null;#VAR LocateResult {%db( %query( &RoomName = "%-1"), RoomVnum)};#IF @LocateResult {#FORALL @LocateResult {#ADDITEM TellString {%zonename( %roomzone( %i))}};#ECHO Room is at: %replace( @Tellstring, "|", ", ");Tellstring=%null} {#ECHO Room is not in the Database.}}
#ALIAS goto {#var Goto {%lower(%-1)};#if (@Goto = "questroom") {#if (!@LocateResult) {#ECHO There are no rooms found for your Quest.} {NearestRoom @LocateResult;#delitem LocateResult @NearestRoom.RoomVnum;#walk @NearestRoom.RoomVnum} {#walk %-1}}}
#ALIAS NearestRoom {NearestRoom.PathLength=1000;NearestRoom.RoomVnum=%null;#loop 1,%numitems(%-1) {#if (%numitems(%pathexpand(%walk(%item(%-1,%i))))<@NearestRoom.PathLength) {#addkey NearestRoom RoomVnum %item(%-1,%i);#addkey NearestRoom PathLength %numitems(%pathexpand(%walk(%item(%-1,%i))))} {}}}

Notes on use: It's really simple. You use the locate alias to find the room name you want to go to, then you type goto questroom to go to the closest room by that name. The locate alias also returns the name of the zone containing the specific room names. You can combine these two simply by making a new alias such as:
Code:
#alias MoveToRoom {#var LocateSearch {%-1};locate @LocateSearch;goto questroom}

The goto alias incorporates the NearestRoom alias which finds the closest matching room. The more rooms returned, the longer it takes to find the closest room. For example, on my MUD, the room Ocean has about 200 rooms by that name. Finding the closest room takes a fairly long time, and despite the number of rooms with that name, the database returns the rooms with that vnum very quickly because all rooms are contained in a single DB entry.

Further notes on changing or modifying the script:
Apart from the above script, you can fairly easily modify it to search for rooms containing a specific substring. Instead of using %query, use %find, combine the RoomVnum results into a single LocateResult variable (Room Vnums are contained in a string list), or alternatively display a list of different matching room names before clicking on the exact roomname via mxp to search and goto those rooms. The possibilities are many and varied. If you would like some help on modifying it, please contact me.
Danlo
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » Finished MUD Scripts All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net