· 6 years ago · May 18, 2019, 10:04 PM
1<?xml version="1.0" encoding="iso-8859-1"?>
2<!DOCTYPE muclient>
3<!-- Saved on Monday, April 26, 2018, 7:21 AM -->
4<!-- MuClient version 4.51 -->
5<!DOCTYPE muclient [
6 <!ENTITY show_vnums "true" >
7 <!ENTITY show_timing "false" >
8 <!ENTITY show_completed "false" >
9 <!ENTITY show_database_mods "true" >
10 <!ENTITY show_other_areas "true" >
11 <!ENTITY show_area_exits "true" >
12 <!ENTITY show_up_down "false" >
13 <!ENTITY speedwalk_prefix "" >
14]>
15<!-- Plugin "AlterAeonMapper" generated by Plugin Wizard -->
16
17<muclient>
18<plugin
19 name="DemonMUSH_Mapper"
20 author="Master Vivi, Endymion, Valour"
21 id="dd07d6dbe73fe0bd02ddb63d"
22 language="Lua"
23 purpose="Shows the mapper for Alter Aeon"
24 save_state="y"
25 date_written="2018-04-26 07:21:01"
26 requires="4.51"
27 version="1.0"
28 >
29
30</plugin>
31
32<aliases>
33
34 <!-- zooming aliases -->
35
36 <alias
37 match="mapper zoom out"
38 enabled="y"
39 sequence="100"
40 omit_from_command_history="y"
41 omit_from_output="y"
42 script="mapper.zoom_out"
43 >
44 </alias>
45
46<alias
47 match="mapper zoom in"
48 enabled="y"
49 sequence="100"
50 omit_from_command_history="y"
51 omit_from_output="y"
52 script="mapper.zoom_in"
53 >
54 </alias>
55<alias
56 match="mapper thisroom"
57 enabled="y"
58 sequence="100"
59 script="show_this_room"
60 regexp="n">
61</alias>
62<alias
63 match="^mapper addnote( .*)?$"
64 regexp="y"
65 enabled="y"
66 sequence="100"
67 send_to="12"
68>
69<send>
70 room_edit_note(nil,nil,Trim("%1"))
71</send>
72</alias>
73<alias
74 match="^mapper next( .*)?$"
75 enabled="y"
76 regexp="y"
77 sequence="100"
78 send_to="12"
79>
80<send>
81mapper.gotoNextResult(Trim("%1"))
82</send>
83</alias>
84
85 <alias
86 match="mapper resume"
87 enabled="y"
88 sequence="100"
89 script="map_resume"
90 >
91
92 </alias>
93 <alias
94 match="go"
95 enabled="y"
96 sequence="100"
97 script="map_resume"
98 >
99
100 </alias>
101 <alias
102 match="mapper stop"
103 enabled="y"
104 sequence="100"
105 script="mapper.cancel_speedwalk"
106 >
107 </alias>
108
109 <!-- show/hide mapper -->
110
111 <alias
112 match="mapper hide"
113 enabled="y"
114 sequence="100"
115 script="mapper.hide"
116 >
117 </alias>
118
119 <alias
120 match="mapper show"
121 enabled="y"
122 sequence="100"
123 script="mapper.show"
124 >
125 </alias>
126<alias
127 match="^mapper help( (.*))?$"
128 enabled="y"
129 regexp="y"
130 script="OnHelp"
131></alias>
132
133<alias
134 match="^mapper updown$"
135 enabled="y"
136 regexp="y"
137 send_to="12"
138>
139<send>
140 mapper.show_up_down = not mapper.show_up_down
141 mapper.draw (current_room)
142</send>
143</alias>
144
145<alias
146 match="^mapper underlines?$"
147 enabled="y"
148 regexp="y"
149 send_to="12"
150>
151<send>
152 NoUnderline_hyperlinks = not NoUnderline_hyperlinks
153 Note("Mapper hyperlinks will " ..(NoUnderline_hyperlinks and "no longer" or "now").." be underlined.")
154 SetVariable("NoUnderline_hyperlinks", NoUnderline_hyperlinks and "1" or "0")
155</send>
156</alias>
157 <alias
158 match="mapper goto *"
159 enabled="y"
160 sequence="100"
161 script="map_goto"
162 >
163 </alias>
164<alias
165 match="mapper find *"
166 enabled="y"
167 sequence="100"
168 script="map_find"
169 regexp="n"
170></alias>
171<alias
172 match="mapper findpath * *"
173 enabled="y"
174 sequence="100"
175 omit_from_output="y"
176 script="findpathfast"
177></alias>
178
179 <alias
180 match="mapper where *"
181 enabled="y"
182 sequence="100"
183 script="map_where"
184 >
185 </alias>
186 <alias
187 match="mapper backup"
188 enabled="y"
189 sequence="100"
190 script="backup_db"
191 >
192 </alias>
193 <alias
194 match="^mapper delete room (\d+)$"
195 enabled="y"
196 regexp="y"
197 script="delete_room_alias"
198>
199</alias>
200<alias
201 match="^mapper delete area (.+)$"
202 enabled="y"
203 regexp="y"
204 script="delete_area_alias"
205>
206</alias>
207
208
209<alias
210 match="^mapper flag (.*)$"
211 enabled="y"
212 regexp="y"
213 sequence="100"
214 script="updateRoomInfo">
215</alias>
216
217
218<alias
219match="UpdateTownSpecial"
220enabled="n"
221sequence="100"
222>
223<send>
224where shops | prefix {Where Shop}
225where banks | prefix {Where Bank}
226where teachers | prefix {Where Teacher}
227where guildmasters | prefix {Where Guildmaster}
228where employers | prefix {Where Employer}
229where priests | prefix {Where Priest}
230where forges | prefix {Where Forge}
231</send>
232</alias>
233
234</aliases>
235
236
237<!-- Triggers -->
238
239<triggers>
240 <trigger
241 enabled="n"
242 match="^kxwt\_waypoint$"
243 omit_from_log="y"
244 omit_from_output="y"
245 regexp="y"
246 send_to="14"
247 sequence="100"
248 >
249<send>waypointtoggle()</send>
250 </trigger>
251 <trigger
252 enabled="y"
253 match="kxwt_rshort *"
254 name="process_room_name"
255 sequence="100"
256 send_to="14"
257 >
258 <send>
259 name="%1"
260 if rooms ~= nil and
261 rooms[uid] ~= nil and
262 rooms[uid].notes ~= nil and
263 rooms[uid].notes ~= ""
264 then
265 mapper.mapprint("Note:", rooms[uid].notes)
266 end
267 </send>
268 </trigger>
269 <trigger
270 enabled="y"
271 match="kxwt_rvnum * * * * * * *"
272 name="process_room_desc"
273 sequence="100"
274 script="room_number"
275 >
276 </trigger>
277 <trigger
278 enabled="y"
279 match="kxwt_walkdir *"
280 name="moved_direction"
281 sequence="100"
282 script="moved_direction"
283 >
284 </trigger>
285 <trigger
286 enabled="y"
287 match="kxwt_terrain *"
288 name="process_terrain"
289 sequence="100"
290 send_to="14"
291 >
292 <send>terrain="%1"</send>
293 </trigger>
294 <trigger
295 enabled="y"
296 match="kxwt_area * *"
297 name="process_area"
298 sequence="100"
299 send_to="14"
300 >
301 <send>area="%2"</send>
302 </trigger>
303 <trigger
304 enabled="y"
305 match="[Exits: *]"
306 name="Exits_Line"
307 sequence="100"
308 send_to="14"
309 >
310 <send>process_exits("%1")</send>
311 </trigger>
312 <trigger
313 enabled="y"
314 match="Alas, you cannot go that way."
315 script="mapper.cancel_speedwalk"
316 sequence="100"
317 ></trigger>
318 <trigger
319 enabled="y"
320 match="* would be left behind."
321 script="mapper.cancel_speedwalk"
322 sequence="100"
323 ></trigger>
324 <trigger
325 enabled="y"
326 match="You are too exhausted to continue your stealthy movement!"
327 script="mapper.cancel_speedwalk"
328 sequence="100"
329 ></trigger>
330 <trigger
331 enabled="y"
332 match="You are too exhausted."
333 script="mapper.cancel_speedwalk"
334 sequence="100"
335 ></trigger>
336 <trigger
337 enabled="y"
338 match="You follow * *."
339 script="mapper.cancel_speedwalk"
340 sequence="100"
341 ></trigger>
342 <trigger
343 enabled="y"
344 match="You'll have to climb to go there."
345 script="mapper.cancel_speedwalk"
346 sequence="100"
347 ></trigger>
348 <trigger
349 enabled="y"
350 match="You can't just walk away from a fight!"
351 script="mapper.cancel_speedwalk"
352 sequence="100"
353 ></trigger>
354 <trigger
355 enabled="y"
356 match="The * is closed."
357 script="mapper.cancel_speedwalk"
358 sequence="100"
359 ></trigger>
360 <trigger
361 enabled="y"
362 match="* blocks your path, preventing you from passing."
363 script="mapper.cancel_speedwalk"
364 sequence="100"
365 ></trigger>
366 <trigger
367 enabled="y"
368 match="^The (door|gate) is closed\.$"
369 regexp="y"
370 name="Door_Closed"
371 script="Door_Closed"
372 sequence="100"
373 >
374 </trigger>
375 <trigger
376 enabled="y"
377 match="The wooden door is closed."
378 regexp=""
379 name="woodendoor_closed"
380 script="Door_Closed"
381 sequence="100"
382 >
383 </trigger>
384<trigger
385 enabled="y"
386 match="^{Where (.*)}\w{1,2}(?:.*->)?\s+(.*)$"
387 regexp="y"
388 name="InfoUpdate"
389 script="updateRoomInfo"
390 sequence="100"
391>
392</trigger>
393</triggers>
394
395<!-- Timers -->
396
397<timers>
398 <timer
399 name="backup_timer"
400 enabled="y"
401 script="backup_db"
402 hour="1" minute="01" second="59"
403 active_closed="y" >
404 </timer>
405</timers>
406
407<!-- Script -->
408
409
410<script>
411local show_other_areas = &show_other_areas;
412<![CDATA[
413
414mapper = require "altermapper"
415require "serialize"
416require "copytable"
417uid = -999
418current_room=nil
419current_area = -999
420expected_exit=-666
421from_room=""
422last_direction_moved=nil
423terrain = 0
424area = "<No area>"
425last_backup = GetVariable("last_backup") or 0
426notes = 0
427default_width = 269
428default_height = 335
429local posx = 100
430local posy = 100
431local DIFFERENT_AREA_COLOUR = "#ff0000"
432areaname = -999
433last_direction_moved = nil
434OUR_ROOM_COLOUR = GetVariable("OUR_ROOM_COLOUR") or "0x0000FF"-- color of room border
435
436
437count = 0
438roomcount = 0
439rooms = {}
440local user_terrain_colour = {}
441
442local kxwt_dirs = {
443 ["0"] = "n",
444 ["2"] = "s",
445 ["4"] = "ne",
446 ["6"] = "sw",
447 ["5"] = "se",
448 ["7"] = "nw",
449 ["3"] = "w",
450 ["1"] = "e",
451 ["20"] = "u",
452 ["30"] = "d",
453 ["99"] = "unk" -- idk what to do here (nothing?) (i'm not sure either, maybe wait till it happens and you can duplicate it)
454}
455
456valid_direction = {
457n = "n",
458s = "s",
459e = "e",
460w = "w",
461u = "u",
462d = "d",
463ne = "ne",
464sw = "sw",
465nw = "nw",
466no="n",
467ea="e",
468so="s",
469we="w",
470se = "se",
471north = "n",
472south = "s",
473east = "e",
474west = "w",
475up = "u",
476down = "d",
477northeast = "ne",
478northwest = "nw",
479southeast = "se",
480southwest = "sw",
481['in'] = "in",
482out = "out",
483} -- end of valid_direction
484
485
486terrain_color = {}
487
488-----------------------------------------
489-- ADDING TRIGGER STUFF
490-----------------------------------------
491
492function room_number(name, line, args)
493 uid = args[1] -- this was in the <send> previously
494 from_room = current_room or ""
495 current_room = args[1]
496end
497
498function moved_direction(name, line, args)
499 last_direction_moved = kxwt_dirs[args[1]] or "unk"
500end
501
502------------------------------------------
503--Update Town Special Procedure
504------------------------------------------
505
506function updateRoomInfo(name, line, wildcards)
507 local roomtype, roomuid, matchFound, room = wildcards[1], current_room or 0,
508 false, ""
509 print("Locals set")
510 print(#wildcards)
511 if #wildcards > 1 then room = wildcards[2] else room = rooms[roomuid].name
512 end
513 print("Wildcards set")
514
515
516 if room then
517 for i,v in pairs(rooms) do
518 if v.name == Trim(room) then
519 roomuid = i
520 matchFound = true
521 break
522 end
523 end
524 else
525 matchFound = true
526 end
527
528 if matchFound == true then
529 if not rooms[roomuid].info then
530 rooms[roomuid].info = roomtype
531 else
532 if not string.find(rooms[roomuid].info, roomtype) then
533 rooms[roomuid].info = rooms[roomuid].info .. " " .. roomtype
534 add_update_room(roomuid, rooms[roomuid])
535 end
536 end
537 mapper.draw(roomuid)
538 else
539 print("Room not mapped!")
540 end
541end
542
543-----------------------------------------
544-- DONE ADDING TRIGGER STUFF
545-----------------------------------------
546
547function room_edit_note(room, vuid, newnotes)
548 if vuid == nil and current_room ~= nil then
549 vuid = current_room
550 room = rooms[vuid]
551 end
552
553 if vuid == nil then -- still nothing?
554 print("No room received from the mud yet. Try using the 'LOOK' command first.")
555 return
556 end
557
558 if newnotes == nil or newnotes == "" then
559 if room.notes ~= nil and room.notes ~= "" then
560 newnotes = utils.inputbox("Modify room comment (clear it to delete from database)", room.name, room.notes)
561 else
562 newnotes = utils.inputbox("Enter room comment (creates a note for this room)", room.name, room.notes)
563 end -- if
564 end
565
566 if not newnotes then
567 return
568 end -- if cancelled
569
570 if newnotes == "" then
571 if room.notes == nil or room.notes == "" then
572 mapper.mapprint("No comment entered, note not saved.")
573 return
574 else
575 mapper.mapprint("Note from room " .. current_room .. " deleted. Was previously: " .. room.notes)
576 rooms[current_room].notes = ""
577 add_update_room(current_room, rooms[current_room])
578 mapper.draw(current_room)
579 end
580 end
581
582 if rooms[current_room].notes == newnotes then
583 return -- no change made
584 end
585
586 local oldNote = room.note
587
588 rooms[current_room].notes = newnotes
589 add_update_room(current_room, rooms[current_room])
590 mapper.draw(current_room)
591
592 if oldNote ~= nil and #oldNote > 0 then
593 mapper.mapprint("Note for room", current_room, "changed to:", newnotes)
594 else
595 mapper.mapprint("Note added to room", current_room, ":", newnotes)
596 end
597end
598
599
600-- -----------------------------------------------------------------
601-- Here on "Exits:" line ----- we have changed rooms
602-- -----------------------------------------------------------------
603
604function process_exits (exits_str)
605 --Note("process exits")
606 if current_room == from_room then
607 --Note(current_room, ", ", from_room)
608 --Note("same room")
609 --return
610 end
611
612 -- genereate a "room ID" by hashing the room name, description and exits
613 -- break up exits into individual directions
614 exits = {}
615
616 for exit in string.gmatch (exits_str, "%w+") do
617 local ex = valid_direction [exit]
618 if ex then
619 exits [ex] = "-666" -- don't know where it goes yet
620 end -- if
621 end -- for
622
623 -- add to table if not known
624 --Note("add room to table")
625 if not rooms [uid] then
626 rooms [uid] = { name = name, desc = uid, exits = exits, area=area, fillcolour=terrain_color[terrain], fillbrush=0, bordercolour=0xffffff }
627 add_update_room(uid, rooms[uid])
628 end -- if
629
630 -- save so we know current room later on
631 current_room = uid
632
633 -- add exit into mapper
634 --Note("add exit")
635 if from_room ~= "" and last_direction_moved then -- we were in a room # that we got from kxwt, and then moved to another room
636 --Note("rooms[", from_room, "].exits[", last_direction_moved, "] = ", current_room)
637 rooms[from_room].exits[last_direction_moved] = current_room
638 add_update_room(from_room, rooms[from_room])
639 last_direction_moved = nil -- remove last direction so updating a room only happens when we walk somewhere
640 end
641
642 -- call mapper to draw this room
643 mapper.draw (uid)
644
645end -- process_exits
646
647-- -----------------------------------------------------------------
648-- Here on white coloured line - this is a room name or room exits
649-- -----------------------------------------------------------------
650
651function Name_Or_Exits (name, line, wildcards)
652
653 exits = string.match (line, "^Exits: (.*)")
654
655 if exits then
656 process_exits (exits)
657 end -- if
658
659 roomname = line
660 roomdesc = nil
661 areaname = 0
662
663end -- Name_Or_Exits
664
665-- -----------------------------------------------------------------
666-- Here on yellow line - part of room description
667-- -----------------------------------------------------------------
668
669function Name_Line (name, line, wildcards)
670 roomdesc = (roomdesc or "" ) .. line .. "\n"
671end -- Name_Or_Exits
672-- -----------------------------------------------------------------
673-- for converting things like ^ $ * etc. into "escaped" sequences
674-- -----------------------------------------------------------------
675function fix_regexp_magic_characters (r)
676 return string.gsub (r, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%1")
677end -- fix_regexp_magic_characters
678
679-- -----------------------------------------------------------------
680-- mapper 'get_room' callback - it wants to know about room uid
681-- -----------------------------------------------------------------
682
683function get_room (uid)
684
685
686 if not rooms [uid] then
687 return nil
688 end -- if
689
690 local room = copytable.deep (rooms [uid])
691 local notes = ""
692 if room.notes and room.notes ~= "" then
693 notes = "\nNote: " .. room.notes
694 end -- if notes
695
696 local texits = {}
697 for dir in pairs (room.exits) do
698 table.insert (texits, dir)
699 end -- for
700 table.sort (texits)
701
702 if uid == current_room then
703 current_area = room.area
704 end -- if
705
706 room.hovermessage = string.format (
707"%s\tExits: %s\nRoom: %s\nArea: %s \nTerrain: %s%s",
708 room.name,
709 table.concat (texits, ", "),
710 uid,
711 area,
712 terrain,
713 notes
714 -- depth,
715 -- table.concat (path, ",")
716 )
717
718
719 -- SPECIAL ROOM COLOUR FILLS
720special_room = false
721 if room.info and room.info ~= "" then
722 if string.match (room.info, "waypoint") then
723 special_room = true
724 elseif string.match (room.info, "bank") then
725 special_room = true
726 elseif string.match (room.info, "alchemyguild") then
727 special_room = true
728 elseif string.match (room.info, "teacher") then
729 special_room = true
730 elseif string.match (room.info, "employer") then
731 special_room = true
732 elseif string.match (room.info, "priest") then
733 special_room = true
734 elseif string.match (room.info, "forge") then
735 special_room = true
736 elseif string.match (room.info, "warriortrainer") then
737 special_room = true
738 elseif string.match (room.info, "thieftrainer") then
739 special_room = true
740 elseif string.match (room.info, "druidtrainer") then
741 special_room = true
742 elseif string.match (room.info, "clerictrainer") then
743 special_room = true
744 elseif string.match (room.info, "magetrainer") then
745 special_room = true
746 elseif string.match (room.info, "necromancertrainer") then
747 special_room = true
748 elseif string.match (room.info, "rangertrainer") then
749 special_room = true
750
751 end
752end -- if
753 if uid == current_room and special_room then
754 room.bordercolour = mapper.OUR_ROOM_COLOUR.colour
755 room.borderpenwidth = 3
756 elseif room.area ~= current_area then
757 room.bordercolour = ColourNameToRGB "red"
758 end -- not in this area
759 return room
760
761
762end -- get_room
763
764function show_this_room (name, line, wildcards)
765 local room = rooms[current_room]
766 if room ~= nil then
767 Note("Details about this room:")
768 Note("+---------------------------+")
769 Note("Name: "..(name or ""))
770 Note("ID: "..(uid or ""))
771 Note("Area: "..(area or ""))
772 Note("Terrain: "..(terrain or ""))
773 Note("Info: "..(room.info or ""))
774 Note("Notes: "..(room.notes or ""))
775 Note("Exits: "..(room.exits or ""))
776else
777 Note("THISROOM ERROR: You need to type 'LOOK' first to initialize the mapper before trying to get room information.")
778 end
779end -- show_this_room
780
781function our_room_colour ()
782 local clr = PickColour(ColourNameToRGB(OUR_ROOM_COLOUR) or 0x000000)
783 if clr ~= -1 then
784 OUR_ROOM_COLOUR = RGBColourToName(clr)
785 SaveState()
786 end
787end
788
789
790function room_click (uid, flags)
791
792 -- check we got room at all
793 if not uid then
794 return nil
795 end -- if
796
797 -- look it up
798 local room = rooms [uid]
799
800 -- not cached - see if in database
801 if not room then
802return
803 end -- not in cache
804
805 if not room then
806 return
807 end -- if still not there
808
809 local function checkmark (which)
810 if rooms [uid] [which] then
811 return "+"
812 else
813 return ""
814 end -- if
815 end -- checkmark
816
817
818 local handlers = {
819 { name = "Edit bookmark", func = room_edit_bookmark} ,
820 { name = "-", } ,
821 { name = "Add Exit", func = room_add_exit} ,
822 { name = "Change Exit", func = room_change_exit} ,
823 { name = "Delete Exit", func = room_delete_exit} ,
824 { name = "-", } ,
825 { name = checkmark ("shop") .. "Shop", func = room_toggle_shop } ,
826 { name = checkmark ("train") .. "Trainer", func = room_toggle_train } ,
827 { name = checkmark ("inn") .. "Inn", func = room_toggle_inn } ,
828 { name = checkmark ("guild") .. "Guildmaster", func = room_toggle_guild } ,
829 { name = "-", } ,
830 { name = "Current Room Border Color", func = our_room_colour} ,
831 } -- handlers
832
833 local t, tf = {}, {}
834 for _, v in pairs (handlers) do
835 table.insert (t, v.name)
836 tf [v.name] = v.func
837 end -- for
838
839 local choice = WindowMenu (mapper.win,
840 WindowInfo (mapper.win, 14),
841 WindowInfo (mapper.win, 15),
842 table.concat (t, "|"))
843
844 local f = tf [choice]
845
846 if f then
847 f (room, uid)
848 end -- if handler found
849
850end -- room_click
851
852
853
854
855
856-- -----------------------------------------------------------------
857-- map_find: mapper find xxx
858-- -----------------------------------------------------------------
859function map_find (name, line, wildcards)
860
861 mapper.mapprint (string.rep ("-", 25) .. " Mapper search " .. string.rep ("-", 25))
862
863 local reset = ANSI (0)
864 local bold = ANSI (1)
865 local unbold = ANSI (22)
866
867 local matches = { }
868 local count = 0
869 local target = Trim (wildcards [1]:lower ())
870
871 if target == "" then
872 mapper.maperror ("No search string specified")
873 return
874 end -- if
875
876 if not mapper.check_we_can_find () then
877 return
878 end -- if find not OK
879
880 -- fix up any regular expression "magic" letters to be escaped by a %
881 local fixed_target = fix_regexp_magic_characters (target)
882
883 -- fix up for caseless searches in the room description (eg. "a" becomes "[aA]")
884 local caseless_target = string.gsub (fixed_target, "(%a)", function (a)
885 return "[" .. a:lower () .. a:upper () .. "]"
886 end -- function
887 )
888
889 -- do a simple string search to find matching rooms
890 for k, v in pairs (rooms) do
891
892 -- don't want nil descriptions
893 if not v.description then
894 v.description = ""
895 end -- if no description
896
897 if string.find (v.name:lower (), fixed_target) or
898 string.find (v.description:lower (), fixed_target) then
899 matches [k] = true
900 count = count + 1
901 end -- if match
902 end -- for each room
903
904 local function show_snippet (uid)
905 local room = rooms [uid]
906 if not room then
907 return
908 end -- if
909
910 -- don't bother if the wanted words was in the room name
911 if string.find (room.name:lower (), fixed_target) then
912 return
913 end -- if
914
915 -- otherwise show the wanted word in the description, in bold
916 AnsiNote (reset .. string.gsub (room.description, caseless_target, bold .. "%1" .. unbold))
917
918 end -- show_snippet
919
920 -- see if nearby
921 mapper.find (
922 function (uid)
923 local room = matches [uid]
924 if room then
925 matches [uid] = nil
926 end -- if
927 return room, next (matches) == nil
928 end, -- function
929 show_vnums, -- show vnum?
930 count, -- how many to expect
931 false, -- don't auto-walk
932 show_snippet -- show find snippet
933 )
934end -- map_find
935
936
937
938-- -----------------------------------------------------------------
939-- map_goto for: mapper goto xxx
940-- -----------------------------------------------------------------
941function map_goto (name, line, wildcards)
942 local wanted = wildcards [1]
943 -- check valid string
944 if string.match (wanted, "%D") then
945 mapper.maperror ("Room number must be numeric, you entered: " .. wanted)
946 return
947 end -- if
948
949 -- see if already there
950 if current_room and string.match (current_room, "^" .. wanted) then
951 mapper.mapprint ("You are already in that room.")
952 return
953 end -- if
954 -- find desired room
955 mapper.find (
956 function (uid)
957 local found = string.match (uid, "^" .. wanted)
958 return found, found
959 end, -- function
960 show_vnums, -- show vnum?
961 1, -- how many to expect
962 true -- just walk there
963 )
964end -- map_goto
965
966function map_resume (name, line, wildcards)
967
968 local wanted = mapper.last_hyperlink_uid or mapper.last_speedwalk_uid
969
970 if not wanted then
971 mapper.print "No outstanding speedwalks or hyperlinks."
972 return
973 end -- if nothing to do
974
975 -- find desired room
976 mapper.find (
977 function (uid)
978 return uid == wanted, uid == wanted
979 end, -- function
980 show_vnums, -- show vnum?
981 1, -- how many to expect
982 true -- just walk there
983 )
984
985end -- map_resume
986
987-- -----------------------------------------------------------------
988-- map_where: Show where a room is
989-- -----------------------------------------------------------------
990function map_where (name, line, wildcards)
991 if not mapper.check_we_can_find () then
992 return
993 end -- if
994 local wanted = wildcards [1]
995 if current_room and wanted == current_room then
996 mapper.mapprint ("You are already in that room.")
997 return
998 end -- if
999 local paths = mapper.find_paths (current_room,
1000 function (uid)
1001 return uid == wanted, -- wanted room?
1002 uid == wanted -- stop searching?
1003 end)
1004 local uid, item = next (paths, nil) -- extract first (only) path
1005 -- nothing? room not found
1006 if not item then
1007 mapper.mapprint (string.format ("Room %s not found", wanted))
1008 return
1009 end -- if
1010 -- turn into speedwalk
1011 local path = mapper.build_speedwalk (item.path)
1012 -- display it
1013 mapper.mapprint (string.format ("Path to %s is: %s", wanted, path))
1014end -- map_where
1015
1016-- -----------------------------------------------------------------
1017-- cannot_walk - we tried to walk but failed
1018-- -----------------------------------------------------------------
1019function cannot_walk (name, line, wildcards)
1020 mapper.cancel_speedwalk ()
1021 room_description = nil
1022 current_exits = nil
1023 room_name = nil
1024 last_direction_moved = nil
1025-- mapper.mapprint ("Attempt to walk cancelled.")
1026
1027end -- cannot_walk
1028
1029function confirm_delete_area(a)
1030 response = utils.umsgbox("Delete area: "..a.."?", "Delete Area", "okcancel", "?", 2)
1031 if response == "ok" then
1032 delete_area(a)
1033 end
1034end
1035
1036function Door_Closed (name, line, wildcards)
1037
1038local dirs = {
1039 n = "north",
1040 s = "south",
1041 e = "east",
1042 w = "west",
1043 u = "up",
1044 d = "down",
1045 ne = "northeast",
1046 sw = "southwest",
1047 nw = "northwest",
1048 se = "southeast",
1049 ['in'] = "in",
1050 out = "out",
1051 } -- end of available
1052
1053 if last_direction_moved then
1054 Send ("open " .. dirs [last_direction_moved])
1055 Send (dirs [last_direction_moved])
1056 end -- if
1057
1058end -- Door_Closed
1059
1060
1061-- -----------------------------------------------------------------
1062-- check_for_cannot_go - look up the line in a table of failure messages
1063-- see table: cannot_move_messages
1064-- -----------------------------------------------------------------
1065function check_for_cannot_go (name, line, wildcards)
1066
1067 for _, v in ipairs (cannot_move_messages) do
1068 if string.find (line, v) then
1069 cannot_walk ()
1070 break
1071 end -- if match
1072 end -- for each message
1073end -- check_for_cannot_go
1074
1075function findpathfast(name, line, wildcards)
1076 local src = wildcards[1]
1077 local dest = wildcards[2]
1078 rooms[src] = load_room_from_database(src)
1079 rooms[dest] = load_room_from_database(dest)
1080
1081 if rooms[src] == nil then
1082 mapper.mapprint (string.format ("Room %s not known.", src))
1083 end
1084 if rooms[dest] == nil then
1085 mapper.mapprint (string.format ("Room %s not known.", dest))
1086 end
1087 if rooms[src] == nil or rooms[dest] == nil then
1088 return
1089 end
1090
1091 local foundpath = findpath(src, dest)
1092 if foundpath == nil then
1093 mapper.mapprint (string.format ("Path from %s to %s not found.", wildcards[1], wildcards[2]))
1094 return
1095 end
1096
1097 -- turn into speedwalk
1098 local speedwalk = mapper.build_speedwalk (foundpath, speedwalk_prefix)
1099
1100 -- display it
1101 if speedwalk ~= nil then
1102 mapper.mapprint (string.format ("Path from %s to %s is: %s", wildcards[1], wildcards[2], speedwalk))
1103 else
1104 mapper.mapprint ("Pick different start and end rooms.")
1105 end
1106end
1107
1108function blackindigoPrint(msg)
1109 ColourNote("blueviolet","black",msg)
1110end
1111function blackredPrint(msg)
1112 ColourNote("black","red",msg)
1113end
1114function whiteindigoPrint(msg)
1115 ColourNote("white","indigo",msg)
1116end
1117
1118
1119function setup_terrain_colors()
1120terrain_color["0"]=tonumber("0x000000")--NOTSET
1121terrain_color["1"]=tonumber("0x606060")--Building
1122terrain_color["2"]=tonumber("0x805a22")--Town
1123terrain_color["3"]=tonumber("0x00ff00")--FIELD
1124terrain_color["4"]=tonumber("0x00c000")--LFOREST
1125terrain_color["5"]=tonumber("0x008000")--TFOREST
1126terrain_color["6"]=tonumber("0x004000")--DFOREST
1127terrain_color["7"]=tonumber("0x406080")--SWAMP
1128terrain_color["8"]=tonumber("0x60a060")--PLATEAU
1129terrain_color["9"]=ColourNameToRGB("khaki")--SANDY
1130terrain_color["10"]=tonumber("0xc0c0c0")--MOUNTAIN
1131terrain_color["11"]=tonumber("0x808080")--ROCK
1132terrain_color["12"]=ColourNameToRGB("burlywood")--DESERT
1133terrain_color["13"]=tonumber("0x805080")--TUNDRA
1134terrain_color["14"]=ColourNameToRGB("lightyellow")--BEACH
1135terrain_color["15"]=tonumber("0x409040")--HILL
1136terrain_color["16"]=ColourNameToRGB("navajowhite")--DUNES
1137terrain_color["17"]=tonumber("0x20c040")--JUNGLE
1138terrain_color["18"]=ColourNameToRGB("darkblue")--OCEAN
1139terrain_color["19"]=tonumber("0x00f0f0")--STREAM
1140terrain_color["20"]=ColourNameToRGB("blue")--RIVER
1141terrain_color["21"]=tonumber("0x021e6c")--UNDERWATER
1142terrain_color["22"]=tonumber("0x303030")--UNDERGROUND
1143terrain_color["23"]=ColourNameToRGB("lightskyblue")--AIR
1144terrain_color["24"]=tonumber("0x82f8e6")--ICE
1145terrain_color["25"]=ColourNameToRGB("red")--LAVA
1146terrain_color["26"]=tonumber("0x806060")--RUINS
1147terrain_color["27"]=tonumber("0x404040")--CAVE
1148terrain_color["28"]=tonumber("0x907040")--CITY
1149terrain_color["29"]=tonumber("0x20a060")--MARSH
1150terrain_color["30"]=tonumber("0xf0f0a0")--WASTELAND
1151terrain_color["31"]=tonumber("0xffffff")--CLOUD
1152terrain_color["32"]=ColourNameToRGB("blue")--WATER
1153terrain_color["33"]=tonumber("0x808080")--METAL
1154terrain_color["34"]=tonumber("0x006000")--TAIGA
1155terrain_color["35"]=tonumber("0x404040")--SEWER
1156terrain_color["36"]=ColourNameToRGB("indigo")--SHADOW
1157terrain_color["37"]=ColourNameToRGB("indigo")--CATACOMB
1158terrain_color["38"]=ColourNameToRGB("olivedrab")--MIRE
1159terrain_color["39"]=ColourNameToRGB("indigo")--CRYSTAL
1160 -- end of terrain_color
1161end
1162
1163-- -----------------------------------------------------------------
1164-- Plugin Install
1165-- -----------------------------------------------------------------
1166
1167function OnPluginInstall ()
1168
1169 config = {} -- in case not found
1170 setup_terrain_colors()
1171
1172 -- get saved configuration
1173 assert (loadstring (GetVariable ("config") or "")) ()
1174
1175 -- and rooms
1176 --assert (loadstring (GetVariable ("rooms") or "")) ()
1177
1178 -- new stuff for sql data
1179 check_create_db()
1180 load_rooms()
1181
1182 -- initialize mapper
1183
1184 mapper.init { config = config,
1185 get_room = get_room, findpath = findpath,
1186 room_click = room_click, -- called on RH click on room square,
1187 show_help = OnHelp, -- to show help,
1188 show_other_areas = show_other_areas, -- want to see areas other than the current one?
1189}
1190 mapper.mapprint (string.format ("MUSHclient mapper installed, version %0.1f", mapper.VERSION))
1191
1192
1193end -- OnPluginInstall
1194
1195function OnHelp (name, line, wildcards)
1196 local help_header = " [Demon Mush Mapper Help] "
1197
1198 local help_index = [[
1199 Mapper Help Index
1200=============================================================================
1201 mapper help --> Show this list
1202-----------------------------------------------------------------------------
1203 mapper help config --> Commands for configuring the mapper
1204 mapper help moving --> Commands for moving between rooms
1205 mapper help utils --> Other utilitarian commands
1206 mapper help searching --> Used for finding notes, shops, guildmasters, etc
1207=============================================================================
1208]]
1209 local help_table = {
1210 ['config'] = {
1211['header'] = [[===== CONFIGURATION =============>]],
1212[[mapper help --> This help
1213 > (or click the "?" button on the top right)]],
1214[[mapper zoom out --> Zoom out]],
1215[[mapper zoom in --> Zoom in]],
1216[[mapper hide --> Hide map]],
1217[[mapper show --> Show map]],
1218[[mapper updown --> Toggle up/down exit drawing]],
1219[[mapper underlines --> Toggle underlining of clickable links]]
1220},
1221
1222 ['utils'] = {
1223['header'] = [[===== UTILITIES =================>]],
1224[[mapper backup --> Creates a backup of the mapper database]],
1225[[mapper addnote --> Add a new note to the current room]],
1226[[mapper addnote <note> --> Ditto, but skips the dialog]]
1227},
1228 ['searching'] = {
1229['header'] = [[===== SEARCHING =================>]],
1230[[mapper find <text> --> Full-text search the whole database]],
1231[[]],
1232[[mapper notes --> Show nearby rooms that you marked with notes]],
1233[[mapper notes <here/area> --> Ditto]],
1234[[mapper shops --> Show all shops/banks]],
1235[[mapper shops <here/area> --> Ditto]],
1236[[mapper train --> Show all trainers]],
1237[[mapper train <here/area> --> Ditto]],
1238[[mapper quest --> Show all quest-givers]],
1239[[mapper quest <here/area> --> Ditto]],
1240[[]],
1241[[mapper next --> Visit the next room in the most recent
1242 > list of results.]],
1243[[mapper next <index> --> Ditto, but skip to the given result index.]],
1244[[mapper where <room id> --> Show directions to a room number]]
1245},
1246
1247
1248 ['moving'] = {
1249['header'] = [[===== MOVING ====================>]],
1250[[mapper goto <room id> --> Run to a room by its room number]]
1251}
1252}
1253
1254 local function show_help(helps)
1255 blackindigoPrint("")
1256 blackindigoPrint(helps['header'])
1257 blackindigoPrint("")
1258 for i,v in ipairs(helps) do
1259 blackindigoPrint(v)
1260 end
1261 end
1262
1263 blackindigoPrint("")
1264 whiteindigoPrint(help_header)
1265 blackindigoPrint("+---------------------------------------------------------------------------+")
1266 badnews = true
1267 if wildcards and wildcards[2] ~= "" then
1268 badnews = false
1269 if wildcards[2] == "all" then
1270 show_help(help_table['config'])
1271 show_help(help_table['exits'])
1272 show_help(help_table['searching'])
1273 show_help(help_table['moving'])
1274 show_help(help_table['utils'])
1275 elseif wildcards[2] == "config" then
1276 show_help(help_table['config'])
1277 elseif wildcards[2] == "searching" then
1278 show_help(help_table['searching'])
1279 elseif wildcards[2] == "moving" then
1280 show_help(help_table['moving'])
1281 elseif wildcards[2] == "utils" then
1282 show_help(help_table['utils'])
1283 elseif wildcards[2]:find("search ") == 1 then
1284 local st, en = wildcards[2]:find("search ")
1285 local pattern = Trim(wildcards[2]:sub(en+1))
1286 ColourTell("cornflower","black","Searching help for: ")
1287 ColourNote("red","black",pattern)
1288 if pattern ~= "" then
1289 for k,v in pairs(help_table) do
1290 local done_header = false
1291 for j,w in ipairs(v) do
1292 if (w ~= "") and (w:find("--------",nil,true) == nil) and (w:find(pattern) ~= nil) then
1293 if not done_header then
1294 blackindigoPrint("")
1295 blackindigoPrint(v['header'])
1296 done_header = true
1297 end
1298 blackindigoPrint("")
1299 local wtable = w:split(pattern)
1300 for i,v in ipairs(wtable) do
1301 ColourTell("cornflower","black",v)
1302 if (i < #wtable) then
1303 ColourTell("red", "black", pattern)
1304 end
1305 end
1306 Note("")
1307 end
1308 end
1309 end
1310 else
1311 badnews = true
1312 end
1313 else
1314 badnews = true
1315 end
1316 end
1317 if badnews then
1318 blackindigoPrint("")
1319 mapper.mapprint (world.GetPluginInfo (world.GetPluginID (), 3))
1320 blackindigoPrint("")
1321 blackindigoPrint(help_index)
1322 end
1323 blackindigoPrint("")
1324 blackindigoPrint("+---------------------------------------------------------------------------+")
1325 blackindigoPrint("")
1326end
1327
1328
1329-- -----------------------------------------------------------------
1330-- Plugin Save State
1331-- -----------------------------------------------------------------
1332
1333function OnPluginSaveState ()
1334 mapper.save_state ()
1335 SetVariable ("config", "config = " .. serialize.save_simple (config))
1336 SetVariable("last_backup", last_backup)
1337SetVariable("OUR_ROOM_COLOUR", OUR_ROOM_COLOUR) -- Color of Room Border
1338end -- OnPluginSaveState
1339
1340------------------------------------------
1341-- start of sql additions
1342------------------------------------------
1343function delete_room_alias(name, line, wildcards)
1344 local num = wildcards[1]
1345 if num then
1346 delete_room(num)
1347 end
1348end
1349
1350function delete_area_alias(name, line, wildcards)
1351 local a = wildcards[1]
1352 if a then
1353 delete_area(a)
1354 end
1355end
1356
1357function delete_room(num) -- delete room from rooms
1358 for r, tbl in pairs(rooms) do -- for each room in table
1359 if tostring(r) == tostring(num) then
1360 rooms[r] = nil -- setting table item to nil deletes it
1361 end
1362 end
1363 run_sql([[DELETE FROM rooms WHERE uid = ']]..num..[[']])
1364 Note("Deleted ", num, ".")
1365 SendNoEcho("look")
1366end
1367
1368function delete_area(a)
1369 local cnt = 0
1370 for r, tbl in pairs(rooms) do -- for each room in table
1371 if tostring(tbl.area) == tostring(a) then
1372 rooms[r] = nil -- setting table item to nil deletes it
1373 cnt = cnt + 1
1374 end
1375 end
1376 run_sql([[DELETE FROM rooms WHERE area = ']]..fix_sql(a)..[[']])
1377 Note("Deleted ", cnt, " rooms in '", a, "' area.")
1378end
1379
1380function clean_file_name(f)
1381 f = string.gsub(f, "[^%w]", "")
1382 return f
1383end
1384
1385function fix_sql(s)
1386 if not s then -- nil value
1387 return ""
1388 end
1389 return string.gsub(s, "'", "''")
1390end
1391
1392function run_sql(sql)
1393 local db = assert(sqlite3.open(GetInfo(66)..clean_file_name(WorldName())..".db"))
1394 --Note(sql)
1395 rslt = db:exec(sql)
1396 --Note(rslt)
1397 db:close()
1398end
1399
1400function load_rooms()
1401 rooms = {}
1402sql = [[
1403 UPDATE rooms SET fillcolour = 0 WHERE fillcolour = ''
1404 ]]
1405run_sql(sql)
1406 sql = [[
1407 SELECT * FROM rooms ORDER BY uid ASC;
1408 ]]
1409 local db = assert(sqlite3.open(GetInfo(66)..clean_file_name(WorldName())..".db"))
1410 local cnt = 0
1411 for row in db:nrows(sql) do
1412 cnt = cnt + 1
1413 rooms[row.uid] = {
1414 name = row.name,
1415 desc = row.desc,
1416 area = row.area,
1417 fillcolour = row.fillcolour,
1418 fillbrush = row.fillbrush,
1419 bordercolour = row.bordercolour,
1420 info = row.info,
1421 notes = row.notes,
1422 exits = loadstring("return "..row.exits)()
1423 }
1424 end
1425 Note("Loaded ", cnt, " rooms from database.")
1426 db:close()
1427
1428 if tonumber(last_backup) == 0 then
1429 backup_db()
1430 end
1431end
1432
1433function check_update_room(uid, room)
1434 if not rooms[uid] or (serialize.save_simple(room) ~= serialize.save_simple(rooms[uid])) then
1435 add_update_room(uid, room)
1436 end
1437end
1438
1439function add_update_room(uid, room)
1440 sql = [[
1441 INSERT OR REPLACE INTO rooms (uid, name, desc, area, fillcolour, fillbrush, bordercolour, info, notes, exits)
1442 VALUES
1443 (']]..uid..[[',
1444 ']]..fix_sql(room.name)..[[',
1445 ']]..room.desc..[[',
1446 ']]..fix_sql(room.area)..[[',
1447 ']]..fix_sql(room.fillcolour)..[[',
1448 ']]..fix_sql(room.fillbrush)..[[',
1449 ']]..fix_sql(room.bordercolour)..[[',
1450 ']]..fix_sql(room.info)..[[',
1451 ']]..fix_sql(room.notes)..[[',
1452 ']]..fix_sql(serialize.save_simple(room.exits))..[[')
1453 ]]
1454 run_sql(sql)
1455end
1456
1457function check_create_db()
1458 sql = [[
1459 CREATE TABLE IF NOT EXISTS rooms (
1460 uid TEXT PRIMARY KEY,
1461 name TEXT,
1462 desc TEXT,
1463 area TEXT,
1464 fillcolour INTEGER,
1465 fillbrush INTEGER,
1466 bordercolour INTEGER,
1467 info TEXT,
1468 notes TEXT,
1469 exits TEXT
1470 )
1471 ]]
1472 run_sql(sql)
1473end
1474
1475------------------------------------------
1476-- end of sql additions
1477------------------------------------------
1478
1479------------------------------------------
1480-- backup stuff
1481------------------------------------------
1482-- If you want to do manual backups, make an alias with: script="backup_db"
1483------------------------------------------
1484
1485function backup_db()
1486 Note("Creating database backup.")
1487 local bk_nm = GetInfo(66).."db_backups\\"..clean_file_name(WorldName())..".db."..os.date("%A")
1488 ffi = require("ffi")
1489 ffi.cdef[[
1490 bool CreateDirectoryA(const char *lpPathName, void *lpSecurityAttributes);
1491 bool CopyFileA(const char* lpExistingFileName, const char * lpNewFileName, bool bFailIfExists);
1492 unsigned long GetLastError(void);
1493 ]]
1494
1495 succ = ffi.C.CreateDirectoryA(GetInfo(66).."db_backups\\", nil)
1496 err_no = ffi.C.GetLastError()
1497 if err_no and err_no ~= 183 and err_no ~= 127 then
1498 Note("Error creating directory: ", err_no)
1499 end
1500
1501 succ = ffi.C.CopyFileA(GetInfo(66)..clean_file_name(WorldName())..".db", bk_nm, false)
1502
1503 Note("Backup created: ", bk_nm)
1504 last_backup = os.time()
1505end
1506
1507------------------------------------------
1508-- end backup stuff
1509------------------------------------------
1510
1511-- Special thanks to Fiendish, Endymion, Valour, and Nick Gammon for all of their assistance with the mapper, and the original basis from which its built.
1512
1513]]>
1514</script>
1515
1516
1517</muclient>