· 6 years ago · May 18, 2019, 11:50 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 mapper.OUR_ROOM_COLOUR = ColourNameToRGB(OUR_ROOM_COLOUR)
786 SaveState()
787 end
788end
789
790
791function room_click (uid, flags)
792
793 -- check we got room at all
794 if not uid then
795 return nil
796 end -- if
797
798 -- look it up
799 local room = rooms [uid]
800
801 -- not cached - see if in database
802 if not room then
803return
804 end -- not in cache
805
806 if not room then
807 return
808 end -- if still not there
809
810 local function checkmark (which)
811 if rooms [uid] [which] then
812 return "+"
813 else
814 return ""
815 end -- if
816 end -- checkmark
817
818
819 local handlers = {
820 { name = "Edit bookmark", func = room_edit_bookmark} ,
821 { name = "-", } ,
822 { name = "Add Exit", func = room_add_exit} ,
823 { name = "Change Exit", func = room_change_exit} ,
824 { name = "Delete Exit", func = room_delete_exit} ,
825 { name = "-", } ,
826 { name = checkmark ("shop") .. "Shop", func = room_toggle_shop } ,
827 { name = checkmark ("train") .. "Trainer", func = room_toggle_train } ,
828 { name = checkmark ("inn") .. "Inn", func = room_toggle_inn } ,
829 { name = checkmark ("guild") .. "Guildmaster", func = room_toggle_guild } ,
830 { name = "-", } ,
831 { name = "Current Room Border Color", func = our_room_colour} ,
832 } -- handlers
833
834 local t, tf = {}, {}
835 for _, v in pairs (handlers) do
836 table.insert (t, v.name)
837 tf [v.name] = v.func
838 end -- for
839
840 local choice = WindowMenu (mapper.win,
841 WindowInfo (mapper.win, 14),
842 WindowInfo (mapper.win, 15),
843 table.concat (t, "|"))
844
845 local f = tf [choice]
846
847 if f then
848 f (room, uid)
849 end -- if handler found
850
851end -- room_click
852
853
854
855
856
857-- -----------------------------------------------------------------
858-- map_find: mapper find xxx
859-- -----------------------------------------------------------------
860function map_find (name, line, wildcards)
861
862 mapper.mapprint (string.rep ("-", 25) .. " Mapper search " .. string.rep ("-", 25))
863
864 local reset = ANSI (0)
865 local bold = ANSI (1)
866 local unbold = ANSI (22)
867
868 local matches = { }
869 local count = 0
870 local target = Trim (wildcards [1]:lower ())
871
872 if target == "" then
873 mapper.maperror ("No search string specified")
874 return
875 end -- if
876
877 if not mapper.check_we_can_find () then
878 return
879 end -- if find not OK
880
881 -- fix up any regular expression "magic" letters to be escaped by a %
882 local fixed_target = fix_regexp_magic_characters (target)
883
884 -- fix up for caseless searches in the room description (eg. "a" becomes "[aA]")
885 local caseless_target = string.gsub (fixed_target, "(%a)", function (a)
886 return "[" .. a:lower () .. a:upper () .. "]"
887 end -- function
888 )
889
890 -- do a simple string search to find matching rooms
891 for k, v in pairs (rooms) do
892
893 -- don't want nil descriptions
894 if not v.description then
895 v.description = ""
896 end -- if no description
897
898 if string.find (v.name:lower (), fixed_target) or
899 string.find (v.description:lower (), fixed_target) then
900 matches [k] = true
901 count = count + 1
902 end -- if match
903 end -- for each room
904
905 local function show_snippet (uid)
906 local room = rooms [uid]
907 if not room then
908 return
909 end -- if
910
911 -- don't bother if the wanted words was in the room name
912 if string.find (room.name:lower (), fixed_target) then
913 return
914 end -- if
915
916 -- otherwise show the wanted word in the description, in bold
917 AnsiNote (reset .. string.gsub (room.description, caseless_target, bold .. "%1" .. unbold))
918
919 end -- show_snippet
920
921 -- see if nearby
922 mapper.find (
923 function (uid)
924 local room = matches [uid]
925 if room then
926 matches [uid] = nil
927 end -- if
928 return room, next (matches) == nil
929 end, -- function
930 show_vnums, -- show vnum?
931 count, -- how many to expect
932 false, -- don't auto-walk
933 show_snippet -- show find snippet
934 )
935end -- map_find
936
937
938
939-- -----------------------------------------------------------------
940-- map_goto for: mapper goto xxx
941-- -----------------------------------------------------------------
942function map_goto (name, line, wildcards)
943 local wanted = wildcards [1]
944 -- check valid string
945 if string.match (wanted, "%D") then
946 mapper.maperror ("Room number must be numeric, you entered: " .. wanted)
947 return
948 end -- if
949
950 -- see if already there
951 if current_room and string.match (current_room, "^" .. wanted) then
952 mapper.mapprint ("You are already in that room.")
953 return
954 end -- if
955 -- find desired room
956 mapper.find (
957 function (uid)
958 local found = string.match (uid, "^" .. wanted)
959 return found, found
960 end, -- function
961 show_vnums, -- show vnum?
962 1, -- how many to expect
963 true -- just walk there
964 )
965end -- map_goto
966
967function map_resume (name, line, wildcards)
968
969 local wanted = mapper.last_hyperlink_uid or mapper.last_speedwalk_uid
970
971 if not wanted then
972 mapper.print "No outstanding speedwalks or hyperlinks."
973 return
974 end -- if nothing to do
975
976 -- find desired room
977 mapper.find (
978 function (uid)
979 return uid == wanted, uid == wanted
980 end, -- function
981 show_vnums, -- show vnum?
982 1, -- how many to expect
983 true -- just walk there
984 )
985
986end -- map_resume
987
988-- -----------------------------------------------------------------
989-- map_where: Show where a room is
990-- -----------------------------------------------------------------
991function map_where (name, line, wildcards)
992 if not mapper.check_we_can_find () then
993 return
994 end -- if
995 local wanted = wildcards [1]
996 if current_room and wanted == current_room then
997 mapper.mapprint ("You are already in that room.")
998 return
999 end -- if
1000 local paths = mapper.find_paths (current_room,
1001 function (uid)
1002 return uid == wanted, -- wanted room?
1003 uid == wanted -- stop searching?
1004 end)
1005 local uid, item = next (paths, nil) -- extract first (only) path
1006 -- nothing? room not found
1007 if not item then
1008 mapper.mapprint (string.format ("Room %s not found", wanted))
1009 return
1010 end -- if
1011 -- turn into speedwalk
1012 local path = mapper.build_speedwalk (item.path)
1013 -- display it
1014 mapper.mapprint (string.format ("Path to %s is: %s", wanted, path))
1015end -- map_where
1016
1017-- -----------------------------------------------------------------
1018-- cannot_walk - we tried to walk but failed
1019-- -----------------------------------------------------------------
1020function cannot_walk (name, line, wildcards)
1021 mapper.cancel_speedwalk ()
1022 room_description = nil
1023 current_exits = nil
1024 room_name = nil
1025 last_direction_moved = nil
1026-- mapper.mapprint ("Attempt to walk cancelled.")
1027
1028end -- cannot_walk
1029
1030function confirm_delete_area(a)
1031 response = utils.umsgbox("Delete area: "..a.."?", "Delete Area", "okcancel", "?", 2)
1032 if response == "ok" then
1033 delete_area(a)
1034 end
1035end
1036
1037function Door_Closed (name, line, wildcards)
1038
1039local dirs = {
1040 n = "north",
1041 s = "south",
1042 e = "east",
1043 w = "west",
1044 u = "up",
1045 d = "down",
1046 ne = "northeast",
1047 sw = "southwest",
1048 nw = "northwest",
1049 se = "southeast",
1050 ['in'] = "in",
1051 out = "out",
1052 } -- end of available
1053
1054 if last_direction_moved then
1055 Send ("open " .. dirs [last_direction_moved])
1056 Send (dirs [last_direction_moved])
1057 end -- if
1058
1059end -- Door_Closed
1060
1061
1062-- -----------------------------------------------------------------
1063-- check_for_cannot_go - look up the line in a table of failure messages
1064-- see table: cannot_move_messages
1065-- -----------------------------------------------------------------
1066function check_for_cannot_go (name, line, wildcards)
1067
1068 for _, v in ipairs (cannot_move_messages) do
1069 if string.find (line, v) then
1070 cannot_walk ()
1071 break
1072 end -- if match
1073 end -- for each message
1074end -- check_for_cannot_go
1075
1076function findpathfast(name, line, wildcards)
1077 local src = wildcards[1]
1078 local dest = wildcards[2]
1079 rooms[src] = load_room_from_database(src)
1080 rooms[dest] = load_room_from_database(dest)
1081
1082 if rooms[src] == nil then
1083 mapper.mapprint (string.format ("Room %s not known.", src))
1084 end
1085 if rooms[dest] == nil then
1086 mapper.mapprint (string.format ("Room %s not known.", dest))
1087 end
1088 if rooms[src] == nil or rooms[dest] == nil then
1089 return
1090 end
1091
1092 local foundpath = findpath(src, dest)
1093 if foundpath == nil then
1094 mapper.mapprint (string.format ("Path from %s to %s not found.", wildcards[1], wildcards[2]))
1095 return
1096 end
1097
1098 -- turn into speedwalk
1099 local speedwalk = mapper.build_speedwalk (foundpath, speedwalk_prefix)
1100
1101 -- display it
1102 if speedwalk ~= nil then
1103 mapper.mapprint (string.format ("Path from %s to %s is: %s", wildcards[1], wildcards[2], speedwalk))
1104 else
1105 mapper.mapprint ("Pick different start and end rooms.")
1106 end
1107end
1108
1109function blackindigoPrint(msg)
1110 ColourNote("blueviolet","black",msg)
1111end
1112function blackredPrint(msg)
1113 ColourNote("black","red",msg)
1114end
1115function whiteindigoPrint(msg)
1116 ColourNote("white","indigo",msg)
1117end
1118
1119
1120function setup_terrain_colors()
1121terrain_color["0"]=tonumber("0x000000")--NOTSET
1122terrain_color["1"]=tonumber("0x606060")--Building
1123terrain_color["2"]=tonumber("0x805a22")--Town
1124terrain_color["3"]=tonumber("0x00ff00")--FIELD
1125terrain_color["4"]=tonumber("0x00c000")--LFOREST
1126terrain_color["5"]=tonumber("0x008000")--TFOREST
1127terrain_color["6"]=tonumber("0x004000")--DFOREST
1128terrain_color["7"]=tonumber("0x406080")--SWAMP
1129terrain_color["8"]=tonumber("0x60a060")--PLATEAU
1130terrain_color["9"]=ColourNameToRGB("khaki")--SANDY
1131terrain_color["10"]=tonumber("0xc0c0c0")--MOUNTAIN
1132terrain_color["11"]=tonumber("0x808080")--ROCK
1133terrain_color["12"]=ColourNameToRGB("burlywood")--DESERT
1134terrain_color["13"]=tonumber("0x805080")--TUNDRA
1135terrain_color["14"]=ColourNameToRGB("lightyellow")--BEACH
1136terrain_color["15"]=tonumber("0x409040")--HILL
1137terrain_color["16"]=ColourNameToRGB("navajowhite")--DUNES
1138terrain_color["17"]=tonumber("0x20c040")--JUNGLE
1139terrain_color["18"]=ColourNameToRGB("darkblue")--OCEAN
1140terrain_color["19"]=tonumber("0x00f0f0")--STREAM
1141terrain_color["20"]=ColourNameToRGB("blue")--RIVER
1142terrain_color["21"]=tonumber("0x021e6c")--UNDERWATER
1143terrain_color["22"]=tonumber("0x303030")--UNDERGROUND
1144terrain_color["23"]=ColourNameToRGB("lightskyblue")--AIR
1145terrain_color["24"]=tonumber("0x82f8e6")--ICE
1146terrain_color["25"]=ColourNameToRGB("red")--LAVA
1147terrain_color["26"]=tonumber("0x806060")--RUINS
1148terrain_color["27"]=tonumber("0x404040")--CAVE
1149terrain_color["28"]=tonumber("0x907040")--CITY
1150terrain_color["29"]=tonumber("0x20a060")--MARSH
1151terrain_color["30"]=tonumber("0xf0f0a0")--WASTELAND
1152terrain_color["31"]=tonumber("0xffffff")--CLOUD
1153terrain_color["32"]=ColourNameToRGB("blue")--WATER
1154terrain_color["33"]=tonumber("0x808080")--METAL
1155terrain_color["34"]=tonumber("0x006000")--TAIGA
1156terrain_color["35"]=tonumber("0x404040")--SEWER
1157terrain_color["36"]=ColourNameToRGB("indigo")--SHADOW
1158terrain_color["37"]=ColourNameToRGB("indigo")--CATACOMB
1159terrain_color["38"]=ColourNameToRGB("olivedrab")--MIRE
1160terrain_color["39"]=ColourNameToRGB("indigo")--CRYSTAL
1161 -- end of terrain_color
1162end
1163
1164-- -----------------------------------------------------------------
1165-- Plugin Install
1166-- -----------------------------------------------------------------
1167
1168function OnPluginInstall ()
1169
1170 config = {} -- in case not found
1171 setup_terrain_colors()
1172
1173 -- get saved configuration
1174 assert (loadstring (GetVariable ("config") or "")) ()
1175
1176 -- and rooms
1177 --assert (loadstring (GetVariable ("rooms") or "")) ()
1178
1179 -- new stuff for sql data
1180 check_create_db()
1181 load_rooms()
1182
1183 -- initialize mapper
1184
1185 mapper.init { config = config,
1186 get_room = get_room, findpath = findpath,
1187 room_click = room_click, -- called on RH click on room square,
1188 show_help = OnHelp, -- to show help,
1189 show_other_areas = show_other_areas, -- want to see areas other than the current one?
1190}
1191 mapper.mapprint (string.format ("MUSHclient mapper installed, version %0.1f", mapper.VERSION))
1192
1193
1194end -- OnPluginInstall
1195
1196function OnHelp (name, line, wildcards)
1197 local help_header = " [Demon Mush Mapper Help] "
1198
1199 local help_index = [[
1200 Mapper Help Index
1201=============================================================================
1202 mapper help --> Show this list
1203-----------------------------------------------------------------------------
1204 mapper help config --> Commands for configuring the mapper
1205 mapper help moving --> Commands for moving between rooms
1206 mapper help utils --> Other utilitarian commands
1207 mapper help searching --> Used for finding notes, shops, guildmasters, etc
1208=============================================================================
1209]]
1210 local help_table = {
1211 ['config'] = {
1212['header'] = [[===== CONFIGURATION =============>]],
1213[[mapper help --> This help
1214 > (or click the "?" button on the top right)]],
1215[[mapper zoom out --> Zoom out]],
1216[[mapper zoom in --> Zoom in]],
1217[[mapper hide --> Hide map]],
1218[[mapper show --> Show map]],
1219[[mapper updown --> Toggle up/down exit drawing]],
1220[[mapper underlines --> Toggle underlining of clickable links]]
1221},
1222
1223 ['utils'] = {
1224['header'] = [[===== UTILITIES =================>]],
1225[[mapper backup --> Creates a backup of the mapper database]],
1226[[mapper addnote --> Add a new note to the current room]],
1227[[mapper addnote <note> --> Ditto, but skips the dialog]]
1228},
1229 ['searching'] = {
1230['header'] = [[===== SEARCHING =================>]],
1231[[mapper find <text> --> Full-text search the whole database]],
1232[[]],
1233[[mapper notes --> Show nearby rooms that you marked with notes]],
1234[[mapper notes <here/area> --> Ditto]],
1235[[mapper shops --> Show all shops/banks]],
1236[[mapper shops <here/area> --> Ditto]],
1237[[mapper train --> Show all trainers]],
1238[[mapper train <here/area> --> Ditto]],
1239[[mapper quest --> Show all quest-givers]],
1240[[mapper quest <here/area> --> Ditto]],
1241[[]],
1242[[mapper next --> Visit the next room in the most recent
1243 > list of results.]],
1244[[mapper next <index> --> Ditto, but skip to the given result index.]],
1245[[mapper where <room id> --> Show directions to a room number]]
1246},
1247
1248
1249 ['moving'] = {
1250['header'] = [[===== MOVING ====================>]],
1251[[mapper goto <room id> --> Run to a room by its room number]]
1252}
1253}
1254
1255 local function show_help(helps)
1256 blackindigoPrint("")
1257 blackindigoPrint(helps['header'])
1258 blackindigoPrint("")
1259 for i,v in ipairs(helps) do
1260 blackindigoPrint(v)
1261 end
1262 end
1263
1264 blackindigoPrint("")
1265 whiteindigoPrint(help_header)
1266 blackindigoPrint("+---------------------------------------------------------------------------+")
1267 badnews = true
1268 if wildcards and wildcards[2] ~= "" then
1269 badnews = false
1270 if wildcards[2] == "all" then
1271 show_help(help_table['config'])
1272 show_help(help_table['exits'])
1273 show_help(help_table['searching'])
1274 show_help(help_table['moving'])
1275 show_help(help_table['utils'])
1276 elseif wildcards[2] == "config" then
1277 show_help(help_table['config'])
1278 elseif wildcards[2] == "searching" then
1279 show_help(help_table['searching'])
1280 elseif wildcards[2] == "moving" then
1281 show_help(help_table['moving'])
1282 elseif wildcards[2] == "utils" then
1283 show_help(help_table['utils'])
1284 elseif wildcards[2]:find("search ") == 1 then
1285 local st, en = wildcards[2]:find("search ")
1286 local pattern = Trim(wildcards[2]:sub(en+1))
1287 ColourTell("cornflower","black","Searching help for: ")
1288 ColourNote("red","black",pattern)
1289 if pattern ~= "" then
1290 for k,v in pairs(help_table) do
1291 local done_header = false
1292 for j,w in ipairs(v) do
1293 if (w ~= "") and (w:find("--------",nil,true) == nil) and (w:find(pattern) ~= nil) then
1294 if not done_header then
1295 blackindigoPrint("")
1296 blackindigoPrint(v['header'])
1297 done_header = true
1298 end
1299 blackindigoPrint("")
1300 local wtable = w:split(pattern)
1301 for i,v in ipairs(wtable) do
1302 ColourTell("cornflower","black",v)
1303 if (i < #wtable) then
1304 ColourTell("red", "black", pattern)
1305 end
1306 end
1307 Note("")
1308 end
1309 end
1310 end
1311 else
1312 badnews = true
1313 end
1314 else
1315 badnews = true
1316 end
1317 end
1318 if badnews then
1319 blackindigoPrint("")
1320 mapper.mapprint (world.GetPluginInfo (world.GetPluginID (), 3))
1321 blackindigoPrint("")
1322 blackindigoPrint(help_index)
1323 end
1324 blackindigoPrint("")
1325 blackindigoPrint("+---------------------------------------------------------------------------+")
1326 blackindigoPrint("")
1327end
1328
1329
1330-- -----------------------------------------------------------------
1331-- Plugin Save State
1332-- -----------------------------------------------------------------
1333
1334function OnPluginSaveState ()
1335 mapper.save_state ()
1336 SetVariable ("config", "config = " .. serialize.save_simple (config))
1337 SetVariable("last_backup", last_backup)
1338SetVariable("OUR_ROOM_COLOUR", OUR_ROOM_COLOUR) -- Color of Room Border
1339end -- OnPluginSaveState
1340
1341------------------------------------------
1342-- start of sql additions
1343------------------------------------------
1344function delete_room_alias(name, line, wildcards)
1345 local num = wildcards[1]
1346 if num then
1347 delete_room(num)
1348 end
1349end
1350
1351function delete_area_alias(name, line, wildcards)
1352 local a = wildcards[1]
1353 if a then
1354 delete_area(a)
1355 end
1356end
1357
1358function delete_room(num) -- delete room from rooms
1359 for r, tbl in pairs(rooms) do -- for each room in table
1360 if tostring(r) == tostring(num) then
1361 rooms[r] = nil -- setting table item to nil deletes it
1362 end
1363 end
1364 run_sql([[DELETE FROM rooms WHERE uid = ']]..num..[[']])
1365 Note("Deleted ", num, ".")
1366 SendNoEcho("look")
1367end
1368
1369function delete_area(a)
1370 local cnt = 0
1371 for r, tbl in pairs(rooms) do -- for each room in table
1372 if tostring(tbl.area) == tostring(a) then
1373 rooms[r] = nil -- setting table item to nil deletes it
1374 cnt = cnt + 1
1375 end
1376 end
1377 run_sql([[DELETE FROM rooms WHERE area = ']]..fix_sql(a)..[[']])
1378 Note("Deleted ", cnt, " rooms in '", a, "' area.")
1379end
1380
1381function clean_file_name(f)
1382 f = string.gsub(f, "[^%w]", "")
1383 return f
1384end
1385
1386function fix_sql(s)
1387 if not s then -- nil value
1388 return ""
1389 end
1390 return string.gsub(s, "'", "''")
1391end
1392
1393function run_sql(sql)
1394 local db = assert(sqlite3.open(GetInfo(66)..clean_file_name(WorldName())..".db"))
1395 --Note(sql)
1396 rslt = db:exec(sql)
1397 --Note(rslt)
1398 db:close()
1399end
1400
1401function load_rooms()
1402 rooms = {}
1403sql = [[
1404 UPDATE rooms SET fillcolour = 0 WHERE fillcolour = ''
1405 ]]
1406run_sql(sql)
1407 sql = [[
1408 SELECT * FROM rooms ORDER BY uid ASC;
1409 ]]
1410 local db = assert(sqlite3.open(GetInfo(66)..clean_file_name(WorldName())..".db"))
1411 local cnt = 0
1412 for row in db:nrows(sql) do
1413 cnt = cnt + 1
1414 rooms[row.uid] = {
1415 name = row.name,
1416 desc = row.desc,
1417 area = row.area,
1418 fillcolour = row.fillcolour,
1419 fillbrush = row.fillbrush,
1420 bordercolour = row.bordercolour,
1421 info = row.info,
1422 notes = row.notes,
1423 exits = loadstring("return "..row.exits)()
1424 }
1425 end
1426 Note("Loaded ", cnt, " rooms from database.")
1427 db:close()
1428
1429 if tonumber(last_backup) == 0 then
1430 backup_db()
1431 end
1432end
1433
1434function check_update_room(uid, room)
1435 if not rooms[uid] or (serialize.save_simple(room) ~= serialize.save_simple(rooms[uid])) then
1436 add_update_room(uid, room)
1437 end
1438end
1439
1440function add_update_room(uid, room)
1441 sql = [[
1442 INSERT OR REPLACE INTO rooms (uid, name, desc, area, fillcolour, fillbrush, bordercolour, info, notes, exits)
1443 VALUES
1444 (']]..uid..[[',
1445 ']]..fix_sql(room.name)..[[',
1446 ']]..room.desc..[[',
1447 ']]..fix_sql(room.area)..[[',
1448 ']]..fix_sql(room.fillcolour)..[[',
1449 ']]..fix_sql(room.fillbrush)..[[',
1450 ']]..fix_sql(room.bordercolour)..[[',
1451 ']]..fix_sql(room.info)..[[',
1452 ']]..fix_sql(room.notes)..[[',
1453 ']]..fix_sql(serialize.save_simple(room.exits))..[[')
1454 ]]
1455 run_sql(sql)
1456end
1457
1458function check_create_db()
1459 sql = [[
1460 CREATE TABLE IF NOT EXISTS rooms (
1461 uid TEXT PRIMARY KEY,
1462 name TEXT,
1463 desc TEXT,
1464 area TEXT,
1465 fillcolour INTEGER,
1466 fillbrush INTEGER,
1467 bordercolour INTEGER,
1468 info TEXT,
1469 notes TEXT,
1470 exits TEXT
1471 )
1472 ]]
1473 run_sql(sql)
1474end
1475
1476------------------------------------------
1477-- end of sql additions
1478------------------------------------------
1479
1480------------------------------------------
1481-- backup stuff
1482------------------------------------------
1483-- If you want to do manual backups, make an alias with: script="backup_db"
1484------------------------------------------
1485
1486function backup_db()
1487 Note("Creating database backup.")
1488 local bk_nm = GetInfo(66).."db_backups\\"..clean_file_name(WorldName())..".db."..os.date("%A")
1489 ffi = require("ffi")
1490 ffi.cdef[[
1491 bool CreateDirectoryA(const char *lpPathName, void *lpSecurityAttributes);
1492 bool CopyFileA(const char* lpExistingFileName, const char * lpNewFileName, bool bFailIfExists);
1493 unsigned long GetLastError(void);
1494 ]]
1495
1496 succ = ffi.C.CreateDirectoryA(GetInfo(66).."db_backups\\", nil)
1497 err_no = ffi.C.GetLastError()
1498 if err_no and err_no ~= 183 and err_no ~= 127 then
1499 Note("Error creating directory: ", err_no)
1500 end
1501
1502 succ = ffi.C.CopyFileA(GetInfo(66)..clean_file_name(WorldName())..".db", bk_nm, false)
1503
1504 Note("Backup created: ", bk_nm)
1505 last_backup = os.time()
1506end
1507
1508------------------------------------------
1509-- end backup stuff
1510------------------------------------------
1511
1512-- 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.
1513
1514]]>
1515</script>
1516
1517
1518</muclient>