|
para Beginner
Joined: 14 Sep 2008 Posts: 18
|
Posted: Sun Sep 14, 2008 10:45 am
Code for going through zones |
I am wondering if theres a way to go through every room in one zone using cmud mapper. for example, i would like to go through every room in zone looking for a mob, if i find the mob in one room, i could either #stop or record the roomnum for the mob and go back there. i tried to use the #queue @path %roomnum(%i) and #walk every %roomnum, but since the neighboring roomnumber doesnot mean neighboring rooms in map, i keep getting caught by server saying too many commands in one time.
So does anyone have any idea? or the code?
This is actually about how to get the shortest path to go through every room one by one in the zone.
thanks |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Sun Sep 14, 2008 12:05 pm |
I don't really have any code handy for this, but I can describe the basic method.
The first thing is to set your map to use Slow Mode for speedwalking. This is necessary to allow you to stop walking when you find your target.
Next you want to generate a list of the rooms in the zone. This is done with %mapquery. You can find many examples of how to do the query you want in the forums.
The third thing is to go through the list of rooms looking for those that only have 1 exit. You want to pull them out into a new list. You will then tack the rest of the rooms onto the new list. The reason to do this is that walking to the 'dead end' rooms will walk you through most of the other rooms. The code would look something like
Code: |
list=""
#FORALL $step2List {
#IF (%numitems(%roomexit(%i))=1) {
#ADDITEM list %i
#DELITEM $setp2List %i
}
}
list=%concat(@list,"|",$step2List) |
Fourth start your walking. That is simply #WALK %item(@list,1). As you walk into each room adjust its cost and remove it from the list. This is done with an onRoomEnter event. You don't have to set the cost very high, if all the rooms have a cost of 1 then 10 is plenty to make the mapper pick a different route through the middle rooms. So I would reccommend multiplying the existing costs by 10. You will want to record which rooms you have changed so that you can put them back when your search is finished.
Next you need to have additional walks started. This is done with an onWalkEnd event. All it has to do is issue a walk to the first item in the list, just like the start of step 4. You also have it check for an empty list and turn off the class containing these events.
Finally you want a way to manually stop it. A button or command that turns off the class for the events, restores the room costs to thier original value, and uses #STOP to end any walk that is in progress. I would suggest an alias for this so that it can be used by the empty list check in step 5. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
para Beginner
Joined: 14 Sep 2008 Posts: 18
|
Posted: Sun Sep 14, 2008 7:18 pm |
Thanks for the reply. Im wondering if this is better:
1.#mapquery to get the list of the roomnum in zone, #queue them by the %numsteps from my current position(is there a way to queue list by the %walk(%roomnum) instead of just %roomnum?)
2. #walk to the first one in queue, then for onroomenter event, delitem the roomnum I went through on my way here and the roomnum I'm curretly in, recalculate %numsteps to the rest unvisted rooms, and requeue the list, then repeat this step till the list of roomnum in zone =null.
Thanks. |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Mon Sep 15, 2008 12:00 am |
In order to compute the number of steps you must compute the entire path. By targetting dead ends first you also cover all the 'no outlet' rooms that lead there very quickly. Setting the room cost value as I suggest tend to cuase a different path to be sleected through the middle of zone each time. This leads to very rapid coverage. As all rooms are removed from the search list with any entry this also pushes those rooms that have become disjoitned to the fore. It is the fastest search formula I have thought of in many years of doing such things.
To specifics:
1. You need to use the %mapquery function rather then the command because you want to work directly with the results.
1. You have to use #WALK instead of %walk because you want commands to be sent to the mud.
2. You should never watse time recalculating. Each room in each path will cause the onRoomEnter event, those rooms get removed and only rooms that are not entered are #WALKed to. Applying the removal as well as the cost change causes most rooms in any configuration to be travesed simply by walking to the dead ends. The remainder of rooms will generally be in central locations with 2 exits and between paths to dead ends. The only way to do better is design a route by hand. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
para Beginner
Joined: 14 Sep 2008 Posts: 18
|
Posted: Mon Sep 15, 2008 2:26 am |
Thanks for the reply again.
So my further question is that after I got a list of rooms with only 1 exit, I still need to queue them by the step numbers from current position( cuz my map is huge and one #walk could have over 40 steps, and there may be over 30 rooms with only 1 exit in every zone)
My thought was to use numsteps_for_roomnum as the elements for the room list, sort the string list,then take the number 1 roomnum out of the sorted list every time i walked into a new room.(How do i extract the _roomnum info out of the numsteps_for_roomnum in the queue? or is there better way for just queuing the list without creating variable like numsteps_for_roomnum?) and also, does it really cost a lot of time for cmud to recalculate like 300 %walk paths if I do it on every move?
Also, i dont quite understand about the cost that you mentioned,is it a default room parameter ?
thanks again. |
|
|
|
para Beginner
Joined: 14 Sep 2008 Posts: 18
|
Posted: Mon Sep 15, 2008 5:29 am |
finally got my code:
#find
#var path %mapquery ("name like '%%'")
#ev roomenterevent {#delitem path %roomnum}
list=""
#FORALL @path {
#IF (%numitems(%roomexit(%i))=1) {
elem=100
#add elem %len(%walk(%i))
elem=%concat(@elem,for)
elem=%concat(@elem,%i)
#ADDITEM list @elem
}
}
#sort list
#if (%item(@list,1)=~ "(*)for(*)") {nextroom=%pat(2);}
#walk @nextroom
basically,its going to the rooms with 1 exit firstly and based on current room to find next nearest 1 exit room, when theres no more 1 exit room, it needs to go back to the original path and go through the rest of the rooms.
any idea to improve this? |
|
|
|
|
|