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

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD General Discussion
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Wed May 16, 2007 3:56 pm   

Need help writing a complex script
 
I'm a builder on a Diku/Circle/Lexi derivitive mud which uses Oasis OLC. The coder recently made a HUGE code change that drastically changed how VNUMs are handled by the MUD. It used to the classic VNUM system. <ZONE#><ROOM#> (example 30255, Zone 302, room 55).

The change went to a virtual ID system which significally expands zones. The new system looks like this <ZONE Name or #>:<Room#> (example NewZone:00). The new system allows from 0 to 2,000,000 rooms per zone.

Before the change, several large areas were spread across several zones, for example one area used zone 302, 303, and 304. The break in the zones not only makes organization difficult, but is also a nightmare when working with scripts (as scripts don't work across zones unless globaled).

The Implementer wants all multizone areas moved a new expanded zone to help keep things organized among others.

I have all the rooms/areas/zones on the MUD in a map database using the Automapper.

What I need to do is this: I need to write a script to rebuild several zones using information from the Automapper.

Unfortunately, I have no idea on even where to begin writing the script. Any help would be GREAT appreciated.

Thanks.
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Wed May 16, 2007 4:21 pm   
 
Take a look at the %room... series of functions and the %zone... series. You can use %roomzone to set the zone of a room, and %zonenum to return zone numbers for use with %roomzone.

The problem is getting the script to recognise which rooms it needs to move and which it can leave alone. If all you want to do is merge two or more zones, as it sounds, you'll probably find it easier to use the mapper's GUI - highlight the rooms you want to move, press Ctrl+z or choose "Move to zone" from the Edit menu, and choose the destination zone. Then just delete the empty zone.

You might also find it useful to edit the database manually - there are plenty of tools floating around the web to edit databases, with all kinds of batch tools.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Wed May 16, 2007 4:50 pm   
 
I think I might have been a little unclear as to what I actuallly need. I don't need to move the zones in the automapper, I need a script that will extract information from the automapper to quickly rebuild a zone on the mud itself
Reply with quote
Arminas
Wizard


Joined: 11 Jul 2002
Posts: 1265
Location: USA

PostPosted: Wed May 16, 2007 5:04 pm   
 
I'm sorry I cannot be much help at the moment but I can point in a vague direction.

You should be able to use the %roomname and %roomdesc to retrieve the names and descriptions from inside the automapper.

It sounds like you need something more complex though. The mapper is written in a microsoft access database perhaps you would have an easier time looking at it through access?
_________________
Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Wed May 16, 2007 5:10 pm   
 
So you want to sync the zone settings for each room on the server with those in your mapper database. How do you go about changing the zone that's registered for a room? Are the vnums of the rooms in your mapper the same as those on the server? The process could be as simple as building a table the matches the zone vnum in the mapper with the zone vnum on the server and then doing something like

#loop %numrooms() {set zone for room %mapvnum(%i) to %zonevnum(%roomzone(%mapvnum(%i)))}
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Wed May 16, 2007 5:27 pm   
 
It might be helpful if I gave a more details explaintion of what I need. Lets start with the Oasis OLC roomedit utility, which looks like this:

-- Room number : [12:49]
1) Name :
2) Description :
3) Room flags :
4) Sector type : Inside
5) Exit north : <NOWHERE>
6) Exit east : 12:82
7) Exit south : <NOWHERE>
8) Exit west : <NOWHERE>
9) Exit up : <NOWHERE>
A) Exit down : <NOWHERE>
B) Extra descriptions menu
Q) Quit
Enter choice :

I need to be able to define a range for the VNUMs. Both for what is extracted from the Automapper (in this case, vnums 30200-30299, 30300-30399, and 30400-30499) and the new rooms to be built (vnums NewZone:0 - NewZone:300).

Then I would need for the script to evaluate which goes where. Meaning, Vnum 30200-30299 be used for new room NewZone:0-NewZone:99, Vnum 30300-30399 would be used for new room NewZone:100-NewZone:199, Vnum 30400-30499 would be used for new rooms NewZone:200-NewZone:299.

Then it should open the editing utility (Syntax redit <vnum>) which would bring up the above screen.
Then, send 1 for room name and send the extracted text from the automapper for room name.
Then, send 2 for room description and send the extracted text from the automapper for room description.
Send /fi and /s to format and save the room description.

Next it should evaluate options 5 through A on the redit screen (the direction, N, E, S, W, Up, Down) and edit to include the VNUM for the rooms matching the directions in the automapper.

It should then send q for quit and y for yes to save.

Once it has completed NewZone:0, it should then automatically proceed to NewZone:1, then NewZone:2, etc, until all rooms in the defined range are completed.

Unfortunately, like I said, I have no idea where to begin with writing this script (other than %roomname and %roomdesc which were kindly provided above :), thank you).

Ultimately, I need to move approximately 10,000 rooms, 5,000 objs, and 3,500 mobs to new vnums. Having an automated script would save me MONTHs and keep me from pulling my hair out.

Any help will be greatly appreciated.
Reply with quote
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Wed May 16, 2007 5:42 pm   
 
Actually, this might be a pointless exercise (as I don't know the flexibility of CMUD and the Automapper, I don't know).

Once the new code was implemented, it changed the naming convention of the existing VNUMs which appear to be incompatible with the VNUM capture of the Automapper.

I'll use zone 302 room 0 as an example.
The convention used to be the standard vnum, 30200, which was easily captured by the Automapper and recognized as a valid VNUM.

The convention changed to vnum 302:0, which the Automapper does not seem to recognize as a valid VNUM now.

So, it might very well be impossible to capture the correct VNUMs to be used for evaluating which rooms go where.

Unless maybe #TAG could be used? Maybe with a trigger to execute on the new vnum and #TAG {%roomvnum(%1)} or something similiar?

Sorry, I've never had to utilize the functions and commands like #TAG and %roomvnum/%zonevnum/etc before. This is definately going to be a learning experience.
Reply with quote
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Wed May 16, 2007 6:03 pm   
 
Room information looks like this:

[303:94] Intersection of Mountain Trail Ave and Purple Heart Ave [ NOBITS ] [Inside]
You are in a freshly dug room.
[ Exits: N E S W ]

So [303:94] is the vnum, Intersection of Mountain Trail Ave and Purple Heart Ave is the name, [ NOBITS ] and [Inside] are room flags.

As I've said, I've never had to use #TAG before, and I can't seem to figure it out to see if capturing that style of vnum is even possible.

I've tried #TRIG {~[(%d)}~ (*) [(*)] [(*)]} {#TAG vnum,name,flag,flag {%1} {%2} {%3} {%4}}, bit it doesn't work properly when I reconfigure the automapper.
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Wed May 16, 2007 6:24 pm   
 
Unfortunately the mapper's vnum property only allows numbers. There's a "short name" field on the room properties that's set with the %roomid function and that would allow colons, but I can't find any way to set room functions to use that name instead of the vnum, or to translate a room id into a room's vnum.

EDIT: I think I need to clarify this... rooms in the mapper must have a unique vnum. This number can be independent of their vnum on the server, and in this script they will be. They have to be, since mapper vnums can't contain colons. To avoid confusion, in the rest of this post I'm going to refer to the client-side vnum as its vnum and its server-side vnum as its id, since those are the room properties fields where they're stored. I hope that makes sense - take a look at the Other tab of the room properties dialog and you'll see what I mean. END EDIT.

That said, it should be simple to convert your map from old-style vnums into new-style ids (this example assumes that all zone vnums are 3 characters and room vnums are two - if zone vnums can have a varied length it should be possible to use %numchars($vnum)-2 instead of a static value):

#loop %numrooms() {$vnum=%mapvnum(%i);#call %roomid($vnum,%insert(":",$vnum,3))}

Once you've done this, you should be able to iterate over all your rooms setting %roomid(%i) as the room's vnum and using %roomname and %roomdesc to get those. To do the exits, you'll want to use %roomlink to return the vnum of a room in a specific direction. You can then use %roomid to return the id of the room in that direction, which you'll set as the exit in that direction. You didn't explain the actual commands needed to set parameters very well (or well enough for me to understand ;P) - if you can set room exits individually you could use something like

#loop %numrooms() {$vnum=%mapvnum(%i);#forall %roomexit($vnum) {#say %roomid(%roomlink($vnum,%j))}}

and if you have to set them all in that specific order you have there, you'll want to use something like:

#loop %numrooms() {$vnum=%mapvnum(%i);#forall n|e|s|w|u|d {$link=%roomlink($vnum,%j);#if ($link>0) {#say %roomid($link)}}}

You'll want to change the #say command to whatever you need to send in order to set the exit.

EDIT2: When you create a new room, don't use #tag to set the vnum - let the mapper set the vnum on its own, since it's irrelevant once you've translated the old-style vnums stored in the mapper into new-style ids. Just call the %roomid function for the current room:

#trig {whatever your room looks like} {#call %roomid(,%1)}
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Sat May 19, 2007 3:56 am   
 
Breaking news: vnums in the automapper don't need to be unique, which makes it even easier to totally ignore them. Also, take a look at the %roommode function. I thought that database key meant some internal number - it actually means the room's shortid, which is excellent if you want to do any complicated scripting once you've converted your map database from using the mapper's vnums to using shortids.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Wed May 23, 2007 5:48 pm   
 
After a week of playing with the automapper, I've decided to not use it at all. Like I've said, I'm unfortunately very new to scripting with CMUD and that inexperience is limiting me greatly in this project. I've decided to go with something which seems to me to be alot simplier. I've decided that instead of extracting the information from the automapper, I will simply write a script that will goto the room that needs to be copied, capture the information with triggers and variables, then launch another trigger that will copy the room information from the variables collected. However, since I am still very inexperienced with scripting with CMUD, I'm not sure exactly how to do it. If I were using C++ or the script used by the mud, I would already know how to do it, I just need help with figuring out how the script should be formatted for use with CMUD.

My two big hang ups are: How to correctly use the #if command and also how to capture multi-lines of text in a variable.

I also need to way to define a range of vnums for the script to work properly. Allow me to explain a step at a time.

Basic Script Layout.
mud command: goto vnum (vnum being the variable of the room number, goto being the command that takes you to the room)
redit (The room edit command)
Triggers and Variables to capture and store room information.
exit redit
redit <new vnum>
Send information to the redit utility, format, exit, save.
goto next vnum in sequence.

First, how to define a range of vnums. The vnums I currently need to copy are 30200-30299, 30300-30399, and 30400-30499. So basically, 30200-30499. I assume I could just store the starting vnum of 30200 in a variable, use that variable in the script and at the end of the script use the #math command to add 1 to the variable?

#math Variable (Variable+1)?

Next, I would need to have the script convert the old vnum to the vnum of the new zone. Again, I don't know how to do this in CMUD script, but I will use an standard if/else statement to explain what I need.

Redit output for room number looks like: -- Room Number : [302:0]
302:0 is the same as 30200 and the mud can use either for the old rooms.

#trig {-- Room Number : ~[(%d):(%d)~]
#if {%1=302} {#VAR RoomNumber NewZoneName:%2} (should return 'NewZoneName:0')
#if {%1=303} {#MATH Variable (%2+100);#VAR RoomNumber NewZoneName:@Variable} (should return 'NewZoneName:100')
#if {%1=304} {#MATH Variable (%2+200);#VAR RoomNumber NewZoneName:@Variable} (should return 'NewZoneName:200')

Thus, if original vnum is 302:0, should return NewZoneName:0; if 303:0, should return NewZoneName:100;if 304:0, should return NewZoneName:200.

Simple Trig to dump one line room name to variable.

Then a Trig to capture a multi-line room description (I don't know how to do multiline captures to variables)

Next is another tricky part. The room exits. In the Redit screen, there will be two options available. <NOWHERE> if there is no exit in that direction, or the vnum of the room in that direciton if it exists (in 302:0 format). I would need the script to ignore <NOWHERE> and move to the next exit or convert the vnum from old to new like above.

Then it would quit the redit screen and send 'N' for no to the save prompt.

That would complete the capture part.

The copy part of the script would be straight forward and should be simple.
Script would simply send the following information.
redit <converted variable for new room, captured and converted from above #if statments>
send 1 for Room Name prompt
send Variable for room name(automatically dumps back to main redit screen)
send 2 for Room Description Editor
send Variable for room description
send '/fi' to format with indent
send '/s' to save and exit back to main redit screen.
send (5,6,7,8,9,A) for Exit Edit Screens for each direction.
send 1 for Exit To Vnum
send Variable for appropriete Vnum Exit
send '0' to quit
then progress to the next exit until last 'A'
send 'Q' to quit
send 'Y' to save

This part should be simple once the capture is complete, as no output from the mud is actually needed. A trigger would probably be setup for the last 'Send 'Y' to save' that would both send the 'Y' and add 1 to the vnum, then call the script to start the capture and write for the next vnum in range.

So basically all I need help with is:
Defining the Vnum Range (I think I already have that, but would like your feedback on it regardless)
How to format the #if commands to function how I illustrated above.
How to capture multiline output from the mud to a single variable (for room description)
How to write the script to ignore <NOWHERE> and capture/convert appropriate VNUMs for the exits

For Reference, I will include examples of the redit screens, including exit editor, below.

-- Room number : [302:0]
1) Name : West Gate
2) Description :
Line 1 of Desc
Line 2 of Desc
Line 3 of Desc
4) Sector type : City
5) Exit north : <NOWHERE>
6) Exit east : 302:1
7) Exit south : <NOWHERE>
8) Exit west : <NOWHERE>
9) Exit up : <NOWHERE>
A) Exit down : <NOWHERE>
B) Extra descriptions menu
Q) Quit
Enter choice :


1) Exit to : 302:1
2) Description :-
<NONE>
3) Door name : door
4) Key : 0:0
5) Door flags : NOBITS
6) Purge exit.
Enter choice, 0 to quit :
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Wed May 23, 2007 6:37 pm   
 
You've got the simplest way to do the vnum iterating since you want to pause between iterations. If you didn't need to pause, you could just use #loop, but since you do, that's the best way.

#if (expression) {true-command} {false-command} is the syntax for #if. The kind of brackets are important and tell CMUD whether the contents are an expression or a command - make sure you're using the right kind. Other than that, your commands should work.

Capturing multiline info is a tricky one. The method I usually use works like this:

#trig {line that starts the text} {#t+ capture;MultiLineText=""}
#cond {line that stops the text} {#t- capture}

#trig "capture" {(*)} {#additem MultiLineText %1}

Then you just do "#forall @MultiLineText {#say %i}" or whatever command you want to be done for each line. Sounds like you'll probably want to #send it.

I'm not sure exactly what you want done with the exits. One way saving the exit value for the room would be to save the destination of each exit no matter what it is. You @RoomExits variable will be a stringlist with six members (you can do a %numitems to check it's worked right too). It'll look something like this:

NOWHERE|302:1|NOWHERE|NOWHERE|NOWHERE|NOWHERE

Then when your script does a #forall through those items to write out the vnums for the exits, you do something like this:

$ExitNumber=1
#forall @RoomExits {#if (%i != "NOWHERE") {#send $ExitNumber;#send 1;#send %i};$ExitNumber=$ExitNumber+1}

The strength of the automapper really is the fact that it's a database and can store all this information for you very conveniently. With %roommode set it can also rebuild an exit destination list very simply. But if you find this way easier, I hope those suggestions help.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Wed May 23, 2007 7:53 pm   
 
Okay, given the following is output from the mud:

-- Room number : [12:49]
1) Name : OFFICE
2) Description :
Line 1
Line 2
Line 3
3) Room flags : PEACEFUL
4) Sector type : Inside
5) Exit north : <NOWHERE>
6) Exit east : 12:82
7) Exit south : <NOWHERE>
8) Exit west : <NOWHERE>
9) Exit up : <NOWHERE>
A) Exit down : <NOWHERE>
B) Extra descriptions menu
Q) Quit
Enter choice : q

I would setup the following triggers and variables.
--------------
#trig Room Name : [(%d):(%d)]
#if (%1=302) {#VAR RoomNumber NewZoneName:%2}
#if (%1=303) {#MATH Variable (%2+100);#VAR RoomNumber NewZoneName:@Variable}
#if (%1=304) {#MATH Variable (%2+200);#VAR RoomNumber NewZoneName:@Variable}
--------------
#trig 1) Name : (*)
#VAR RoomName %1
--------------
#trig {2) Description:} {#t+ capture;RoomDesc=""}
#cond {3) Room flags} {#t- capture}

#trig "capture" {(*)} {#additem RoomDesc %1}
--------------
#trig {Exit North : (*)} {#VAR ExitNorth %1}
--------------
#trig {Exit East : (*)} {#VAR ExitEast %1}
--------------
#trig {Exit South : (*)} {#VAR ExitSouth %1}
--------------
#trig {Exit West : (*)} {#VAR ExitWest %1}
--------------
#trig {Exit Up : (*)} {#VAR ExitUp %1}
--------------
#trig {Exit Down : (*)} {#VAR ExitDown %1}
#action <name of writing trigger>

That set of triggers should yield the following variables:
@RoomNumber, @RoomName, @RoomDesc, @ExitNorth, etc.


Then following the progress of the redit utility, the next trigger, #action'ed from the last trigger above, should execute basically as follows?

#send redit @RoomNumber
#send 1
#send @RoomName
#send 2
#send @RoomDesc
#send /fi
#send /s
#send 5 (For north exit)
#send 1 (for Exit to on menu)
#send @ExitNorth
#send 0
(repeat #sends for 6 through A)
#send Q
#send Y
#MATH @Range (@Range+1) - (Assuming manually set @Range of 30200)
#send goto @Range

Last #send should auto repeat to the next room in sequence.

I would still like to define the range so it automatically stops at a designated point like room number 30499

So I assume I should have a #while (@Range<30500) (command to stop trigger looping?), but I'm not sure where to put that or how exactly to write it.
Reply with quote
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Wed May 23, 2007 9:15 pm   
 
I've gotten all the triggers to capture the appropriate information except the multiline capture.

With the multiline capture there are two problems.

As the only constants to use for the trigger are 2) Room Description (followed by text) and 3) Room Flags (to end the capture), they are also getting capture by the trigger. Is there a way to delete the first and last line from the capture?

Also, when I #send @Var to the mud, it also seperates each line of text with '|'. Is there anyway to prevent the '|' from being outputted and just have all the test sent as a single line?
Reply with quote
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Wed May 23, 2007 9:17 pm   
 
Example:

The output text looks like:

("(""2) Description :"| High above Mountain Trail Ave, the supporting
structure for the Rhea Silvia|Monorail shines brightly in the sun. The massive
rail and supporting wall|completely encircle Rhea Silvia, doubling as both the
cities main public|transportation system and as a protective wall guarding the
city from the local|animals of Rhea. To the west is the terminal for the
Monorail, Mountain Trail|Ave continues north toward the mountain range and
south toward the city center. |"3) Room flags : NOBITS"")")

It should look more like:

High above Mountain Trail Ave, the supporting structure for the Rhea Silvia
Monorail shines brightly in the sun. The massive rail and supporting wall
completely encircle Rhea Silvia, doubling as both the cities main public
transportation system and as a protective wall guarding the city from the local
animals of Rhea. To the west is the terminal for the Monorail, Mountain Trail
Ave continues north toward the mountain range and south toward the city center.
Reply with quote
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Wed May 23, 2007 11:35 pm   
 
Actually, just figured out an easier way to copy the room descriptions. I still think that capturing the variables from the redit screen is the easiest (at least for my limited scripting ability) way to handle things like vnum conversion and the actual room exits.

But since the script I have written copies the new room while being IN the old room, it would be simple to add #FIND and #send %roomdesc.
Reply with quote
scottt.m
Beginner


Joined: 03 May 2007
Posts: 18

PostPosted: Thu May 24, 2007 3:06 pm   
 
Success!

The script works and I have successfully moved all three old zones into the new single zone without a glitch!

Thank you for all of your assistance, I wouldn't have been able to complete it without you.

All I need to do now is clean up the script, add some #prompts to help define the range of zones (source and destinations) and possibly convert the script into a module so my other builders can use it as well.

Again, thanks for all of your assistance!
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD General Discussion 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