Advertisement
tdubbzz

Untitled

May 27th, 2018
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 114.00 KB | None | 0 0
  1. <?xml version="1.0" encoding="iso-8859-1"?>
  2. <!DOCTYPE muclient [
  3. <!ENTITY show_vnums "true" >
  4. <!ENTITY show_timing "false" >
  5. <!ENTITY show_completed "false" >
  6. <!ENTITY show_other_areas "true" >
  7. <!ENTITY show_area_exits "false" >
  8. <!ENTITY show_up_down "true" >
  9. <!ENTITY speedwalk_prefix "" >
  10. <!ENTITY verbose_mode "true" >
  11. ]>
  12.  
  13. <muclient>
  14.  
  15. <plugin
  16. name="MM_GMCP_Mapper_GMCP"
  17. author="Nick Gammon, Ruthgul"
  18. id="f973af093e715dece34dc25f"
  19. language="Lua"
  20. purpose="GMCP Mapper for Materia Magica"
  21. save_state="y"
  22. date_written="2012-02-03 20:26:09"
  23. date_modified="2017-01-21 23:20:21"
  24. requires="4.71"
  25. version="1.0"
  26. >
  27.  
  28. <description trim="y">
  29.  
  30. <![CDATA[
  31.  
  32. .-----------------------.
  33. | MM_GMCP_Mapper_GMCP |
  34. `-----------------------'
  35.  
  36. Materia Magica GMCP mapper.
  37. Original plugin by Nick Gammon. (http://www.gammon.com.au/forum/?id=10667)
  38. Modified to work with GMCP by Ruthgul. (Please report bugs to Ruthgul.)
  39.  
  40.  
  41. ** REQUIRES **
  42.  
  43. - The file mm_mapper.lua must be placed in the MUSHclient/lua directory.
  44. - MUSHclient _must_ have write access to its folder.
  45. - MM_GMCP_Handler (plugin id="f67c4339ed0591a5b010d05b") must be installed and enabled.
  46. - Client setting: Game, Configure, Output > [x] Convert IAC EOR/GA to new line (must be checked).
  47. - Game settings: SHOW-EXITS must be ON (to show room numbers, road exits and unmapped exits).
  48.  
  49.  
  50. Notes:
  51.  
  52. * The window can be dragged to a new location by dragging the room name.
  53. * Your current room is always in the center with a bolder border.
  54. * LH-click on a room to speed-walk to it. RH-click on a room for options.
  55. * LH-click on the "*" button on the bottom-left corner to configure it.
  56.  
  57.  
  58. Syntax:
  59.  
  60. > Interface:
  61.  
  62. * mapper zoom out - zoom out
  63. * mapper zoom in - zoom in
  64.  
  65. * mapper hide - hide map
  66. * mapper show - show map
  67.  
  68. * mapper color terrain [on|off] - toggle PK vs terrain coloring (off by default)
  69. * mapper show flags [on|off] - toggle showing room flags on/off (off by default)
  70. * mapper show numbers [on|off] - toggle showing/logging room numbers on/off (off by default)
  71. * mapper show road exits [on|off] - toggle showing on-road exits on/off (off by default)
  72. * mapper show unmapped exits [on|off] - toggle showing unmapped exits on/off (off by default)
  73. * mapper draw other floors [on|off] - toggle drawing other floors on/off (on by default)
  74.  
  75. * mapper auto-open [on|off] - toggle auto-open doors on/off (on by default)
  76. * mapper safewalk [on|off] - toggle avoid PK rooms and DTs on/off (off by default, only works for mapper goto, not for clicking on a room in the map, not for mapper path)
  77.  
  78. * mapper peek [<room#>] - redraw the map centered on any room, by its room number
  79.  
  80. > Queries:
  81.  
  82. * mapper where <room_name> - show room# and area for an existing room, by its room name (Note that the % symbol can be used as a wildcard.)
  83. * mapper find <text> - search by keywords (eg, courtyard OR lobby)
  84. * mapper bookmarks - show nearby rooms that you bookmarked ('nearby' is determined by your mapper's depth setting)
  85. * mapper findbm <text> - search by bookmark
  86. * mapper flags <flags> - search by room flags
  87. * mapper notflags <flags> - search by negated room flags
  88. * mapper adjacent <full_room_name> - show adjacent rooms with different names
  89.  
  90. * mapper safes - show nearby safe rooms
  91. * mapper cpks - show nearby CPK rooms
  92.  
  93. * mapper dts - show nearby death traps
  94. * mapper shops - show nearby shops
  95. * mapper trainers - show nearby trainers
  96.  
  97. > Movement:
  98.  
  99. * mapper path <room#> - show directions to a room, by its room number
  100. * mapper path <room1#> <room2#> - show directions from room1 to room2, by room number
  101.  
  102. * mapper goto <room#> - walk to a room, by its room number (partial)
  103. * mapper stop - cancel any current speedwalk
  104. * mapper resume - resume last speedwalk or hyperlinked speedwalk
  105. * mapper speedwalk next - show (or SAPI say) next direction of the speedwalk (to flee, etc.)
  106.  
  107. > Special areas:
  108.  
  109. * mapper map wilds [on|off] - toggle mapping the wilds on/off (off by default)
  110.  
  111. > Maintanence:
  112.  
  113. * mapper purge area <full_area_name> - delete an entire area from the database
  114. * mapper purge wilds <full_plane_name> - deletes rooms in the vmap except for roads
  115. * mapper purge pursuer - delete changing orc pursuer maze info from the database
  116. * mapper purge sandbox - delete housing sandbox info from the database
  117. * mapper purge molehill - delete changing labyrinthine molehill info from the database
  118.  
  119. * mapper maintenance - show a list of advanced maintenance & privacy aliases
  120.  
  121.  
  122. Authors: Nick Gammon, Ruthgul (maintained by Ruthgul)
  123.  
  124. Latest version:
  125. http://github.com/mu3r73/mm-mushclient-scripts
  126.  
  127. ]]>
  128.  
  129. </description>
  130.  
  131. </plugin>
  132.  
  133.  
  134.  
  135. <!-- Aliases -->
  136.  
  137. <aliases>
  138.  
  139. <!-- interface -->
  140.  
  141. <alias
  142. enabled="y"
  143. match="^mapper[ ]+reset[ ]+defaults$"
  144. regexp="y"
  145. sequence="100"
  146. omit_from_command_history="y"
  147. omit_from_output="y"
  148. script="reset_defaults"
  149. >
  150. </alias>
  151.  
  152. <alias
  153. enabled="y"
  154. match="^mapper[ ]+show[ ]+database[ ]+mods(|[ ]+(?P&lt;status&gt;(on|off)))$"
  155. regexp="y"
  156. send_to="12"
  157. sequence="100"
  158. >
  159. <send>toggle_show_database_mods_to("%&lt;status&gt;")
  160. </send>
  161. </alias>
  162.  
  163. <alias
  164. enabled="y"
  165. match="^mapper[ ]+zoom[ ]+out$"
  166. regexp="y"
  167. sequence="100"
  168. omit_from_command_history="y"
  169. omit_from_output="y"
  170. script="mapper.zoom_out"
  171. >
  172. </alias>
  173.  
  174. <alias
  175. enabled="y"
  176. match="^mapper[ ]+zoom[ ]+in$"
  177. regexp="y"
  178. sequence="100"
  179. omit_from_command_history="y"
  180. omit_from_output="y"
  181. script="mapper.zoom_in"
  182. >
  183. </alias>
  184.  
  185. <alias
  186. enabled="y"
  187. match="^mapper[ ]+hide$"
  188. regexp="y"
  189. send_to="12"
  190. sequence="100"
  191. >
  192. <send>mapper_hide(true)
  193. </send>
  194. </alias>
  195.  
  196. <alias
  197. enabled="y"
  198. match="^mapper[ ]+show$"
  199. regexp="y"
  200. send_to="12"
  201. sequence="100"
  202. >
  203. <send>mapper_show(true)
  204. </send>
  205. </alias>
  206.  
  207. <alias
  208. enabled="y"
  209. match="^mapper[ ]+colo(|u)r[ ]+terrain(|[ ]+(?P&lt;status&gt;(on|off)))$"
  210. regexp="y"
  211. send_to="12"
  212. sequence="100"
  213. >
  214. <send>toggle_terrain_to("%&lt;status&gt;")
  215. </send>
  216. </alias>
  217.  
  218. <alias
  219. enabled="y"
  220. match="^mapper[ ]+show[ ]+flags(|[ ]+(?P&lt;status&gt;(on|off)))$"
  221. regexp="y"
  222. send_to="12"
  223. sequence="100"
  224. >
  225. <send>toggle_vis_flags_to("%&lt;status&gt;")
  226. </send>
  227. </alias>
  228.  
  229. <alias
  230. enabled="y"
  231. match="^mapper[ ]+show[ ]+numbers(|[ ]+(?P&lt;status&gt;(on|off)))$"
  232. regexp="y"
  233. send_to="12"
  234. sequence="100"
  235. >
  236. <send>toggle_vis_number_to("%&lt;status&gt;")
  237. </send>
  238. </alias>
  239.  
  240. <alias
  241. enabled="y"
  242. match="^mapper[ ]+show[ ]+road[ ]+exits(|[ ]+(?P&lt;status&gt;(on|off)))$"
  243. regexp="y"
  244. send_to="12"
  245. sequence="100"
  246. >
  247. <send>toggle_vis_road_exits_to("%&lt;status&gt;")
  248. </send>
  249. </alias>
  250.  
  251. <alias
  252. enabled="y"
  253. match="^mapper[ ]+show[ ]+unmapped[ ]+exits(|[ ]+(?P&lt;status&gt;(on|off)))$"
  254. regexp="y"
  255. send_to="12"
  256. sequence="100"
  257. >
  258. <send>toggle_vis_unmapped_to("%&lt;status&gt;")
  259. </send>
  260. </alias>
  261.  
  262. <alias
  263. enabled="y"
  264. match="^mapper[ ]+draw[ ]+other[ ]+floors(|[ ]+(?P&lt;status&gt;(on|off)))$"
  265. regexp="y"
  266. send_to="12"
  267. sequence="100"
  268. >
  269. <send>toggle_draw_other_floors_to("%&lt;status&gt;")
  270. </send>
  271. </alias>
  272.  
  273. <alias
  274. enabled="y"
  275. match="^mapper[ ]+auto\-open(|[ ]+(?P&lt;status&gt;(on|off)))$"
  276. regexp="y"
  277. send_to="12"
  278. sequence="100"
  279. >
  280. <send>toggle_auto_open_to("%&lt;status&gt;")
  281. </send>
  282. </alias>
  283.  
  284. <alias
  285. enabled="y"
  286. match="^mapper[ ]+safewalk(|[ ]+(?P&lt;status&gt;(on|off)))$"
  287. regexp="y"
  288. send_to="12"
  289. sequence="100"
  290. >
  291. <send>toggle_safewalk_to("%&lt;status&gt;")
  292. </send>
  293. </alias>
  294.  
  295. <alias
  296. enabled="y"
  297. match="^mapper[ ]+peek[ ]+(?P&lt;id&gt;[0-9]+)$"
  298. regexp="y"
  299. send_to="12"
  300. sequence="100"
  301. >
  302. <send>peek_room("%&lt;id&gt;")
  303. </send>
  304. </alias>
  305.  
  306.  
  307. <!-- queries -->
  308.  
  309. <alias
  310. enabled="y"
  311. match="^mapper[ ]+where[ ]+(?P&lt;name&gt;[^\:]+)$"
  312. regexp="y"
  313. send_to="12"
  314. sequence="100"
  315. >
  316. <send>map_where("%&lt;name&gt;")
  317. </send>
  318. </alias>
  319.  
  320. <alias
  321. enabled="y"
  322. match="^mapper[ ]+wheree[ ]+(?P&lt;name&gt;[^\:]+)(| a\:(?P&lt;area&gt;[^\:]+))$"
  323. regexp="y"
  324. send_to="12"
  325. sequence="100"
  326. >
  327. <send>map_wheree("%&lt;name&gt;", "%&lt;area&gt;")
  328. </send>
  329. </alias>
  330.  
  331. <alias
  332. enabled="y"
  333. match="^mapper[ ]+find[ ]+(?P&lt;what&gt;[a-zA-Z0-9 \,\.\'\-]+)$"
  334. regexp="y"
  335. send_to="12"
  336. sequence="100"
  337. >
  338. <send>map_find("%&lt;what&gt;")
  339. </send>
  340. </alias>
  341.  
  342. <alias
  343. enabled="y"
  344. match="^mapper[ ]+(bm|book(|mark(|s)))$"
  345. regexp="y"
  346. sequence="100"
  347. script="map_bookmarks"
  348. >
  349. </alias>
  350.  
  351. <alias
  352. enabled="y"
  353. match="^mapper[ ]+findbm[ ]+(?P&lt;bm&gt;[a-zA-Z0-9 \,\.\'\-]+)$"
  354. regexp="y"
  355. send_to="12"
  356. sequence="100"
  357. >
  358. <send>map_find_bookmark("%&lt;bm&gt;")
  359. </send>
  360. </alias>
  361.  
  362. <alias
  363. enabled="y"
  364. match="^mapper[ ]+flags[ ]+(?P&lt;flags&gt;[a-z \-]+)$"
  365. regexp="y"
  366. send_to="12"
  367. sequence="100"
  368. >
  369. <send>map_list_by_flags("%&lt;flags&gt;")
  370. </send>
  371. </alias>
  372.  
  373. <alias
  374. enabled="y"
  375. match="^mapper[ ]+notflags[ ]+(?P&lt;flags&gt;[a-z \-]+)$"
  376. regexp="y"
  377. send_to="12"
  378. sequence="100"
  379. >
  380. <send>map_list_by_not_flags("%&lt;flags&gt;")
  381. </send>
  382. </alias>
  383.  
  384. <alias
  385. enabled="y"
  386. match="^mapper[ ]+adjacent[ ]+(?P&lt;name&gt;[^\:]+)$"
  387. regexp="y"
  388. send_to="12"
  389. sequence="100"
  390. >
  391. <send>map_show_adjacent_rooms("%&lt;name&gt;")
  392. </send>
  393. </alias>
  394.  
  395. <alias
  396. enabled="y"
  397. match="^mapper[ ]+safes$"
  398. regexp="y"
  399. sequence="100"
  400. script="map_safe"
  401. >
  402. </alias>
  403.  
  404. <alias
  405. enabled="y"
  406. match="^mapper[ ]+cpks$"
  407. regexp="y"
  408. sequence="100"
  409. script="map_cpk"
  410. >
  411. </alias>
  412.  
  413. <alias
  414. enabled="y"
  415. match="^mapper[ ]+dts$"
  416. regexp="y"
  417. sequence="100"
  418. script="map_dts"
  419. >
  420. </alias>
  421.  
  422. <alias
  423. enabled="y"
  424. match="^mapper[ ]+shops$"
  425. regexp="y"
  426. sequence="100"
  427. script="map_shops"
  428. >
  429. </alias>
  430.  
  431. <alias
  432. enabled="y"
  433. match="^mapper[ ]+trainers$"
  434. regexp="y"
  435. sequence="100"
  436. script="map_trainers"
  437. >
  438. </alias>
  439.  
  440.  
  441. <!-- movement -->
  442.  
  443. <alias
  444. enabled="y"
  445. match="^mapper[ ]+path[ ]+(?P&lt;id&gt;[0-9]+)$"
  446. regexp="y"
  447. send_to="12"
  448. sequence="100"
  449. >
  450. <send>map_path("%&lt;id&gt;")
  451. </send>
  452. </alias>
  453.  
  454. <alias
  455. enabled="y"
  456. match="^mapper[ ]+path[ ]+(?P&lt;id1&gt;[0-9]+)[ ]+(?P&lt;id2&gt;[0-9]+)$"
  457. regexp="y"
  458. send_to="12"
  459. sequence="100"
  460. >
  461. <send>map_path2("%&lt;id1&gt;", "%&lt;id2&gt;")
  462. </send>
  463. </alias>
  464.  
  465. <alias
  466. enabled="y"
  467. match="^mapper[ ]+goto[ ]+(?P&lt;id&gt;[0-9]+)$"
  468. regexp="y"
  469. send_to="12"
  470. sequence="100"
  471. >
  472. <send>map_goto("%&lt;id&gt;")
  473. </send>
  474. </alias>
  475.  
  476. <alias
  477. enabled="y"
  478. match="^mapper[ ]+stop$"
  479. regexp="y"
  480. sequence="100"
  481. script="mapper.cancel_speedwalk"
  482. >
  483. </alias>
  484.  
  485. <alias
  486. enabled="y"
  487. match="^mapper[ ]+resume$"
  488. regexp="y"
  489. sequence="100"
  490. script="map_resume"
  491. >
  492. </alias>
  493.  
  494. <alias
  495. enabled="y"
  496. match="^mapper[ ]+speed(|walk)[ ]+next$"
  497. regexp="y"
  498. sequence="100"
  499. script="map_speedwalk_next"
  500. >
  501. </alias>
  502.  
  503.  
  504. <!-- special areas -->
  505.  
  506. <alias
  507. enabled="y"
  508. match="^mapper[ ]+map[ ]+wilds(|[ ]+(?P&lt;status&gt;(on|off)))$"
  509. regexp="y"
  510. send_to="12"
  511. sequence="100"
  512. >
  513. <send>toggle_wilds_mapping("%&lt;status&gt;")
  514. </send>
  515. </alias>
  516.  
  517.  
  518. <!-- maintenance -->
  519.  
  520. <alias
  521. enabled="y"
  522. match="^mapper[ ]+purge[ ]+area[ ]+(?P&lt;areaid&gt;[a-zA-Z0-9 \,\.\'\-]+)$"
  523. regexp="y"
  524. send_to="12"
  525. sequence="100"
  526. >
  527. <send>purge_entire_area("%&lt;areaid&gt;")
  528. </send>
  529. </alias>
  530.  
  531. <alias
  532. enabled="y"
  533. match="^mapper[ ]+purge[ ]+wilds[ ]+(?P&lt;planeid&gt;[a-zA-Z ]+)$"
  534. regexp="y"
  535. send_to="12"
  536. sequence="100"
  537. >
  538. <send>purge_wilds("%&lt;planeid&gt;")
  539. </send>
  540. </alias>
  541.  
  542. <alias
  543. enabled="y"
  544. match="^mapper[ ]+purge[ ]+pursuer$"
  545. regexp="y"
  546. sequence="100"
  547. script="purge_pursuer"
  548. >
  549. </alias>
  550.  
  551. <alias
  552. enabled="y"
  553. match="^mapper[ ]+purge[ ]+sandbox$"
  554. regexp="y"
  555. sequence="100"
  556. script="purge_sandbox"
  557. >
  558. </alias>
  559.  
  560. <alias
  561. enabled="y"
  562. match="^mapper[ ]+purge[ ]+molehill$"
  563. regexp="y"
  564. sequence="100"
  565. script="purge_molehill"
  566. >
  567. </alias>
  568.  
  569. <alias
  570. enabled="y"
  571. match="^mapper[ ]+maintenance$"
  572. regexp="y"
  573. sequence="100"
  574. script="help_maintenance"
  575. >
  576. </alias>
  577.  
  578.  
  579. <!-- maintenance - queries -->
  580.  
  581. <alias
  582. match="^mapper[ ]+roominfo(|[ ]+(?P&lt;id&gt;[0-9]+))$"
  583. enabled="y"
  584. regexp="y"
  585. send_to="12"
  586. sequence="100"
  587. >
  588. <send>show_room_info("%&lt;id&gt;")
  589. </send>
  590. </alias>
  591.  
  592. <alias
  593. match="^mapper[ ]+export[ ]+rooms[ ]+(?P&lt;name&gt;.+)$"
  594. enabled="y"
  595. regexp="y"
  596. send_to="12"
  597. sequence="100"
  598. >
  599. <send>export_rooms("%&lt;name&gt;")
  600. </send>
  601. </alias>
  602.  
  603. <alias
  604. match="^mapper[ ]+export[ ]+area[ ]+(?P&lt;name&gt;.+)$"
  605. enabled="y"
  606. regexp="y"
  607. send_to="12"
  608. sequence="100"
  609. >
  610. <send>export_area("%&lt;name&gt;")
  611. </send>
  612. </alias>
  613.  
  614.  
  615. <!-- maintenance - additions -->
  616.  
  617. <alias
  618. match="^mapper[ ]+addroom[ ]+(?P&lt;id&gt;[0-9]+)[ ]+n\:(?P&lt;name&gt;.+) a\:(?P&lt;area&gt;.+) f\:(?P&lt;flags&gt;.+) t\:(?P&lt;terrain&gt;.+) ti\:(?P&lt;terraininfo&gt;.+)$"
  619. enabled="y"
  620. regexp="y"
  621. send_to="12"
  622. sequence="100"
  623. >
  624. <send>map_add_room("%&lt;id&gt;", "%&lt;name&gt;", "%&lt;area&gt;", "%&lt;flags&gt;", "%&lt;terrain&gt;", "%&lt;terraininfo&gt;")
  625. </send>
  626. </alias>
  627.  
  628. <alias
  629. match="^mapper[ ]+addexit[ ]+(?P&lt;dir&gt;[a-z]+)(|[ ]+f\:(?P&lt;fromid&gt;[0-9]+)) t\:(?P&lt;toid&gt;[0-9]+)$"
  630. enabled="y"
  631. regexp="y"
  632. send_to="12"
  633. sequence="100"
  634. >
  635. <send>map_add_exit("%&lt;dir&gt;", "%&lt;fromid&gt;", "%&lt;toid&gt;")
  636. </send>
  637. </alias>
  638.  
  639. <alias
  640. match="^mapper[ ]+addbm(|[ ]+(?P&lt;roomid&gt;[0-9]+))(|[ ]+b\:(?P&lt;book&gt;.+))$"
  641. enabled="y"
  642. regexp="y"
  643. send_to="12"
  644. sequence="100"
  645. >
  646. <send>map_add_bookmark("%&lt;roomid&gt;", "%&lt;book&gt;")
  647. </send>
  648. </alias>
  649.  
  650.  
  651. <!-- maintenance - deletions -->
  652.  
  653. <alias
  654. match="^mapper[ ]+delroom[ ]+(?P&lt;id&gt;[0-9]+)$"
  655. enabled="y"
  656. regexp="y"
  657. send_to="12"
  658. sequence="100"
  659. >
  660. <send>map_del_room("%&lt;id&gt;")
  661. </send>
  662. </alias>
  663.  
  664. <alias
  665. match="^mapper[ ]+delexit[ ]+(?P&lt;dir&gt;[a-z]+)(|[ ]+f\:(?P&lt;fromid&gt;[0-9]+))$"
  666. enabled="y"
  667. regexp="y"
  668. send_to="12"
  669. sequence="100"
  670. >
  671. <send>map_del_exit("%&lt;dir&gt;", "%&lt;fromid&gt;")
  672. </send>
  673. </alias>
  674.  
  675. <alias
  676. match="^mapper[ ]+delexits[ ]+(?P&lt;fromid&gt;[0-9]+)$"
  677. enabled="y"
  678. regexp="y"
  679. send_to="12"
  680. sequence="100"
  681. >
  682. <send>map_del_exits("%&lt;fromid&gt;")
  683. </send>
  684. </alias>
  685.  
  686. <alias
  687. match="^mapper[ ]+delbm(|[ ]+(?P&lt;roomid&gt;[0-9]+))$"
  688. regexp="y"
  689. enabled="y"
  690. send_to="12"
  691. sequence="100"
  692. >
  693. <send>map_del_bookmark("%&lt;roomid&gt;")
  694. </send>
  695. </alias>
  696.  
  697.  
  698. <!-- maintenance - tags -->
  699.  
  700. <alias
  701. match="^mapper[ ]+dt(|[ ]+(?P&lt;id&gt;[0-9]+))$"
  702. enabled="y"
  703. regexp="y"
  704. send_to="12"
  705. sequence="100"
  706. >
  707. <send>map_toggle_tag("%&lt;id&gt;", "dt")
  708. </send>
  709. </alias>
  710.  
  711. <alias
  712. match="^mapper[ ]+trap(|[ ]+(?P&lt;id&gt;[0-9]+))$"
  713. enabled="y"
  714. regexp="y"
  715. send_to="12"
  716. sequence="100"
  717. >
  718. <send>map_toggle_tag("%&lt;id&gt;", "trap")
  719. </send>
  720. </alias>
  721.  
  722. <alias
  723. match="^mapper[ ]+no(|\-)speed(|[ ]+(?P&lt;id&gt;[0-9]+))$"
  724. enabled="y"
  725. regexp="y"
  726. send_to="12"
  727. sequence="100"
  728. >
  729. <send>map_toggle_tag("%&lt;id&gt;", "no-speed")
  730. </send>
  731. </alias>
  732.  
  733. <alias
  734. match="^mapper[ ]+shop(|[ ]+(?P&lt;id&gt;[0-9]+))$"
  735. enabled="y"
  736. regexp="y"
  737. send_to="12"
  738. sequence="100"
  739. >
  740. <send>map_toggle_tag("%&lt;id&gt;", "shop")
  741. </send>
  742. </alias>
  743.  
  744. <alias
  745. match="^mapper[ ]+train(|er)(|[ ]+(?P&lt;id&gt;[0-9]+))$"
  746. enabled="y"
  747. regexp="y"
  748. send_to="12"
  749. sequence="100"
  750. >
  751. <send>map_toggle_tag("%&lt;id&gt;", "trainer")
  752. </send>
  753. </alias>
  754.  
  755.  
  756. <!-- maintenance - privacy -->
  757.  
  758. <alias
  759. enabled="y"
  760. match="^mapper[ ]+purge[ ]+clanhalls$"
  761. regexp="y"
  762. sequence="100"
  763. script="purge_clanhalls"
  764. >
  765. </alias>
  766.  
  767. <alias
  768. enabled="y"
  769. match="^mapper[ ]+purge[ ]+homes$"
  770. regexp="y"
  771. sequence="100"
  772. script="purge_player_homes"
  773. >
  774. </alias>
  775.  
  776. <alias
  777. enabled="y"
  778. match="^mapper[ ]+purge[ ]+bookmarks$"
  779. regexp="y"
  780. sequence="100"
  781. script="purge_notes"
  782. >
  783. </alias>
  784.  
  785.  
  786. <!-- maintenance - rebuild data -->
  787.  
  788. <alias
  789. enabled="y"
  790. match="^mapper[ ]+(?P&lt;cmd&gt;(recreate|upgrade))[ ]+database$"
  791. regexp="y"
  792. send_to="12"
  793. sequence="100"
  794. >
  795. <send>recreate_database("%&lt;cmd&gt;")
  796. </send>
  797. </alias>
  798.  
  799. <alias
  800. enabled="y"
  801. match="^mapper[ ]+rebuild[ ]+lookup$"
  802. regexp="y"
  803. sequence="100"
  804. script="rebuild_lookup"
  805. >
  806. </alias>
  807.  
  808.  
  809. <!-- used by scripts -->
  810.  
  811. <alias
  812. enabled="y"
  813. match="^tprt$"
  814. regexp="y"
  815. send_to="12"
  816. sequence="100"
  817. >
  818. <send>notify_teleport()
  819. </send>
  820. </alias>
  821.  
  822. <alias
  823. enabled="y"
  824. match="^prtl$"
  825. regexp="y"
  826. send_to="12"
  827. sequence="100"
  828. >
  829. <send>notify_portal()
  830. </send>
  831. </alias>
  832.  
  833. <alias
  834. enabled="y"
  835. match="^mapper[ ]+hyper[ ]+(?P&lt;id&gt;[0-9]+)$"
  836. regexp="y"
  837. send_to="12"
  838. sequence="100"
  839. >
  840. <send>map_hyperlink("%&lt;id&gt;")
  841. </send>
  842. </alias>
  843.  
  844.  
  845. <!-- Plugin help -->
  846.  
  847. <alias
  848. enabled="y"
  849. ignore_case="y"
  850. match="^(|MM\_GMCP\_)Mapper(|\_GMCP)(|( |\:)help)$"
  851. regexp="y"
  852. script="OnHelp"
  853. >
  854. </alias>
  855.  
  856. </aliases>
  857.  
  858.  
  859.  
  860. <trigger
  861. enabled="y"
  862. keep_evaluating="y"
  863. match="^You open the (.*) (door|doors|gate|grating|trapdoor).*\.$"
  864. regexp="y"
  865. send_to="12"
  866. sequence="100"
  867. >
  868. <send>local dir = {}
  869. dir['northeast'] = 'ne'
  870. dir['northwest'] = 'nw'
  871. dir['southeast'] = 'se'
  872. dir['southwest'] = 'nw'
  873. if dir[%1] ~= nil then
  874. Execute(dir[%1])
  875. else
  876. Execute(string.sub("%1", 1, 1))
  877. end</send>
  878. </trigger>
  879.  
  880.  
  881. <!-- auto-open doors -->
  882.  
  883. <trigger
  884. enabled="y"
  885. keep_evaluating="y"
  886. match="^(The (.+) (is|are) closed|A strange force blocks your passage)\.$"
  887. regexp="y"
  888. send_to="12"
  889. sequence="100"
  890. >
  891. <send>mapper.auto_open()
  892. </send>
  893. </trigger>
  894.  
  895. <trigger
  896. enabled="y"
  897. keep_evaluating="y"
  898. match="^(.+)\: It\'s locked\.$"
  899. regexp="y"
  900. send_to="12"
  901. sequence="100"
  902. >
  903. <send>mapper.stop_auto_open()
  904. </send>
  905. </trigger>
  906.  
  907.  
  908. <!-- various messages that cancel speedwalks -->
  909.  
  910. <trigger
  911. enabled="y"
  912. match="You are too exhausted. Better rest for a bit."
  913. keep_evaluating="y"
  914. regexp="y"
  915. script="mapper.cancel_speedwalk"
  916. sequence="100"
  917. >
  918. </trigger>
  919.  
  920.  
  921.  
  922.  
  923.  
  924. <!-- Scripts -->
  925.  
  926. <script>
  927.  
  928. local show_vnums = &show_vnums;
  929. local show_timing = &show_timing;
  930. local show_completed = &show_completed;
  931. local verbose_mode = &verbose_mode;
  932. local show_other_areas = &show_other_areas;
  933. local show_up_down = &show_up_down;
  934. local show_area_exits = &show_area_exits;
  935. local speedwalk_prefix = "&speedwalk_prefix;"
  936. local prefer_shown = true
  937.  
  938.  
  939. <![CDATA[
  940.  
  941. require "serialize"
  942. require "copytable"
  943. require "wait"
  944. require "gmcphelper"
  945.  
  946.  
  947. function file_exists(path)
  948. local f = io.open(path, "r")
  949.  
  950. if (f) then
  951. io.close(f)
  952. return true
  953. else
  954. return false
  955. end
  956. end
  957.  
  958.  
  959. if (file_exists(GetInfo(66) .. "lua/mm_mapper.lua")) then
  960. mapper = require "mm_mapper"
  961. else
  962. require "mapper"
  963. end
  964.  
  965.  
  966. rooms = {}
  967. --areas = {}
  968.  
  969. local fontcol = "silver"
  970. local bgcol = "black"
  971.  
  972.  
  973.  
  974. -- --------------
  975. -- plugin stuff
  976. -- --------------
  977.  
  978. function OnPluginInstall()
  979. wait.make(function()
  980. config = {} -- in case not found
  981.  
  982. -- get saved configuration
  983. assert(loadstring(GetVariable("config") or ""))()
  984.  
  985. -- allow for additions to config
  986. for k, v in pairs(default_config) do
  987. config[k] = config[k] or v
  988. end
  989.  
  990. -- initialize mapper
  991. mapper.init {
  992. config = config,
  993. get_room = get_room,
  994. show_help = OnHelp, -- to show help
  995. room_click = room_click, -- called on RH click on room square
  996. timing = show_timing, -- want to see timing
  997. show_completed = show_completed, -- want to see "Speedwalk completed." message
  998. show_other_areas = show_other_areas, -- want to see areas other than the current one?
  999. show_up_down = show_up_down, -- want to follow up/down exits?
  1000. show_area_exits = show_area_exits, -- want to see area exits?
  1001. speedwalk_prefix = speedwalk_prefix, -- how to speedwalk
  1002. }
  1003.  
  1004. mapper.mapprint(string.format("MUSHclient mapper installed, version %0.1f", mapper.VERSION))
  1005.  
  1006. -- open database on disk
  1007. if (file_exists(GetInfo(66) .. "mm_mapper.db"))
  1008. or (not file_exists(GetInfo(66) .. Trim(WorldAddress()) .. "_mapper.db")) then
  1009. db = assert(sqlite3.open(GetInfo(66) .. "mm_mapper.db"))
  1010. compatibility = false
  1011.  
  1012. elseif (file_exists(GetInfo(66) .. Trim(WorldAddress()) .. "_mapper.db")) then
  1013. ColourTell("white", "maroon", "GMCP Mapper WARNING: type ")
  1014. ColourTell("lime", "maroon", "mapper upgrade database")
  1015. ColourNote("white", "maroon", " to convert your old maps database file to the new structure.")
  1016. ColourNote("silver", "black", "(This process may take several minutes, during which the client will seem to be 'frozen'.)")
  1017. ColourNote("white", "maroon", "NOTICE that the mapper might NOT warn you about CPK rooms until you have upgraded the database.")
  1018. db = assert(sqlite3.open(GetInfo(66) .. Trim(WorldAddress()) .. "_mapper.db"))
  1019. compatibility = true
  1020. end
  1021.  
  1022. create_tables() -- create database structure if necessary
  1023.  
  1024. Tell("-- " .. GetPluginInfo(GetPluginID(), 1) .. ": type ")
  1025. ColourTell("silver", "black", GetPluginInfo(GetPluginID(), 1) .. " help")
  1026. Note(" to see info about this plugin --")
  1027.  
  1028. room_not_in_database = {}
  1029.  
  1030. first_room = true
  1031.  
  1032. load_config2()
  1033.  
  1034. -- give the plugins time to initialize
  1035. wait.time(3)
  1036.  
  1037. detect_plugins()
  1038. end)
  1039. end
  1040.  
  1041.  
  1042. function OnPluginSaveState()
  1043. mapper.save_state()
  1044. SetVariable("config", "config = " .. serialize.save_simple(config))
  1045. end
  1046.  
  1047.  
  1048. function OnPluginClose()
  1049. mapper.hide()
  1050. end
  1051.  
  1052.  
  1053. function OnPluginDisable()
  1054. mapper.hide()
  1055. end
  1056.  
  1057.  
  1058. function OnPluginListChanged()
  1059. detect_plugins()
  1060. end
  1061.  
  1062.  
  1063. function detect_plugins()
  1064. use_events_mini = events_mini_installed()
  1065. reader_present = detect_reader()
  1066. sapi_present = sapi_plugin_present()
  1067. end
  1068.  
  1069.  
  1070. function is_plugin_present(name, id)
  1071. local res = false
  1072.  
  1073. local plugin_name = GetPluginInfo(id, 1)
  1074.  
  1075. if (plugin_name == name) then
  1076. -- is it enabled?
  1077. if (GetPluginInfo(id, 17)) then
  1078. res = true
  1079. end
  1080. end
  1081.  
  1082. return res
  1083. end
  1084.  
  1085.  
  1086. function plugin_update_url()
  1087. local t = {
  1088. "https://raw.githubusercontent.com/mu3r73/mm-mushclient-scripts/master/src/MM_GMCP_Mapper_GMCP.xml",
  1089. }
  1090. return (table.concat(t, ";"))
  1091. end
  1092.  
  1093.  
  1094. function plugin_update_aux_url()
  1095. local t = {
  1096. "https://raw.githubusercontent.com/mu3r73/mm-mushclient-scripts/master/src/mm_mapper.lua,MUSH/lua",
  1097. }
  1098. return (table.concat(t, ";"))
  1099. end
  1100.  
  1101.  
  1102.  
  1103. ---------
  1104. -- help
  1105. ---------
  1106.  
  1107. function OnHelp()
  1108. mapper.mapprint(string.format("[MUSHclient mapper, version %0.1f]", mapper.VERSION))
  1109. ColourNote("silver", "black", world.GetPluginInfo(world.GetPluginID(), 3))
  1110. Note("")
  1111. ColourNote("silver", "black", "(this version: " .. os.date("%c", GetPluginInfo(GetPluginID(), 14)) .. ")")
  1112. end
  1113.  
  1114.  
  1115. function help_maintenance()
  1116. ColourNote("silver", "black", world.GetPluginInfo(world.GetPluginID(), 3))
  1117. ColourNote("silver", "black", [[> Advanced Maintenance/Privacy Aliases
  1118.  
  1119. > config:
  1120.  
  1121. * mapper reset defaults - use to restore default settings, if necessary
  1122. * mapper show database mods [on|off] - toggle showing database updates on/off (on by default)
  1123.  
  1124. > queries:
  1125.  
  1126. * mapper roominfo [<room#>] - show info about a room
  1127.  
  1128. * mapper export rooms <name> - exports all rooms matching the name
  1129. * mapper export area <name> - exports a whole area
  1130.  
  1131. > additions:
  1132.  
  1133. * mapper addroom <room#> n:<name> a:<area> f:<flags> t:<terrain> ti:<terraininfo> - add a room
  1134.  
  1135. * mapper addexit <dir> [f:<from_room#>] t:<to_room#> - add an exit to a room
  1136.  
  1137. * mapper addbm [<room#>] [b:<text>] - add a bookmark
  1138.  
  1139. > deletions:
  1140.  
  1141. * mapper delroom <room#> - delete a room
  1142.  
  1143. * mapper delexit <dir> [f:<from_room#>] - delete an exit from a room
  1144. * mapper delexits <from_room#> - delete all exits from a room
  1145.  
  1146. * mapper delbm [<room#>] - delete a bookmark
  1147.  
  1148. > tags:
  1149.  
  1150. * mapper dt [<room#>] - tag room as DT
  1151. * mapper trap [<room#>] - tag room as trap
  1152. * mapper no-speed [<room#>] - tag room as no-speed
  1153. * mapper shop [<room#>] - tag room as shop
  1154. * mapper trainer [<room#>] - tag room as trainer
  1155.  
  1156. > privacy:
  1157.  
  1158. * mapper purge clanhalls - purge clanhalls data from the database
  1159. * mapper purge homes - purge player homes data from the database
  1160. * mapper purge bookmarks - purge all non-vmap notes from the database
  1161.  
  1162. > rebuild data:
  1163.  
  1164. * mapper recreate database - copy data to a new database file
  1165. * mapper rebuild lookup - rebuild the rooms_lookup table
  1166.  
  1167. ]])
  1168.  
  1169. end
  1170.  
  1171.  
  1172.  
  1173. -- ---------------
  1174. -- GMCP broadcast
  1175. -- ---------------
  1176.  
  1177. function OnPluginBroadcast(msg, id, name, text)
  1178. if (id =="f67c4339ed0591a5b010d05b") then -- GMCP message
  1179. if (text == "room.info") then -- room.info
  1180. peeking = false
  1181. purge_cache_if_area_changed()
  1182.  
  1183. get_gmcp_room()
  1184. process_room()
  1185. end
  1186. end
  1187. end
  1188.  
  1189.  
  1190.  
  1191. ---------------
  1192. -- GMCP stuff
  1193. ---------------
  1194.  
  1195. function get_gmcp_room()
  1196. local res, gmcparg = CallPlugin("f67c4339ed0591a5b010d05b", "gmcpval", "room.info")
  1197. luastmt = "gmcpdata = " .. gmcparg
  1198.  
  1199. assert(loadstring(luastmt or ""))()
  1200. end
  1201.  
  1202.  
  1203.  
  1204. -- ----------------------
  1205. -- default configuration
  1206. -- ----------------------
  1207.  
  1208. function reset_defaults()
  1209. config = {}
  1210.  
  1211. for k, v in pairs(default_config) do
  1212. config[k] = v
  1213. end
  1214.  
  1215. -- initialize mapper
  1216. mapper.init {
  1217. config = config,
  1218. get_room = get_room,
  1219. show_help = OnHelp, -- to show help
  1220. room_click = room_click, -- called on RH click on room square
  1221. timing = show_timing, -- want to see timing
  1222. show_completed = show_completed, -- want to see "Speedwalk completed." message
  1223. show_other_areas = show_other_areas, -- want to see areas other than the current one?
  1224. show_up_down = show_up_down, -- want to follow up/down exits?
  1225. show_area_exits = show_area_exits, -- want to see area exits?
  1226. speedwalk_prefix = speedwalk_prefix, -- how to speedwalk
  1227. }
  1228. end
  1229.  
  1230.  
  1231. default_config = {
  1232. -- assorted colours
  1233. BACKGROUND_COLOUR = {
  1234. name = "Background",
  1235. colour = ColourNameToRGB "cadetblue",
  1236. },
  1237. ROOM_COLOUR = {
  1238. name = "Room",
  1239. colour = ColourNameToRGB "cyan",
  1240. },
  1241. EXIT_COLOUR = {
  1242. name = "Exit",
  1243. colour = ColourNameToRGB "darkgreen",
  1244. },
  1245. EXIT_COLOUR_UP_DOWN = {
  1246. name = "Exit up/down",
  1247. colour = ColourNameToRGB "darkmagenta",
  1248. },
  1249. OUR_ROOM_COLOUR = {
  1250. name = "Our room",
  1251. colour = ColourNameToRGB "black",
  1252. },
  1253. UNKNOWN_ROOM_COLOUR = {
  1254. name = "Unknown room",
  1255. colour = ColourNameToRGB "#00CACA",
  1256. },
  1257. DIFFERENT_AREA_COLOUR = {
  1258. name = "Another area",
  1259. colour = ColourNameToRGB "gray",
  1260. },
  1261. DT_FILL_COLOUR = {
  1262. name = "DT",
  1263. colour = ColourNameToRGB "black",
  1264. },
  1265. SAFE_FILL_COLOUR = {
  1266. name = "Safe",
  1267. colour = ColourNameToRGB "white",
  1268. },
  1269. SHOP_FILL_COLOUR = {
  1270. name = "Shop",
  1271. colour = ColourNameToRGB "yellow",
  1272. },
  1273. TRAINER_FILL_COLOUR = {
  1274. name = "Trainer",
  1275. colour = ColourNameToRGB "mediumpurple"
  1276. },
  1277. LPK_FILL_COLOUR = {
  1278. name = "LPK",
  1279. colour = ColourNameToRGB "lightcoral"
  1280. },
  1281. NPK_FILL_COLOUR = {
  1282. name = "NPK",
  1283. colour = ColourNameToRGB "tomato"
  1284. },
  1285. CPK_FILL_COLOUR = {
  1286. name = "CPK",
  1287. colour = ColourNameToRGB "darkred"
  1288. },
  1289. DIZZY_COLOUR = {
  1290. name = "Dizzy",
  1291. colour = ColourNameToRGB "blue"
  1292. },
  1293. FEAR_COLOUR = {
  1294. name = "Fear",
  1295. colour = ColourNameToRGB "yellow"
  1296. },
  1297. TRAP_COLOUR = {
  1298. name = "Dizzy",
  1299. colour = ColourNameToRGB "red"
  1300. },
  1301. DIGGABLE_FILL_COLOUR = {
  1302. name = "diggable",
  1303. colour = ColourNameToRGB "wheat"
  1304. },
  1305. WOODED_FILL_COLOUR = {
  1306. name = "wooded",
  1307. colour = ColourNameToRGB "seagreen"
  1308. },
  1309. UNDERWATER_FILL_COLOUR = {
  1310. name = "underwater",
  1311. colour = ColourNameToRGB "steelblue"
  1312. },
  1313. FREEZING_FILL_COLOUR = {
  1314. name = "freezing",
  1315. colour = ColourNameToRGB "lightcyan"
  1316. },
  1317. FIRE_FILL_COLOUR = {
  1318. name = "fire",
  1319. colour = ColourNameToRGB "red"
  1320. },
  1321. POISON_FILL_COLOUR = {
  1322. name = "poison-gas",
  1323. colour = ColourNameToRGB "yellowgreen"
  1324. },
  1325. ACID_FILL_COLOUR = {
  1326. name = "acid",
  1327. colour = ColourNameToRGB "greenyellow"
  1328. },
  1329. NOTHING_FILL_COLOUR = {
  1330. name = "nothing",
  1331. colour = ColourNameToRGB "deepskyblue"
  1332. },
  1333.  
  1334. ROOM_NAME_TEXT = {
  1335. name = "Room name text",
  1336. colour = ColourNameToRGB "#BEF3F1",
  1337. },
  1338. ROOM_NAME_FILL = {
  1339. name = "Room name fill",
  1340. colour = ColourNameToRGB "#105653",
  1341. },
  1342. ROOM_NAME_BORDER = {
  1343. name = "Room name box",
  1344. colour = ColourNameToRGB "black",
  1345. },
  1346.  
  1347. AREA_NAME_TEXT = {
  1348. name = "Area name text",
  1349. colour = ColourNameToRGB "#BEF3F1",
  1350. },
  1351. AREA_NAME_FILL = {
  1352. name = "Area name fill",
  1353. colour = ColourNameToRGB "#105653",
  1354. },
  1355. AREA_NAME_BORDER = {
  1356. name = "Area name box",
  1357. colour = ColourNameToRGB "black",
  1358. },
  1359.  
  1360. FONT = {
  1361. name = get_preferred_font {
  1362. "Dina",
  1363. "Lucida Console",
  1364. "Fixedsys",
  1365. "Courier",
  1366. "Sylfaen",
  1367. },
  1368. size = 8.
  1369. },
  1370.  
  1371. -- size of map window
  1372. WINDOW = {
  1373. width = 400,
  1374. height = 261
  1375. },
  1376.  
  1377. -- how far from where we are standing to draw (rooms)
  1378. SCAN = {
  1379. depth = 250
  1380. },
  1381.  
  1382. -- speedwalk delay
  1383. DELAY = {
  1384. time = 0
  1385. },
  1386.  
  1387. -- how many seconds to show "recent visit" lines (default 3 minutes)
  1388. LAST_VISIT_TIME = {
  1389. time = 60 * 3
  1390. },
  1391. }
  1392.  
  1393.  
  1394.  
  1395. -- -----------------
  1396. -- specific config
  1397. -- -----------------
  1398.  
  1399. function load_config2()
  1400. config2 = {
  1401. visible = ((GetVariable("mapper_visible") or "true") == "true"),
  1402. auto_open = ((GetVariable("auto_open") or "true") == "true"),
  1403. safewalk = ((GetVariable("safewalk") or "false") == "true"),
  1404. color_terrain = ((GetVariable("color_terrain") or "false") == "true"),
  1405. do_map_wilds = ((GetVariable("do_map_wilds") or "false") == "true"),
  1406. show_database_mods = ((GetVariable("show_database_mods") or "true") == "true"),
  1407. show_flags = ((GetVariable("show_flags") or "false") == "true"),
  1408. show_numbers = ((GetVariable("show_numbers") or "false") == "true"),
  1409. vis_road_exits = ((GetVariable("vis_road_exits") or "false") == "true"),
  1410. vis_unmapped_exits = ((GetVariable("vis_unmapped_exits") or "false") == "true"),
  1411. draw_other_floors = ((GetVariable("draw_other_floors") or "true") == "true"),
  1412. -- this last variable overrides config.show_up_down
  1413. }
  1414.  
  1415. if (not config2.visible) then
  1416. mapper.hide()
  1417. end
  1418. end
  1419.  
  1420.  
  1421. function save_config2()
  1422. SetVariable("mapper_visible", tostring(config2.visible))
  1423. SetVariable("auto_open", tostring(config2.auto_open))
  1424. SetVariable("safewalk", tostring(config2.safewalk))
  1425. SetVariable("color_terrain", tostring(config2.color_terrain))
  1426. SetVariable("do_map_wilds", tostring(config2.do_map_wilds))
  1427. SetVariable("show_database_mods", tostring(config2.show_database_mods))
  1428. SetVariable("show_flags", tostring(config2.show_flags))
  1429. SetVariable("show_numbers", tostring(config2.show_numbers))
  1430. SetVariable("vis_road_exits", tostring(config2.vis_road_exits))
  1431. SetVariable("vis_unmapped_exits", tostring(config2.vis_unmapped_exits))
  1432. SetVariable("draw_other_floors", tostring(config2.draw_other_floors))
  1433.  
  1434. SaveState()
  1435. end
  1436.  
  1437.  
  1438.  
  1439. -- ---------------------------
  1440. -- mapper 'get_room' callback
  1441. -- ---------------------------
  1442.  
  1443. function get_room(uid)
  1444. -- check we got room at all
  1445. if (not uid) then
  1446. return nil
  1447. end
  1448.  
  1449. -- look it up
  1450. local ourroom = rooms[uid]
  1451.  
  1452. -- not cached - see if in database
  1453. if (not ourroom) then
  1454. ourroom = load_room_from_database(uid)
  1455. end -- not in cache
  1456.  
  1457. if (not ourroom) then
  1458. return nil
  1459. end
  1460.  
  1461. local room = copytable.deep(ourroom)
  1462.  
  1463. -- build hover message
  1464.  
  1465. local flags = room.flags
  1466. if (not flags) or (flags == "") then
  1467. flags = "-"
  1468. end
  1469.  
  1470. local terrain = room.terrain
  1471. if (not terrain) or (terrain == "") then
  1472. terrain = "-"
  1473. end
  1474.  
  1475. local terraininfo = room.terraininfo
  1476. if (not terraininfo) or (terraininfo == "") then
  1477. terraininfo = "-"
  1478. end
  1479.  
  1480. local notes = room.notes
  1481. if (not room.notes) or (room.notes == "") then
  1482. notes = "-"
  1483. end -- if notes
  1484.  
  1485. local tags = room.tags
  1486. if (not tags) or (room.tags == "") then
  1487. tags = "-"
  1488. end -- if DT
  1489.  
  1490. local texits = {}
  1491. for dir in pairs(room.exits) do
  1492. table.insert(texits, dir)
  1493. end -- for
  1494. table.sort(texits)
  1495.  
  1496. room.hovermessage = string.format(
  1497. "%s\tExits: %s\nGMCP #: %s\nFlags: %s\nTerrain: %s (%s)\nTags: %s\nBookmarks: %s",
  1498. room.name,
  1499. table.concat(texits, ", "),
  1500. uid,
  1501. flags,
  1502. terrain,
  1503. terraininfo,
  1504. tags,
  1505. notes
  1506. )
  1507.  
  1508. room.bordercolour = config.ROOM_COLOUR.colour
  1509. room.borderpen = 0 -- solid
  1510. room.borderpenwidth = 1
  1511.  
  1512. -- special room fill colours
  1513.  
  1514. if (has_flag(room.flags, "safe")) then
  1515. room.fillcolour = config.SAFE_FILL_COLOUR.colour
  1516. room.fillbrush = 8
  1517.  
  1518. elseif (has_flag(room.flags, "player-kill-chaotic")) then
  1519. room.fillcolour = config.CPK_FILL_COLOUR.colour
  1520. room.fillbrush = 8
  1521.  
  1522. elseif (has_tag(room.tags, "dt")) then
  1523. room.fillcolour = config.DT_FILL_COLOUR.colour
  1524. room.fillbrush = 8
  1525.  
  1526. elseif (has_tag(room.tags, "trainer")) then
  1527. room.fillcolour = config.TRAINER_FILL_COLOUR.colour
  1528. room.fillbrush = 8
  1529.  
  1530. elseif (has_tag(room.tags, "shop")) then
  1531. room.fillcolour = config.SHOP_FILL_COLOUR.colour
  1532. room.fillbrush = 8
  1533.  
  1534. elseif (has_flag(room.flags, "player-kill-neutral")) then
  1535. room.fillcolour = config.NPK_FILL_COLOUR.colour
  1536. room.fillbrush = 8
  1537.  
  1538. elseif (has_flag(room.flags, "player-kill-lawful")) then
  1539. room.fillcolour = config.LPK_FILL_COLOUR.colour
  1540. room.fillbrush = 8
  1541.  
  1542. elseif (string.find(terraininfo, "underwater")) then
  1543. room.fillcolour = config.UNDERWATER_FILL_COLOUR.colour
  1544. room.fillbrush = 8
  1545.  
  1546. elseif (string.find(terraininfo, "wooded")) then
  1547. room.fillcolour = config.WOODED_FILL_COLOUR.colour
  1548. room.fillbrush = 8
  1549.  
  1550. elseif (string.find(terraininfo, "freezing")) then
  1551. room.fillcolour = config.FREEZING_FILL_COLOUR.colour
  1552. room.fillbrush = 8
  1553.  
  1554. elseif (string.find(terraininfo, "fire")) then
  1555. room.fillcolour = config.FIRE_FILL_COLOUR.colour
  1556. room.fillbrush = 8
  1557.  
  1558. elseif (string.find(terraininfo, "poison")) then
  1559. room.fillcolour = config.POISON_FILL_COLOUR.colour
  1560. room.fillbrush = 8
  1561.  
  1562. elseif (string.find(terraininfo, "acid")) then
  1563. room.fillcolour = config.ACID_FILL_COLOUR.colour
  1564. room.fillbrush = 8
  1565.  
  1566. elseif (string.find(terraininfo, "diggable")) then
  1567. room.fillcolour = config.DIGGABLE_FILL_COLOUR.colour
  1568. room.fillbrush = 8
  1569.  
  1570. elseif (string.find(terraininfo, "nothing")) then
  1571. room.fillcolour = config.NOTHING_FILL_COLOUR.colour
  1572. room.fillbrush = 8
  1573.  
  1574. else
  1575. room.fillcolour = 0xff0000
  1576. room.fillbrush = 1 -- no fill
  1577. end
  1578.  
  1579. -- terrain is always shown in non-pk
  1580. -- however, in all-pk areas, pk colors prevail over terrain colors
  1581. -- config2.color_terrain toggles terrain coloring for pk areas
  1582. if (config2.color_terrain) then
  1583. if (string.find(terraininfo, "underwater")) then
  1584. room.fillcolour = config.UNDERWATER_FILL_COLOUR.colour
  1585. room.fillbrush = 8
  1586.  
  1587. elseif (string.find(terraininfo, "wooded")) then
  1588. room.fillcolour = config.WOODED_FILL_COLOUR.colour
  1589. room.fillbrush = 8
  1590.  
  1591. elseif (string.find(terraininfo, "freezing")) then
  1592. room.fillcolour = config.FREEZING_FILL_COLOUR.colour
  1593. room.fillbrush = 8
  1594.  
  1595. elseif (string.find(terraininfo, "fire")) then
  1596. room.fillcolour = config.FIRE_FILL_COLOUR.colour
  1597. room.fillbrush = 8
  1598.  
  1599. elseif (string.find(terraininfo, "poison")) then
  1600. room.fillcolour = config.POISON_FILL_COLOUR.colour
  1601. room.fillbrush = 8
  1602.  
  1603. elseif (string.find(terraininfo, "acid")) then
  1604. room.fillcolour = config.ACID_FILL_COLOUR.colour
  1605. room.fillbrush = 8
  1606.  
  1607. elseif (string.find(terraininfo, "diggable")) then
  1608. room.fillcolour = config.DIGGABLE_FILL_COLOUR.colour
  1609. room.fillbrush = 8
  1610.  
  1611. elseif (string.find(terraininfo, "nothing")) then
  1612. room.fillcolour = config.NOTHING_FILL_COLOUR.colour
  1613. room.fillbrush = 8
  1614.  
  1615. else
  1616. room.fillcolour = 0xff0000
  1617. room.fillbrush = 1 -- no fill
  1618. end
  1619. end -- config2.color_terrain
  1620.  
  1621. if (room.area ~= current_area) then
  1622. room.bordercolour = config.DIFFERENT_AREA_COLOUR.colour
  1623.  
  1624. elseif (has_tag(room.tags, "trap")) then
  1625. room.bordercolour = config.TRAP_COLOUR.colour
  1626.  
  1627. elseif (has_flag(room.flags, "disorient")) then
  1628. room.bordercolour = config.DIZZY_COLOUR.colour
  1629.  
  1630. elseif (has_flag(room.flags, "fear")) then
  1631. room.bordercolour = config.FEAR_COLOUR.colour
  1632. end
  1633.  
  1634. if (uid == current_room) then
  1635. if (not has_flag(room.flags, "disorient"))
  1636. and (not has_flag(room.flags, "fear")) then
  1637. room.bordercolour = config.OUR_ROOM_COLOUR.colour
  1638. end
  1639. room.borderpenwidth = 2
  1640. end
  1641.  
  1642. return room
  1643. end
  1644.  
  1645.  
  1646.  
  1647. ----------------------
  1648. -- gui main function
  1649. ----------------------
  1650.  
  1651. function room_click(uid, flags)
  1652. -- check we got room at all
  1653. if (not uid) then
  1654. return nil
  1655. end
  1656.  
  1657. -- look it up
  1658. local room = rooms[uid]
  1659.  
  1660. -- not cached - see if in database
  1661. if (not room) then
  1662. room = load_room_from_database(uid)
  1663. end -- not in cache
  1664.  
  1665. if (not room) then
  1666. return
  1667. end -- if still not there
  1668.  
  1669. local handlers = {
  1670. { name = "Edit bookmark", func = room_edit_bookmark} ,
  1671. { name = "-", } ,
  1672. { name = "Add Exit", func = room_add_exit} ,
  1673. { name = "Change Exit", func = room_change_exit} ,
  1674. { name = "Delete Exit", func = room_delete_exit} ,
  1675. { name = "-", } ,
  1676. { name = "Toggle DT", func = room_toggle_tag, tag = "dt" } ,
  1677. { name = "Toggle No-Speed", func = room_toggle_tag, tag = "no-speed" } ,
  1678. { name = "Toggle Shop", func = room_toggle_tag, tag = "shop" } ,
  1679. { name = "Toggle Trainer", func = room_toggle_tag, tag = "trainer" } ,
  1680. { name = "Toggle Trap", func = room_toggle_tag, tag = "trap" } ,
  1681. } -- handlers
  1682.  
  1683. local t, tf = {}, {}
  1684. for _, v in pairs(handlers) do
  1685. table.insert(t, v.name)
  1686. tf[v.name] = v
  1687. end -- for
  1688.  
  1689. local choice = WindowMenu(mapper.win,
  1690. WindowInfo(mapper.win, 14),
  1691. WindowInfo(mapper.win, 15),
  1692. table.concat(t, "|"))
  1693.  
  1694. local f = tf[choice]
  1695.  
  1696. if f then
  1697. f.func(room, uid, f.tag)
  1698. end -- if handler found
  1699. end
  1700.  
  1701.  
  1702.  
  1703. --------------------
  1704. -- interface stuff
  1705. --------------------
  1706.  
  1707. function mapper_show(prefer)
  1708. config2.visible = true
  1709. save_config2()
  1710.  
  1711. if (prefer) then
  1712. prefer_shown = true
  1713. end
  1714.  
  1715. if (prefer_shown) then
  1716. mapper.show()
  1717. end
  1718. end
  1719.  
  1720.  
  1721. function mapper_hide(prefer)
  1722. config2.visible = false
  1723. save_config2()
  1724.  
  1725. if (prefer) then
  1726. prefer_shown = false
  1727. end
  1728.  
  1729. mapper.hide()
  1730. end
  1731.  
  1732.  
  1733. function toggle_terrain_to(status)
  1734. config2.color_terrain = do_toggle(config2.color_terrain, status)
  1735.  
  1736. save_config2()
  1737.  
  1738. if (config2.color_terrain) then
  1739. Note("-- MM_GMCP_Mapper: showing terrain color only --")
  1740. else
  1741. Note("-- MM_GMCP_Mapper: PK/shop/trainer color supersedes terrain color --")
  1742. end
  1743.  
  1744. mapper.draw(current_room)
  1745. end
  1746.  
  1747.  
  1748. function toggle_vis_flags_to(status)
  1749. config2.show_flags = do_toggle(config2.show_flags, status)
  1750.  
  1751. save_config2()
  1752.  
  1753. if (config2.show_flags) then
  1754. Note("-- MM_GMCP_Mapper: showing room flags and terrain ON --")
  1755. else
  1756. Note("-- MM_GMCP_Mapper: showing room flags and terrain OFF --")
  1757. end
  1758. end
  1759.  
  1760.  
  1761. function toggle_vis_number_to(status)
  1762. config2.show_numbers = do_toggle(config2.show_numbers, status)
  1763.  
  1764. save_config2()
  1765.  
  1766. if (config2.show_numbers) then
  1767. Note("-- MM_GMCP_Mapper: showing and logging room numbers ON --")
  1768. else
  1769. Note("-- MM_GMCP_Mapper: showing and logging room numbers OFF --")
  1770. end
  1771. end
  1772.  
  1773.  
  1774. function toggle_vis_road_exits_to(status)
  1775. config2.vis_road_exits = do_toggle(config2.vis_road_exits, status)
  1776.  
  1777. save_config2()
  1778.  
  1779. if (config2.vis_road_exits) then
  1780. Note("-- MM_GMCP_Mapper: showing road exits ON --")
  1781. else
  1782. Note("-- MM_GMCP_Mapper: showing road exits OFF --")
  1783. end
  1784. end
  1785.  
  1786.  
  1787. function toggle_vis_unmapped_to(status)
  1788. config2.vis_unmapped_exits = do_toggle(config2.vis_unmapped_exits, status)
  1789.  
  1790. save_config2()
  1791.  
  1792. if (config2.vis_unmapped_exits) then
  1793. Note("-- MM_GMCP_Mapper: showing unmapped exits ON --")
  1794. else
  1795. Note("-- MM_GMCP_Mapper: showing unmapped exits OFF --")
  1796. end
  1797. end
  1798.  
  1799.  
  1800. function toggle_draw_other_floors_to(status)
  1801. config2.draw_other_floors = do_toggle(config2.draw_other_floors, status)
  1802.  
  1803. save_config2()
  1804.  
  1805. if (config2.draw_other_floors) then
  1806. mapper.toggle_show_up_down(true)
  1807. Note("-- MM_GMCP_Mapper: drawing other floors ON --")
  1808. else
  1809. mapper.toggle_show_up_down(false)
  1810. Note("-- MM_GMCP_Mapper: drawing other floors OFF --")
  1811. end
  1812. end
  1813.  
  1814.  
  1815. function toggle_auto_open_to(status)
  1816. config2.auto_open = do_toggle(config2.auto_open, status)
  1817.  
  1818. save_config2()
  1819.  
  1820. if (config2.auto_open) then
  1821. Note("-- MM_GMCP_Mapper: auto-open doors ON --")
  1822. else
  1823. Note("-- MM_GMCP_Mapper: auto-open doors OFF --")
  1824. end
  1825. end
  1826.  
  1827.  
  1828. function toggle_safewalk_to(status)
  1829. config2.safewalk = do_toggle(config2.safewalk, status)
  1830.  
  1831. save_config2()
  1832.  
  1833. if (config2.safewalk) then
  1834. Note("-- MM_GMCP_Mapper: safewalk mode ON --")
  1835. else
  1836. Note("-- MM_GMCP_Mapper: safewalk mode OFF --")
  1837. end
  1838. end
  1839.  
  1840.  
  1841. function toggle_show_database_mods_to(status)
  1842. config2.show_database_mods = do_toggle(config2.show_database_mods, status)
  1843.  
  1844. save_config2()
  1845.  
  1846. if (config2.show_database_mods) then
  1847. Note("-- MM_GMCP_Mapper: showing database mods ON --")
  1848. else
  1849. Note("-- MM_GMCP_Mapper: showing database mods OFF --")
  1850. end
  1851. end
  1852.  
  1853.  
  1854. function do_toggle(var, status)
  1855. if (status == "on") then
  1856. var = true
  1857. elseif (status == "off") then
  1858. var = false
  1859. else
  1860. var = not var
  1861. end
  1862.  
  1863. return var
  1864. end
  1865.  
  1866.  
  1867. function check_if_show_flags_and_terrain(flags, terrain)
  1868. if (config2.show_flags) then
  1869. show_flags_and_terrain(flags, terrain)
  1870. end
  1871. end
  1872.  
  1873.  
  1874. function show_flags_and_terrain(flags, terrain)
  1875. local show_flags = flags
  1876. if (not show_flags) or (show_flags == "") then
  1877. show_flags = "-"
  1878. end
  1879.  
  1880. local show_terrain = terrain
  1881. if (not show_terrain) or (show_terrain == "") then
  1882. show_terrain = "-"
  1883. end
  1884.  
  1885. Note("[gmcp: " .. show_flags .. " / " .. show_terrain .. "]")
  1886. end
  1887.  
  1888.  
  1889. function check_if_show_room_number(exits)
  1890. local texits = utils.split(Trim(exits), " ")
  1891.  
  1892. if (config2.show_numbers) or (texits[1] == "?") or (texits[1] == "None.") then
  1893. show_room_number()
  1894. end
  1895. end
  1896.  
  1897.  
  1898. function show_room_number()
  1899. if (uid) then
  1900. Note("[gmcp #" .. uid .. "]")
  1901. WriteLog("[gmcp #" .. uid .. "]")
  1902. end
  1903. end
  1904.  
  1905.  
  1906. function check_if_show_road_exits()
  1907. if (config2.vis_road_exits) and (is_vmap()) then
  1908. show_road_exits()
  1909. end
  1910. end
  1911.  
  1912.  
  1913. function show_road_exits()
  1914. local dest, room, ok_exits
  1915.  
  1916. ok_exits = {}
  1917.  
  1918. for dir in string.gmatch(exits_str, "%a+") do
  1919. dest = gmcpval("exits." .. dir)
  1920.  
  1921. room = load_room_from_database(dest)
  1922.  
  1923. if (room) then
  1924. ok_exits[#ok_exits + 1] = capitalize(dir)
  1925. end
  1926. end -- for each exit
  1927.  
  1928. ok_exits = Trim(table.concat(ok_exits, " "))
  1929.  
  1930. if (ok_exits ~= "") then
  1931. Tell(" on-road exits: ")
  1932. ColourNote("silver", "black", ok_exits)
  1933. end
  1934. end
  1935.  
  1936.  
  1937. function check_if_show_unmapped_exits()
  1938. if (config2.vis_unmapped_exits) and (not is_vmap()) then
  1939. show_unmapped_exits()
  1940. end
  1941. end
  1942.  
  1943.  
  1944. function show_unmapped_exits()
  1945. local dest, room, ok_exits
  1946.  
  1947. unmapped_exits = {}
  1948. one_way_exits = {}
  1949.  
  1950. local uid = gmcpval("num")
  1951.  
  1952. for dir in string.gmatch(exits_str, "%a+") do
  1953. dest = gmcpval("exits." .. dir)
  1954.  
  1955. room = load_room_from_database(dest)
  1956.  
  1957. if (not room) then
  1958. unmapped_exits[#unmapped_exits + 1] = capitalize(dir)
  1959.  
  1960. else
  1961. local links_back = false
  1962.  
  1963. -- Tell("exits from " .. dest .. ": ")
  1964. -- Note(serialize.save_simple(room.exits))
  1965.  
  1966. for dir, num in pairs(room.exits) do
  1967. if (num == uid) then
  1968. links_back = true
  1969. break
  1970. end
  1971. end
  1972.  
  1973. if (not links_back) then
  1974. one_way_exits[#one_way_exits + 1] = capitalize(dir)
  1975. end
  1976. end
  1977. end -- for each exit
  1978.  
  1979. unmapped_exits = Trim(table.concat(unmapped_exits, " "))
  1980. if (unmapped_exits ~= "") then
  1981. Tell(" unmapped exits: ")
  1982. ColourNote("silver", "black", unmapped_exits)
  1983. end
  1984.  
  1985. one_way_exits = Trim(table.concat(one_way_exits, " "))
  1986. if (one_way_exits ~= "") then
  1987. Tell(" one way exits: ")
  1988. ColourNote("silver", "black", one_way_exits)
  1989. end
  1990. end
  1991.  
  1992.  
  1993. function peek_room(id)
  1994. local room = load_room_from_database(id)
  1995.  
  1996. if (room) then -- room is in the map
  1997. peeking = true
  1998. peeking_from = id
  1999. Send("rest")
  2000. mapper.mapprint("Peeking room", id, "... Type 'look' to return to normal view.")
  2001. if (verbose_mode) then
  2002. Note("(making you rest so if you click on a room, you won't start a wrong speedwalk)")
  2003. end
  2004. mapper.draw(id)
  2005.  
  2006. else
  2007. mapper.mapprint("The room", id, "isn't in the map.")
  2008. end
  2009. end
  2010.  
  2011.  
  2012. function notify_teleport()
  2013. Note("-- mapper: wait for teleport... --")
  2014. end
  2015.  
  2016.  
  2017. function notify_portal()
  2018. Note("-- mapper: enter portal/mirror/gate/etching/... --")
  2019.  
  2020. BroadcastPlugin(1, "portal")
  2021. end
  2022.  
  2023.  
  2024.  
  2025. ------------
  2026. -- queries
  2027. ------------
  2028.  
  2029. function map_where(rname)
  2030. local sname = fixsql("%" .. string.upper(rname) .. "%")
  2031. local t = {}
  2032.  
  2033. for row in db:nrows(string.format("SELECT uid, area FROM rooms WHERE UPPER(name) like %s", sname)) do
  2034. if (not is_vmap(row.area)) then
  2035. t[#t + 1] = row.uid
  2036. end
  2037. end -- finding rooms
  2038.  
  2039. ColourNote("lightgreen", "black", "Results for: '" .. rname .. "':")
  2040. show_hyperlinks(t)
  2041. if (verbose_mode) then
  2042. ColourNote("lightgreen", "black", "Click on a room's name or type 'mapper goto <id>' to speedwalk to the room, if possible.")
  2043. end
  2044. end
  2045.  
  2046.  
  2047. function map_wheree(rname, area)
  2048. local sname = fixsql(string.upper(rname))
  2049. local t = {}
  2050.  
  2051. area = Trim(area)
  2052.  
  2053. for row in db:nrows(string.format("SELECT uid, area FROM rooms WHERE UPPER(name) = %s", sname)) do
  2054. if (not is_vmap(row.area)) and (area ~= "") then
  2055. if (string.lower(row.area) == string.lower(area)) then
  2056. t[#t + 1] = row.uid
  2057. end
  2058. else
  2059. t[#t + 1] = row.uid
  2060. end
  2061. end -- finding rooms
  2062.  
  2063. ColourTell("lightgreen", "black", "Results for: '" .. rname .. "'")
  2064. if (area ~= "") then
  2065. ColourNote("lightgreen", "black", " in the area: '" .. area .. "':")
  2066. else
  2067. ColourNote("lightgreen", "black", ":")
  2068. end
  2069.  
  2070. show_hyperlinks(t)
  2071.  
  2072. if (area ~= "") then
  2073. ColourTell("lightgreen", "black", "Click ")
  2074. Hyperlink("mapper wheree " .. rname, "[here]", "", "lightgreen", "black", false)
  2075. ColourNote("lightgreen", "black", " or type 'mapper wheree " .. rname .. "' to repeat the search without area restrictions.")
  2076. end
  2077. end
  2078.  
  2079.  
  2080. function get_room_areas(rname)
  2081. local sname = fixsql(string.upper(rname))
  2082. local t = {}
  2083.  
  2084. for row in db:nrows(string.format("SELECT area FROM rooms WHERE UPPER(name) = %s", sname)) do
  2085. t[#t + 1] = row.area
  2086. end -- finding rooms
  2087.  
  2088. return table.concat(t, ";")
  2089. end
  2090.  
  2091.  
  2092. function map_find(keywords)
  2093. if (not peeking) then
  2094. local rooms = {}
  2095. local count = 0
  2096. local snippets = {}
  2097. local reset = ANSI(0)
  2098. local bold = ANSI(1)
  2099. local unbold = ANSI(22)
  2100. local red = ANSI(31)
  2101.  
  2102. function show_snippet(uid)
  2103. local room = rooms[uid]
  2104. if (not room) then
  2105. room = load_room_from_database(uid)
  2106. end
  2107.  
  2108. local cpk = ""
  2109. if (has_flag(room.flags, "player-kill-chaotic")) then
  2110. cpk = red .. bold .. " [CPK]"
  2111. end
  2112.  
  2113. if (not reader_present) then
  2114. AnsiNote(reset .. snippets[uid], cpk, reset .. " @ " .. room.area)
  2115. else
  2116. Note(StripANSI(snippets[uid] .. cpk .. " @ " .. room.area))
  2117. end
  2118. end
  2119.  
  2120. -- find matching rooms using FTS3
  2121. for row in db:nrows(string.format(
  2122. [[
  2123. SELECT uid, name, snippet(rooms_lookup, '%s', '%s', ' ... ', -1, -10) AS snippet
  2124. FROM rooms_lookup
  2125. WHERE rooms_lookup MATCH %s]],
  2126. bold, unbold,
  2127. fixsql(keywords))) do
  2128. rooms[row.uid] = true
  2129. snippets[row.uid] = row.snippet
  2130. count = count + 1
  2131. end -- finding room
  2132.  
  2133. -- see if nearby
  2134. mapper.find(
  2135. function (uid)
  2136. local room = rooms[uid]
  2137. if room then
  2138. rooms[uid] = nil
  2139. end
  2140. return room, next(rooms) == nil
  2141. end, -- function
  2142. show_vnums, -- show vnum?
  2143. count, -- how many to expect
  2144. false, -- don't auto-walk
  2145. config2.safewalk,
  2146. show_snippet -- show find snippet
  2147. )
  2148. end
  2149. end
  2150.  
  2151.  
  2152. function map_bookmarks(name, line, wildcards)
  2153. if (compatibility) then
  2154. ColourNote("tomato", "black", "GMCP Mapper: I can't find bookmarks in compatibility mode. Please upgrade your database.")
  2155.  
  2156. else
  2157. local rooms = {}
  2158. local count = 0
  2159.  
  2160. -- build table of special places (with info in them)
  2161. for row in db:nrows(string.format("SELECT uid FROM rooms WHERE area = %s", fixsql(zone))) do
  2162. local anote = load_notes_from_database(row.uid)
  2163. if (anote) and (anote ~= "") then
  2164. rooms[row.uid] = capitalize(anote)
  2165. count = count + 1
  2166. end
  2167. end -- finding room
  2168.  
  2169. -- find such places
  2170. mapper.find(
  2171. function (uid)
  2172. local room = rooms[uid]
  2173. if room then
  2174. rooms[uid] = nil
  2175. end
  2176. return room, next(rooms) == nil -- room will be type of info(eg. shop)
  2177. end, -- function
  2178. show_vnums, -- show vnum?
  2179. count, -- how many to expect
  2180. false, -- don't auto-walk
  2181. config2.safewalk
  2182. )
  2183. end
  2184. end
  2185.  
  2186.  
  2187. function map_find_bookmark(book)
  2188. if (compatibility) then
  2189. ColourNote("tomato", "black", "GMCP Mapper: I can't find bookmarks in compatibility mode. Please upgrade your database.")
  2190.  
  2191. else
  2192. local sbook = "%" .. string.upper(book) .. "%"
  2193. local t = {}
  2194.  
  2195. for row in db:nrows(string.format('SELECT * FROM bookmarks WHERE UPPER(notes) like "%s"', sbook)) do
  2196. local room = load_room_from_database(row.uid)
  2197. if (room.area == current_area) then
  2198. t[#t + 1] = row.uid
  2199. end
  2200. end -- finding rooms
  2201.  
  2202. ColourNote("lightgreen", "black", "Rooms bookmarked as: '" .. sbook .. "':")
  2203. show_hyperlinks(t)
  2204.  
  2205. if (verbose_mode) then
  2206. ColourNote("lightgreen", "black", "Click on a room's name or type 'mapper goto <id>' to speedwalk to the room, if possible.")
  2207. end
  2208. end
  2209. end
  2210.  
  2211.  
  2212. function map_list_by_flags(flags)
  2213. local sflags = utils.split(flags, " ")
  2214. local rarea = current_area
  2215. local t = {}
  2216. local rflags
  2217.  
  2218. local use_column = "flags"
  2219. if (compatibility) then
  2220. use_column = "description"
  2221. end
  2222.  
  2223. for row in db:nrows(string.format('SELECT uid, %s FROM rooms WHERE area = "%s"', use_column, rarea)) do
  2224. local use_field = row.flags
  2225. if (compatibility) then
  2226. use_field = row.description
  2227. end
  2228. rflags = string.gsub(use_field or "", " ", "")
  2229. rflags = utils.split(rflags, ",")
  2230.  
  2231. if (has_all(sflags, rflags)) then
  2232. t[#t + 1] = row.uid
  2233. end
  2234. end -- finding rooms
  2235.  
  2236. mapper.mapprint("Results for flag(s)", flags, "in the area", rarea)
  2237. show_hyperlinks(t)
  2238.  
  2239. if (verbose_mode) then
  2240. mapper.mapprint("Click on a room's name or type 'mapper goto <id>' to speedwalk to the room, if possible.")
  2241. end
  2242. end
  2243.  
  2244.  
  2245. function has_all(sflags, rflags)
  2246. local res
  2247. local tres = {}
  2248.  
  2249. for i = 1, #sflags do
  2250. -- Note(sflags[i])
  2251. tres[i] = false
  2252.  
  2253. for j = 1, #rflags do
  2254. -- Note(rflags[j])
  2255. if (sflags[i] == rflags[j]) then
  2256. tres[i] = true
  2257. end
  2258. end
  2259. end
  2260.  
  2261. res = true
  2262. for i = 1, #tres do
  2263. res = res and tres[i]
  2264. end
  2265.  
  2266. return res
  2267. end
  2268.  
  2269.  
  2270. function has_none(sflags, rflags)
  2271. local res
  2272. local tres = {}
  2273.  
  2274. for i = 1, #sflags do
  2275. -- Note(sflags[i])
  2276. tres[i] = false
  2277.  
  2278. for j = 1, #rflags do
  2279. -- Note(rflags[j])
  2280. if (sflags[i] == rflags[j]) then
  2281. tres[i] = true
  2282. end
  2283. end
  2284. end
  2285.  
  2286. res = true
  2287. for i = 1, #tres do
  2288. res = res and (not tres[i])
  2289. end
  2290.  
  2291. return res
  2292. end
  2293.  
  2294.  
  2295. function map_list_by_not_flags(flags)
  2296. local sflags = utils.split(flags, " ")
  2297. local rarea = current_area
  2298. local t = {}
  2299. local rflags
  2300.  
  2301. local use_column = "flags"
  2302. if (compatibility) then
  2303. use_column = "description"
  2304. end
  2305.  
  2306. for row in db:nrows(string.format('SELECT uid, name, %s FROM rooms WHERE area = "%s"', use_column, rarea)) do
  2307. local use_field = row.flags
  2308. if (compatibility) then
  2309. use_field = row.description
  2310. end
  2311. rflags = string.gsub(use_field or "", " ", "")
  2312. rflags = utils.split(rflags, ",")
  2313.  
  2314. if (has_none(sflags, rflags)) then
  2315. t[#t + 1] = row.uid
  2316. end
  2317. end -- finding rooms
  2318.  
  2319. mapper.mapprint("Results for NOT flag(s)", flags, "in the area", rarea)
  2320. show_hyperlinks(t)
  2321.  
  2322. if (verbose_mode) then
  2323. mapper.mapprint("Click on a room's name or type 'mapper goto <id>' to speedwalk to the room, if possible.")
  2324. end
  2325. end
  2326.  
  2327.  
  2328. function map_hyperlink(id)
  2329. local t = {id}
  2330. show_hyperlinks(t)
  2331. end
  2332.  
  2333.  
  2334. function show_hyperlinks(t)
  2335. table.sort(t)
  2336. local rflags
  2337.  
  2338. for i = 1, #t do
  2339. -- Note(t[i])
  2340. local room = rooms[t[i]]
  2341. if (not room) then
  2342. room = load_room_from_database(t[i])
  2343. end
  2344.  
  2345. Tell("room: ")
  2346. Hyperlink ("mapper goto " .. t[i], room.name, "", "white", bgcol, false)
  2347.  
  2348. if (has_flag(room.flags, "player-kill-chaotic")) then
  2349. ColourTell("red", bgcol, " [CPK]")
  2350. end
  2351.  
  2352. Tell(" - id: ")
  2353. ColourTell(fontcol, bgcol, t[i])
  2354.  
  2355. if (room.area ~= "-") then
  2356. Tell(" - area: ")
  2357. ColourTell(fontcol, bgcol, room.area)
  2358. -- Hyperlink("gate " .. room.area, room.area, "", fontcol, bgcol, false)
  2359. end
  2360.  
  2361. Note("")
  2362. end
  2363. end
  2364.  
  2365.  
  2366. function map_show_adjacent_rooms(name)
  2367. local sname = fixsql(string.upper(Trim(name)))
  2368.  
  2369. -- find matching rooms
  2370. local taux = {}
  2371.  
  2372. for row in db:nrows(string.format("SELECT uid FROM rooms WHERE UPPER(name) = %s", sname)) do
  2373. taux[#taux + 1] = row.uid
  2374. end
  2375.  
  2376. mapper.mapprint("Adjacent rooms for name =", name)
  2377.  
  2378. if (#taux == 0) then
  2379. Note("No rooms by that name in my db.")
  2380. return
  2381. end
  2382.  
  2383. table.sort(taux)
  2384.  
  2385. -- find adjacent exits with names /= name
  2386. local tres = {}
  2387. local thisroom, adjroom
  2388.  
  2389. for i = 1, #taux do
  2390. thisroom = load_room_from_database(taux[i])
  2391.  
  2392. for _, num in pairs(thisroom.exits) do
  2393. adjroom = load_room_from_database(num)
  2394.  
  2395. if (adjroom)
  2396. and (string.upper(Trim(adjroom.name)) ~= string.upper(Trim(name))) then
  2397. tres[#tres + 1] = "(" .. adjroom.area .. ") " .. adjroom.name
  2398. end
  2399. end
  2400. end
  2401.  
  2402. -- show results, if any
  2403. if (#tres > 0) then
  2404. table.sort(tres)
  2405.  
  2406. for i = 1, #tres do
  2407. ColourNote("silver", "black", tres[i])
  2408. end
  2409.  
  2410. else
  2411. Note("No matches.")
  2412. end
  2413. end
  2414.  
  2415.  
  2416. function map_safe()
  2417. if (not peeking) then
  2418. map_list_by_flags("safe")
  2419. end
  2420. end
  2421.  
  2422.  
  2423. function map_cpk()
  2424. if (not peeking) then
  2425. map_list_by_flags("player-kill-chaotic")
  2426. end
  2427. end
  2428.  
  2429.  
  2430. function map_dts()
  2431. if (not peeking) then
  2432. if (not compatibility) then
  2433. map_list_by_tags("dt")
  2434. else
  2435. ColourNote("tomato", "black", "GMCP Mapper: I can't search rooms with the DT tag in compatibility mode. Please upgrade your database.")
  2436. end
  2437. end
  2438. end
  2439.  
  2440.  
  2441. function map_shops()
  2442. if (not peeking) then
  2443. if (not compatibility) then
  2444. map_list_by_tags("shop")
  2445. else
  2446. map_list_by_tags_compat("shop")
  2447. end
  2448. end
  2449. end
  2450.  
  2451.  
  2452. function map_trainers()
  2453. if (not peeking) then
  2454. if (not compatibility) then
  2455. map_list_by_tags("trainer")
  2456. else
  2457. map_list_by_tags_compat("train")
  2458. end
  2459. end
  2460. end
  2461.  
  2462.  
  2463. function map_list_by_tags(tags)
  2464. local stags = utils.split(tags, " ")
  2465. local rarea = current_area
  2466. local t = {}
  2467. local room, rtags
  2468.  
  2469. for row in db:nrows(string.format('SELECT * FROM player_tags')) do
  2470. room = do_load_room(row.uid)
  2471.  
  2472. if (room.area == rarea) then
  2473. rtags = row.tags
  2474. rtags = string.gsub(rtags or "", " ", "")
  2475. rtags = utils.split(rtags, ",")
  2476.  
  2477. if (has_all(stags, rtags)) then
  2478. t[#t + 1] = row.uid
  2479. end
  2480. end
  2481. end -- finding rooms
  2482.  
  2483. mapper.mapprint("Results for tag(s)", tags, "in the area", rarea)
  2484. show_hyperlinks(t)
  2485.  
  2486. if (verbose_mode) then
  2487. mapper.mapprint("Click on a room's name or type 'mapper goto <id>' to speedwalk to the room, if possible.")
  2488. end
  2489. end
  2490.  
  2491.  
  2492. function map_list_by_tags_compat(which)
  2493. local rooms = {}
  2494. local count = 0
  2495.  
  2496. -- build table of special places (with info in them)
  2497. for row in db:nrows(string.format("SELECT uid, name FROM rooms WHERE %s = 1", which)) do
  2498. rooms[row.uid] = true
  2499. count = count + 1
  2500. end -- finding room
  2501.  
  2502. -- find such places
  2503. mapper.find(
  2504. function (uid)
  2505. local room = rooms[uid]
  2506. if room then
  2507. rooms[uid] = nil
  2508. end
  2509. return room, next(rooms) == nil -- room will be type of info (eg. shop)
  2510. end, -- function
  2511. show_vnums, -- show vnum?
  2512. count, -- how many to expect
  2513. false, -- don't auto-walk
  2514. config2.safewalk
  2515. )
  2516. end
  2517.  
  2518.  
  2519.  
  2520. -------------
  2521. -- movement
  2522. -------------
  2523.  
  2524. function map_path(wanted)
  2525. return map_path2(current_room, wanted)
  2526. end
  2527.  
  2528.  
  2529. function map_path2(fromuid, touid)
  2530. if not mapper.check_we_can_find() then
  2531. return
  2532. end
  2533.  
  2534. if fromuid and touid == fromuid then
  2535. mapper.mapprint("You are already in that room.")
  2536. return
  2537. end
  2538.  
  2539. local old_depth = config.SCAN.depth
  2540. config.SCAN.depth = 2500
  2541.  
  2542. local paths = mapper.find_paths(fromuid,
  2543. function (uid)
  2544. return uid == touid, -- wanted room?
  2545. uid == touid -- stop searching?
  2546. end)
  2547.  
  2548. local uid, item = next(paths, nil) -- extract first (only) path
  2549.  
  2550. config.SCAN.depth = old_depth
  2551.  
  2552. -- nothing? room not found
  2553. if not item then
  2554. mapper.mapprint(string.format("Path from %s to %s not found.", fromuid, touid))
  2555. return
  2556. end
  2557.  
  2558. -- turn into speedwalk
  2559. local path = mapper.build_speedwalk(item.path)
  2560.  
  2561. -- display it
  2562. path = string.gsub(path, "tprt", "teleport")
  2563. path = string.gsub(path, "prtl", "portal")
  2564.  
  2565. mapper.mapprint(string.format("Path from %s to %s is: %s", fromuid, touid, path))
  2566.  
  2567. return path
  2568. end
  2569.  
  2570.  
  2571. function map_goto(wanted)
  2572. -- -- check valid string
  2573. -- if string.match(wanted, "%D") then
  2574. -- mapper.maperror("Room number must be a number, you entered: " .. wanted)
  2575. -- return
  2576. -- end
  2577.  
  2578. -- see if the room is mapped
  2579. local room = load_room_from_database(wanted)
  2580. if (not room) then
  2581. mapper.mapprint("That room is not mapped.")
  2582. return
  2583. end
  2584.  
  2585. -- see if already there
  2586. if current_room and (current_room == wanted) then
  2587. mapper.mapprint("You are already in that room.")
  2588. return
  2589. end
  2590.  
  2591. local old_depth = config.SCAN.depth
  2592.  
  2593. if (is_vmap(zone))
  2594. or (zone ~= room.area) then
  2595. config.SCAN.depth = 2500
  2596. else
  2597. config.SCAN.depth = 500
  2598. end
  2599.  
  2600. -- find desired room
  2601. mapper.find(
  2602. function (uid)
  2603. local found = string.match(uid, "^" .. wanted .. "$")
  2604. return found, found
  2605. end, -- function
  2606. show_vnums, -- show vnum?
  2607. 1, -- how many to expect
  2608. true, -- just walk there
  2609. config2.safewalk
  2610. )
  2611.  
  2612. config.SCAN.depth = old_depth
  2613. end
  2614.  
  2615.  
  2616. function map_resume(name, line, wildcards)
  2617. local wanted = mapper.last_hyperlink_uid or mapper.last_speedwalk_uid
  2618.  
  2619. if (wanted) then
  2620. map_goto(wanted)
  2621.  
  2622. elseif (not wanted) then
  2623. mapper.mapprint("No outstanding speedwalks or hyperlinks.")
  2624. end -- if nothing to do
  2625. end
  2626.  
  2627.  
  2628. function map_speedwalk_next(name, line, wildcards)
  2629. local next = mapper.get_next_dir()
  2630.  
  2631. if (next) then
  2632. if (sapi_present) then
  2633. if (string.lower(next) == "teleport") then
  2634. sapi_say("wait for teleport")
  2635. elseif (string.lower(next) == "portal") then
  2636. sapi_say("enter portal")
  2637. else
  2638. sapi_say(next)
  2639. end
  2640.  
  2641. else
  2642. Note("* next speedwalk direction: " .. next)
  2643. end
  2644. end
  2645. end
  2646.  
  2647.  
  2648.  
  2649. -- ---------------------------------
  2650. -- process room (as we walk, etc.)
  2651. -- ---------------------------------
  2652.  
  2653. function process_room()
  2654. uid = gmcpval("num")
  2655. zone = gmcpval("zone")
  2656.  
  2657. if (uid ~= "") then
  2658. -- Note(uid)
  2659.  
  2660. if (uid) then
  2661. roomname = gmcpval("name")
  2662.  
  2663. roomflags = gmcpval("flags")
  2664. if (roomflags == "_empty") then
  2665. roomflags = nil
  2666. end
  2667.  
  2668. exits = {}
  2669. exits_str = gmcp_get_exits()
  2670.  
  2671. current_area = zone
  2672.  
  2673. terrain = gmcpval("terrain")
  2674. terraininfo = gmcpval("terraininfo")
  2675.  
  2676. check_if_show_flags_and_terrain(roomflags, terrain)
  2677.  
  2678. current_room = uid
  2679.  
  2680. local room = rooms[current_room]
  2681. if (not room) then -- not cached
  2682. room = load_room_from_database(current_room) -- try to load room from db
  2683. end
  2684.  
  2685. if (not room) then -- room isn't mapped yet
  2686. if (config2.do_map_wilds) -- we're mapping everything
  2687. or ((not is_vmap(zone) or (is_road(terrain) and not is_cave(roomname)))) then -- it's not in the wilds
  2688. db:exec("BEGIN TRANSACTION;")
  2689.  
  2690. save_room_to_database(current_room, roomname, roomflags, zone, terrain, terraininfo)
  2691. save_exits_to_database(zone, current_room, exits_str)
  2692.  
  2693. db:exec("COMMIT;")
  2694.  
  2695. room = load_room_from_database(current_room) -- get it back now
  2696.  
  2697. -- for fixes to outdated maps, run 'mapper update room'
  2698. end
  2699.  
  2700. else -- room already mapped, update if needed
  2701. update_room(uid)
  2702. end
  2703. end
  2704.  
  2705. first_room = false
  2706. end
  2707.  
  2708. if (uid) -- we're not in a maze
  2709. and ((config2.do_map_wilds) -- we're mapping the wilds
  2710. or ((not is_vmap(zone) or (is_road(terrain) and not is_cave(roomname))))) then
  2711. -- or we're in a part of the wilds that we always wanna map
  2712. mapper.draw(current_room) -- call mapper to draw this rom
  2713. end
  2714. end
  2715.  
  2716.  
  2717.  
  2718. -------------------
  2719. -- various checks
  2720. -------------------
  2721.  
  2722. function purge_cache_if_area_changed()
  2723. local zone = gmcpval("zone")
  2724.  
  2725. if (zone ~= old_zone) then
  2726. rooms = {}
  2727. old_zone = zone
  2728. room_not_in_database = {}
  2729. end
  2730. end
  2731.  
  2732.  
  2733. function has_flag(flags, flag)
  2734. local aux
  2735. aux = flags or ""
  2736. aux = string.gsub(aux, escaped_str("no-" .. flag), "x")
  2737. return (string.find(aux, escaped_str(flag)) ~= nil)
  2738. end
  2739.  
  2740.  
  2741. function escaped_str(s)
  2742. s = string.gsub(s, "%-", "%%-")
  2743. return s
  2744. end
  2745.  
  2746.  
  2747. function has_tag(tags, tag)
  2748. return (string.find(tags or "", escaped_str(tag)) ~= nil)
  2749. end
  2750.  
  2751.  
  2752. function is_true(x)
  2753. local res
  2754.  
  2755. x = fixbool(x)
  2756. if (x == 1) then
  2757. res = true
  2758. end
  2759.  
  2760. return res
  2761. end
  2762.  
  2763.  
  2764. function is_vmap(zone)
  2765. local vmap_zones = {
  2766. ["alyria"] = true,
  2767. ["chat rooms wilderness"] = true,
  2768. ["faerie plane wilderness"] = true,
  2769. ["great alyrian underground"] = true,
  2770. ["lasler valley"] = true,
  2771. ["sigil underground"] = true,
  2772. ["verity isle"] = true,
  2773. }
  2774.  
  2775. local res
  2776.  
  2777. if (not zone) then
  2778. local code = gmcpval("coord.code")
  2779. res = (code ~= "")
  2780.  
  2781. else
  2782. res = vmap_zones[string.lower(Trim(zone))]
  2783. end
  2784.  
  2785. return res
  2786. end
  2787.  
  2788.  
  2789. function is_cave(name)
  2790. local cave_names = {
  2791. ["subterranean cave"] = true,
  2792. ["subterranean caves"] = true,
  2793. ["caves of darkness and shadow"] = true,
  2794. }
  2795.  
  2796. return cave_names[string.lower(name)]
  2797. end
  2798.  
  2799.  
  2800. function is_road(terrain)
  2801. local road_terrains = {
  2802. ["bridge"] = true,
  2803. ["city street"] = true,
  2804. ["dusty road"] = true,
  2805. ["gravel road"] = true,
  2806. ["mountain-road"] = true,
  2807. ["paved road"] = true,
  2808. ["trail"] = true,
  2809. }
  2810.  
  2811. return road_terrains[string.lower(terrain)]
  2812. end
  2813.  
  2814.  
  2815. function is_valid_direction(dir)
  2816. local dirs = {
  2817. ["ne"] = true,
  2818. ["e"] = true,
  2819. ["se"] = true,
  2820. ["s"] = true,
  2821. ["sw"] = true,
  2822. ["w"] = true,
  2823. ["nw"] = true,
  2824. ["n"] = true,
  2825. ["u"] = true,
  2826. ["d"] = true,
  2827. ["tprt"] = true,
  2828. ["prtl"] = true,
  2829. }
  2830. return(dirs[dir] ~= nil)
  2831. end
  2832.  
  2833.  
  2834. function is_volatile(uid)
  2835. local volatile = {
  2836. ["10328"] = "Feral Wolverine Mother", -- Mandrake Woods
  2837. ["12242"] = "A Dark Alcove", -- Rune Forest
  2838. ["12258"] = "A Frozen Passage", -- Rune Forest
  2839. ["16334"] = "A Small, Nondescript Cave", -- Limbo Maze
  2840. ["17835"] = "Broad Corridor [chemwalker]", -- Deceit
  2841. ["22434"] = "The Wandering Sidhe",
  2842. ["25835"] = "The Wicker Undercarriage of the Airship Inconvenience",
  2843. ["28637"] = "A Cramped Room [illusionist]", -- Sigil
  2844. -- ["49837"] = "Spiral Staircase", -- Riga
  2845. ["67734"] = "A Concealed Spiral Stair [Idolatry]", -- Catacombs of Shame
  2846. ["68323"] = "A Quartz Cave [tourmaline dragon]", -- Maldra Keep
  2847. ["68263"] = "Preacher Dan's House of Vandynity", -- Maldra Keep
  2848. ["78413"] = "Maze Passageway [angel]", -- HH
  2849. ["107527"] = "A Hidden Torture Room", -- Hellbent
  2850. }
  2851.  
  2852. local x = volatile[tostring(uid)]
  2853.  
  2854. if (x) then
  2855. add_to_events_mini("room #" .. current_room .. ": " .. x)
  2856. end
  2857.  
  2858. return (x ~= nil)
  2859. end
  2860.  
  2861.  
  2862. function add_to_events_mini(txt)
  2863. function add_style_to_events_mini(fgcol, bgcol, txt)
  2864. CallPlugin("9ced43d0a7b4a60116794096", "add_to_mini", fgcol, bgcol, txt)
  2865. end
  2866.  
  2867. -- OnPluginListChanged() should keep 'use_events_mini' updated
  2868.  
  2869. if (use_events_mini) then
  2870. add_style_to_events_mini("dodgerblue", "black", txt)
  2871. add_style_to_events_mini("silver", "black", "\r\n")
  2872. end
  2873. end
  2874.  
  2875.  
  2876. function events_mini_installed()
  2877. return is_plugin_present("events_mini", "9ced43d0a7b4a60116794096")
  2878. end
  2879.  
  2880.  
  2881.  
  2882. ------------------------
  2883. -- specific GMCP stuff
  2884. ------------------------
  2885.  
  2886. function gmcp_get_exits()
  2887. local shortdir = {"n", "nw", "w", "sw", "s", "se", "e", "ne", "u", "d"}
  2888.  
  2889. local exits, i, res, touid, doort
  2890.  
  2891. doort = gmcpval("exits")
  2892.  
  2893. if (string.find(serialize.save_simple(doort) or "", "hidden")) then
  2894. ColourNote("blueviolet", "black", "[gmcp: hidden exit!]")
  2895. end
  2896.  
  2897. if (string.find(serialize.save_simple(doort) or "", "buried")) then
  2898. ColourNote("blueviolet", "black", "[gmcp: buried exit!]")
  2899. end
  2900.  
  2901. if (string.find(serialize.save_simple(doort) or "", "illusion%-disguised")) then
  2902. ColourNote("blueviolet", "black", "[gmcp: illus exit!]")
  2903. end
  2904.  
  2905. exits = ""
  2906. for i = 1, #shortdir do
  2907. touid = gmcpval("exits." .. shortdir[i])
  2908.  
  2909. if (touid ~= "") then
  2910. if (exits == "") then
  2911. exits = shortdir[i]
  2912. else
  2913. exits = exits .. " " .. shortdir[i]
  2914. end
  2915. end
  2916. end
  2917.  
  2918. return exits
  2919. end
  2920.  
  2921.  
  2922.  
  2923. ------------------------
  2924. -- database management
  2925. ------------------------
  2926.  
  2927. function dbcheck(code)
  2928. if code ~= sqlite3.OK and -- no error
  2929. code ~= sqlite3.ROW and -- completed OK with another row of data
  2930. code ~= sqlite3.DONE then -- completed OK, no more rows
  2931. local err = db:errmsg() -- the rollback will change the error message
  2932. db:exec("ROLLBACK") -- rollback any transaction to unlock the database
  2933. error(err, 2) -- show error in caller's context
  2934. end
  2935. end
  2936.  
  2937.  
  2938. function fixsql(s)
  2939. if s then
  2940. return "'" .. (string.gsub(s, "'", "''")) .. "'" -- replace single quotes with two lots of single quotes
  2941. else
  2942. return "NULL"
  2943. end
  2944. end
  2945.  
  2946.  
  2947. function fixbool(b)
  2948. if ((b == true) or (b == "yes") or (b == 1) or (b == "1")) then
  2949. b = 1
  2950. elseif ((b == false) or (b == "no") or (b == 0) or (b == "0") or (not b)) then -- fix for old maps that used different values
  2951. b = 0
  2952. end
  2953. return b
  2954. end
  2955.  
  2956.  
  2957. function create_tables()
  2958. -- create rooms table
  2959. -- and create rooms_lookup table, if it doesn't exist
  2960. if (not compatibility) then
  2961. create_tables_new(db)
  2962. create_rooms_lookup_new(db)
  2963. else
  2964. create_tables_compatibility(db)
  2965. create_rooms_lookup_compatibility(db)
  2966. end
  2967. end
  2968.  
  2969.  
  2970. function create_tables_new(use_db)
  2971. dbcheck(use_db:execute[[
  2972.  
  2973. PRAGMA foreign_keys = ON;
  2974. PRAGMA journal_mode = WAL;
  2975.  
  2976. CREATE TABLE IF NOT EXISTS rooms(
  2977. uid TEXT NOT NULL, -- vnum or how the MUD identifies the room
  2978. name TEXT, -- name of room
  2979. flags TEXT, -- room flags
  2980. area TEXT, -- which area it is in
  2981. terrain TEXT, -- terrain
  2982. terraininfo TEXT, -- terrain info
  2983. date_added DATE, -- date added to database
  2984. UNIQUE(uid)
  2985. );
  2986.  
  2987. CREATE TABLE IF NOT EXISTS bookmarks(
  2988. uid TEXT NOT NULL, -- room's vnum
  2989. notes TEXT, -- player notes
  2990. UNIQUE(uid),
  2991. FOREIGN KEY(uid) REFERENCES rooms(uid)
  2992. );
  2993.  
  2994. CREATE TABLE IF NOT EXISTS player_tags(
  2995. uid TEXT NOT NULL, -- room's vnum
  2996. tags TEXT, -- player tags (DT, no-speed, shop, trainer, trap)
  2997. UNIQUE(uid),
  2998. FOREIGN KEY(uid) REFERENCES rooms(uid)
  2999. );
  3000.  
  3001. CREATE TABLE IF NOT EXISTS exits(
  3002. dir TEXT NOT NULL, -- direction, eg. "n", "s"
  3003. fromuid TEXT NOT NULL, -- exit from which room(in rooms table)
  3004. touid TEXT NOT NULL, -- exit to which room(in rooms table)
  3005. date_added DATE, -- date added to database
  3006. FOREIGN KEY(fromuid) REFERENCES rooms(uid)
  3007. );
  3008. CREATE INDEX IF NOT EXISTS fromuid_index ON exits(fromuid);
  3009. CREATE INDEX IF NOT EXISTS touid_index ON exits(touid);
  3010. ]])
  3011. end
  3012.  
  3013.  
  3014. function create_tables_compatibility(use_db)
  3015. dbcheck(use_db:execute[[
  3016.  
  3017. PRAGMA foreign_keys = ON;
  3018. PRAGMA journal_mode = WAL;
  3019.  
  3020. CREATE TABLE IF NOT EXISTS rooms(
  3021. roomid INTEGER PRIMARY KEY AUTOINCREMENT,
  3022. uid TEXT NOT NULL, -- vnum or how the MUD identifies the room
  3023. name TEXT, -- name of room
  3024. description TEXT, -- room flags
  3025. area TEXT, -- which area it is in
  3026. terrain TEXT, -- terrain
  3027. terraininfo TEXT, -- terrain info
  3028. safe INTEGER, -- 1 = safe room
  3029. lpk INTEGER, -- 1 = lpk room
  3030. npk INTEGER, -- 1 = npk room
  3031. cpk INTEGER, -- 1 = cpk room
  3032. shop INTEGER, -- 1 = shop here
  3033. train INTEGER, -- 1 = trainer here
  3034. notes TEXT, -- player notes
  3035. date_added DATE, -- date added to database
  3036. UNIQUE(uid)
  3037. );
  3038. CREATE INDEX IF NOT EXISTS safe_index ON rooms(safe);
  3039. CREATE INDEX IF NOT EXISTS cpk_index ON rooms(cpk);
  3040. CREATE INDEX IF NOT EXISTS shop_index ON rooms(shop);
  3041. CREATE INDEX IF NOT EXISTS train_index ON rooms(train);
  3042.  
  3043. CREATE TABLE IF NOT EXISTS exits(
  3044. exitid INTEGER PRIMARY KEY AUTOINCREMENT,
  3045. dir TEXT NOT NULL, -- direction, eg. "n", "s"
  3046. fromuid TEXT NOT NULL, -- exit from which room(in rooms table)
  3047. touid TEXT NOT NULL, -- exit to which room(in rooms table)
  3048. date_added DATE, -- date added to database
  3049. FOREIGN KEY(fromuid) REFERENCES rooms(uid)
  3050. );
  3051. CREATE INDEX IF NOT EXISTS fromuid_index ON exits(fromuid);
  3052. CREATE INDEX IF NOT EXISTS touid_index ON exits(touid);
  3053.  
  3054. ]])
  3055. end
  3056.  
  3057.  
  3058. function create_rooms_lookup_new(use_db)
  3059. local table_exists
  3060. for a in use_db:nrows "SELECT * FROM sqlite_master WHERE name = 'rooms_lookup' AND type = 'table'" do
  3061. table_exists = true
  3062. end
  3063.  
  3064. if not table_exists then
  3065. dbcheck(use_db:execute "CREATE VIRTUAL TABLE rooms_lookup USING FTS3(uid, name, area);")
  3066. -- in case we only deleted the rooms_lookup table to save space in the download
  3067. dbcheck(use_db:execute "INSERT INTO rooms_lookup(uid, name, area) SELECT uid, name, area FROM rooms;")
  3068. end
  3069. end
  3070.  
  3071.  
  3072. function create_rooms_lookup_compatibility(use_db)
  3073. local table_exists
  3074. for a in use_db:nrows "SELECT * FROM sqlite_master WHERE name = 'rooms_lookup' AND type = 'table'" do
  3075. table_exists = true
  3076. end
  3077.  
  3078. if not table_exists then
  3079. dbcheck(use_db:execute "CREATE VIRTUAL TABLE rooms_lookup USING FTS3(uid, name, description);")
  3080. -- in case we only deleted the rooms_lookup table to save space in the download
  3081. dbcheck(use_db:execute "INSERT INTO rooms_lookup(uid, name, description) SELECT uid, name, description FROM rooms;")
  3082. end
  3083. end
  3084.  
  3085.  
  3086.  
  3087. ---------------------
  3088. -- database queries
  3089. ---------------------
  3090.  
  3091. function load_room_from_database(uid)
  3092. assert(uid, "No UID supplied to load_room_from_database")
  3093.  
  3094. if (room_not_in_database[uid]) then
  3095. return nil
  3096. end -- no point looking
  3097.  
  3098. local room = do_load_room(uid)
  3099.  
  3100. if (room) then
  3101. rooms[uid] = room
  3102. room_not_in_database[uid] = nil
  3103. return room
  3104. end -- if found
  3105.  
  3106. room_not_in_database[uid] = true
  3107. return nil
  3108. end
  3109.  
  3110.  
  3111. function do_load_room(uid)
  3112. local room
  3113.  
  3114. for row in db:nrows(string.format("SELECT * FROM rooms WHERE uid = %s", fixsql(uid))) do
  3115. room = {
  3116. name = row.name,
  3117. area = row.area,
  3118. terrain = row.terrain,
  3119. terraininfo = row.terraininfo,
  3120. date_added = row.date_added,
  3121. exits = {}
  3122. }
  3123.  
  3124. if (not compatibility) then
  3125. room.flags = row.flags
  3126. room.notes = load_notes_from_database(uid)
  3127. room.tags = load_tags_from_database(uid)
  3128.  
  3129. else
  3130. room.flags = row.description
  3131. room.flags = fix_flag(room.flags, row.safe, "safe")
  3132. room.flags = fix_flag(room.flags, row.lpk, "player-kill-lawful")
  3133. room.flags = fix_flag(room.flags, row.npk, "player-kill-neutral")
  3134. room.flags = fix_flag(room.flags, row.cpk, "player-kill-chaotic")
  3135.  
  3136. room.notes = row.notes
  3137.  
  3138. room.tags = ""
  3139. room.tags = fix_tag(room.tags, row.shop, "shop")
  3140. room.tags = fix_tag(room.tags, row.train, "trainer")
  3141. end
  3142.  
  3143. for exitrow in db:nrows(string.format("SELECT * FROM exits WHERE fromuid = %s", fixsql(uid))) do
  3144. room.exits[exitrow.dir] = tostring(exitrow.touid)
  3145. end -- for each exit
  3146. end -- finding room
  3147.  
  3148. return room
  3149. end
  3150.  
  3151.  
  3152. function room_exits(uid)
  3153. local room = rooms[uid]
  3154. if (not room) then
  3155. room = load_room_from_database(uid)
  3156. end
  3157.  
  3158. local res = ""
  3159. if (room) then
  3160. res = serialize.save_simple(room.exits or {})
  3161. end
  3162.  
  3163. return res
  3164. end
  3165.  
  3166.  
  3167. function fix_flag(flags, field, flag)
  3168. if (is_true(field))
  3169. and (not has_flag(flags, flag)) then
  3170. flags = add_a_flag(flags, flag)
  3171. end
  3172.  
  3173. return flags
  3174. end
  3175.  
  3176.  
  3177. function fix_tag(tags, field, tag)
  3178. if (is_true(field))
  3179. and (not has_tag(tags, tag)) then
  3180. tags = add_a_tag(tags, tag)
  3181. end
  3182.  
  3183. return tags
  3184. end
  3185.  
  3186.  
  3187. function add_a_flag(flags, flag)
  3188. return add_a_tag(flags, flag)
  3189. end
  3190.  
  3191.  
  3192. function load_notes_from_database(uid)
  3193. local res
  3194.  
  3195. for row in db:nrows(string.format("SELECT * FROM bookmarks WHERE uid = %s", fixsql(uid))) do
  3196. res = row.notes
  3197. end
  3198.  
  3199. return res
  3200. end
  3201.  
  3202.  
  3203. function load_tags_from_database(uid)
  3204. local res
  3205.  
  3206. for row in db:nrows(string.format("SELECT * FROM player_tags WHERE uid = %s", fixsql(uid))) do
  3207. res = row.tags
  3208. end
  3209.  
  3210. return res
  3211. end
  3212.  
  3213.  
  3214.  
  3215. -- -----------
  3216. -- additions
  3217. -- -----------
  3218.  
  3219. --------------
  3220. -- add rooms
  3221. --------------
  3222.  
  3223. function map_add_room(id, name, zone, flags, terrain, terraininfo)
  3224. local room = load_room_from_database(id)
  3225.  
  3226. if (not room) then -- room isn't mapped yet
  3227. db:exec("BEGIN TRANSACTION;")
  3228.  
  3229. save_room_to_database(id, Trim(name), Trim(flags), Trim(zone), Trim(terrain), Trim(terraininfo))
  3230.  
  3231. db:exec("COMMIT;")
  3232.  
  3233. -- update in-memory table
  3234. load_room_from_database(id)
  3235.  
  3236. mapper.draw(current_room)
  3237.  
  3238. else
  3239. mapper.mapprint("The room", id, "is already mapped.")
  3240. end
  3241. end
  3242.  
  3243.  
  3244. function save_room_to_database(uid, title, flags, area, terrain, terraininfo)
  3245. assert(uid, "No UID supplied to save_room_to_database")
  3246.  
  3247. local use_column = "flags"
  3248. if (compatibility) then
  3249. use_column = "description"
  3250. end
  3251.  
  3252. dbcheck(db:execute(string.format(
  3253. "INSERT INTO rooms(uid, name, %s, area, terrain, terraininfo, date_added) VALUES(%s, %s, %s, %s, %s, %s, DATETIME('NOW'));",
  3254. use_column,
  3255. fixsql(uid),
  3256. fixsql(title),
  3257. fixsql(flags),
  3258. fixsql(area),
  3259. fixsql(terrain),
  3260. fixsql(terraininfo)
  3261. )))
  3262.  
  3263. use_column = "area"
  3264. local use_field = area
  3265. if (compatibility) then
  3266. use_column = "flags"
  3267. use_field = flags
  3268. end
  3269.  
  3270. dbcheck(db:execute(string.format(
  3271. "INSERT INTO rooms_lookup(uid, name, %s) VALUES(%s, %s, %s);",
  3272. use_column,
  3273. fixsql(uid),
  3274. fixsql(title),
  3275. fixsql(use_field)
  3276. )))
  3277.  
  3278. room_not_in_database[uid] = nil
  3279.  
  3280. if (config2.show_database_mods) then
  3281. mapper.mapprint("Added room", uid, "to database. Name:", title)
  3282. end
  3283. end
  3284.  
  3285.  
  3286.  
  3287. ------------------
  3288. -- add bookmarks
  3289. ------------------
  3290.  
  3291. function map_add_bookmark(id, new_note)
  3292. if (compatibility) then
  3293. ColourNote("tomato", "black", "GMCP Mapper: I can't edit bookmarks in compatibility mode. Please upgrade your database.")
  3294.  
  3295. else
  3296. if (id == "") then
  3297. id = uid -- current room is default
  3298. end
  3299.  
  3300. if (new_note == "") then
  3301. new_note = "x"
  3302. end
  3303.  
  3304. local room = load_room_from_database(id)
  3305.  
  3306. if (room) then -- room is in the map
  3307. db:exec("BEGIN TRANSACTION;")
  3308.  
  3309. local notes = load_notes_from_database(id)
  3310.  
  3311. if (notes) then -- room already has a bookmark
  3312. update_bookmark(id, new_note)
  3313. mapper.mapprint("Bookmark for room", uid, "changed to:", new_note)
  3314. else
  3315. save_bookmark(id, new_note)
  3316. mapper.mapprint("Bookmark for room", id, "set to:", new_note)
  3317. end
  3318.  
  3319. db:exec("COMMIT;")
  3320.  
  3321. -- update in-memory table
  3322. if (rooms[id]) then
  3323. rooms[id].notes = new_note
  3324. end
  3325.  
  3326. else
  3327. mapper.mapprint("The room", id, "isn't in the map.")
  3328. end
  3329. end
  3330. end
  3331.  
  3332.  
  3333. function room_edit_bookmark(room, uid)
  3334. -- gui function
  3335. if (compatibility) then
  3336. ColourNote("tomato", "black", "GMCP Mapper: I can't edit bookmarks in compatibility mode. Please upgrade your database.")
  3337.  
  3338. else
  3339. local notes = room.notes or ""
  3340.  
  3341. if (notes ~= "") then
  3342. newnotes = utils.inputbox("Modify room comment (clear it to delete from database)", room.name, notes)
  3343. else
  3344. newnotes = utils.inputbox("Enter room comment (creates a bookmark for this room)", room.name, notes)
  3345. end
  3346.  
  3347. if (not newnotes) then
  3348. return
  3349. end -- if cancelled
  3350.  
  3351. if (notes ~= newnotes) then
  3352. if (newnotes == "") then
  3353. if (notes == "") then
  3354. mapper.mapprint("No comment entered, bookmark not saved.")
  3355. else
  3356. del_bookmark_from_database(uid)
  3357. mapper.mapprint("Bookmark for room", uid, "deleted. Was previously:", notes)
  3358.  
  3359. -- update in-memory table
  3360. if (rooms[id]) then
  3361. rooms[id].notes = nil
  3362. end
  3363. end
  3364.  
  3365. else -- newnotes not empty
  3366. if (notes == "") then
  3367. save_bookmark(uid, newnotes)
  3368. mapper.mapprint("Bookmark added to room", uid, ":", newnotes)
  3369. else
  3370. update_bookmark(uid, newnotes)
  3371. mapper.mapprint("Bookmark for room", uid, "changed to:", newnotes)
  3372. end
  3373.  
  3374. -- update in-memory table
  3375. if (rooms[id]) then
  3376. rooms[id].notes = newnotes
  3377. end
  3378. end
  3379. end
  3380. end
  3381. end
  3382.  
  3383.  
  3384. function save_bookmark(uid, notes)
  3385. dbcheck(db:execute(string.format(
  3386. "INSERT INTO bookmarks(uid, notes) VALUES(%s, %s);",
  3387. fixsql(uid),
  3388. fixsql(notes)
  3389. )))
  3390. end
  3391.  
  3392.  
  3393.  
  3394. -------------
  3395. -- add tags
  3396. -------------
  3397.  
  3398. function save_tags_to_database(uid, tags)
  3399. dbcheck(db:execute(string.format(
  3400. "INSERT INTO player_tags(uid, tags) VALUES(%s, %s);",
  3401. fixsql(uid),
  3402. fixsql(tags)
  3403. )))
  3404. end
  3405.  
  3406.  
  3407.  
  3408. --------------
  3409. -- add exits
  3410. --------------
  3411.  
  3412. function map_add_exit(dir, fromid, toid)
  3413. if (fromid == "") then
  3414. fromid = uid -- current room is default
  3415. end
  3416.  
  3417. local room = load_room_from_database(fromid)
  3418.  
  3419. if (room) then -- room fromid is in the map
  3420. if (is_valid_direction(dir)) then
  3421. if (not is_volatile(toid)) then
  3422. db:exec("BEGIN TRANSACTION;")
  3423.  
  3424. add_exit_to_database(dir, fromid, toid)
  3425.  
  3426. db:exec("COMMIT;")
  3427.  
  3428. -- update in-memory table
  3429. if (rooms[fromid]) then
  3430. if (not rooms[fromid].exits) then
  3431. rooms[fromid].exits = {}
  3432. end
  3433.  
  3434. rooms[fromid].exits[dir] = toid
  3435. end
  3436.  
  3437. mapper.draw(current_room)
  3438.  
  3439. else
  3440. mapper.mapprint("The room", toid, "changes locations.")
  3441. end
  3442.  
  3443. else
  3444. mapper.mapprint("You must provide a valid direction (n, ne, etc.)")
  3445. end
  3446.  
  3447. else
  3448. mapper.mapprint("The room", fromid, "isn't in the map.")
  3449. end
  3450. end
  3451.  
  3452.  
  3453. function add_exit_to_database(dir, fromuid, touid)
  3454. assert(dir, "No direction supplied to add_exit_to_database")
  3455. assert(fromuid, "No fromUID supplied to add_exit_to_database")
  3456. assert(touid, "No toUID supplied to add_exit_to_database")
  3457.  
  3458. dbcheck(db:execute(string.format(
  3459. "INSERT INTO exits(dir, fromuid, touid, date_added) VALUES(%s, %s, %s, DATETIME('NOW'));",
  3460. fixsql(dir), -- direction (eg. "n")
  3461. fixsql(fromuid), -- from room
  3462. fixsql(touid) -- destination room
  3463. )))
  3464.  
  3465. if (config2.show_database_mods) then
  3466. mapper.mapprint("Added exit to database,", dir, "from", fromuid, "to", touid)
  3467. end
  3468. end
  3469.  
  3470.  
  3471. function save_exits_to_database(zone, uid, exits)
  3472. local dest
  3473.  
  3474. for dir in string.gmatch(exits, "%a+") do
  3475. dest = gmcpval("exits." .. dir)
  3476.  
  3477. if (dest ~= "-99") then
  3478. dbcheck(db:execute(string.format(
  3479. "INSERT INTO exits(dir, fromuid, touid, date_added) VALUES(%s, %s, %s, DATETIME('NOW'));",
  3480. fixsql(dir), -- direction (eg. "n")
  3481. fixsql(uid), -- from current room
  3482. fixsql(dest) -- destination room
  3483. )))
  3484. end
  3485. end -- for each exit
  3486. end
  3487.  
  3488.  
  3489. function room_add_exit(room, uid)
  3490. -- gui function
  3491. local available = {
  3492. n = "North",
  3493. s = "South",
  3494. e = "East",
  3495. w = "West",
  3496. u = "Up",
  3497. d = "Down",
  3498. ne = "Northeast",
  3499. sw = "Southwest",
  3500. nw = "Northwest",
  3501. se = "Southeast",
  3502. tprt = "Teleport",
  3503. prtl = "Portal",
  3504. }
  3505.  
  3506. -- remove existing exits
  3507. for k in pairs(room.exits) do
  3508. available[k] = nil
  3509. end
  3510.  
  3511. if next(available) == nil then
  3512. utils.msgbox("All exits already used.", "No free exits!", "ok", "!", 1)
  3513. return
  3514. end -- not known
  3515.  
  3516. local chosen_exit = utils.listbox("Choose exit to add", "Exits ...", available)
  3517. if (not chosen_exit) then
  3518. return
  3519. end
  3520.  
  3521. exit_destination = utils.inputbox("Enter destination room id for " .. available[chosen_exit], room.name, "")
  3522.  
  3523. if (not exit_destination) then
  3524. return
  3525. end -- cancelled
  3526.  
  3527. dbcheck(db:execute(string.format(
  3528. "INSERT INTO exits(dir, fromuid, touid, date_added) VALUES(%s, %s, %s, DATETIME('NOW'));",
  3529. fixsql(chosen_exit), -- direction (eg. "n")
  3530. fixsql(uid), -- from current room
  3531. fixsql(exit_destination) -- destination room
  3532. )))
  3533.  
  3534. if (config2.show_database_mods) then
  3535. mapper.mapprint("Added exit", available[chosen_exit], "from room", uid, "to room", exit_destination, "to database.")
  3536. end
  3537.  
  3538. -- update in-memory table
  3539. rooms[uid].exits[chosen_exit] = exit_destination
  3540.  
  3541. mapper.draw(current_room)
  3542. end
  3543.  
  3544.  
  3545.  
  3546. -- -----------
  3547. -- deletions
  3548. -- -----------
  3549.  
  3550. -----------------
  3551. -- delete rooms
  3552. -----------------
  3553.  
  3554. function map_del_room(id)
  3555. local room = load_room_from_database(id)
  3556.  
  3557. if (room) then -- room is in the map
  3558.  
  3559. if (count_exits(room.exits) == 0) then -- the room has no "from" links
  3560. db:exec("BEGIN TRANSACTION;")
  3561.  
  3562. del_room_from_database(id)
  3563.  
  3564. local notes = load_notes_from_database(uid)
  3565. if (notes) then
  3566. del_bookmark_from_database(id)
  3567. end
  3568.  
  3569. local tags = load_tags_from_database(uid)
  3570. if (tags) then
  3571. del_tags_from_database(id)
  3572. end
  3573.  
  3574. db:exec("COMMIT;")
  3575.  
  3576. -- update in-memory table
  3577. if (rooms[id]) then
  3578. rooms[id] = nil
  3579. end
  3580.  
  3581. mapper.draw(current_room)
  3582.  
  3583. else
  3584. mapper.mapprint("Delete exits from room", id, "to other rooms first.")
  3585. end
  3586.  
  3587. else
  3588. mapper.mapprint("The room", id, "isn't in the map.")
  3589. end
  3590. end
  3591.  
  3592.  
  3593. function count_exits(exits)
  3594. local shortdir = {"n", "ne", "e", "se", "s", "sw", "w", "nw", "u", "d", "none"}
  3595. local i, res
  3596.  
  3597. res = 0
  3598.  
  3599. for i = 1, #shortdir do
  3600. if (exits[shortdir[i]]) then
  3601. res = res + 1
  3602. end
  3603. end
  3604.  
  3605. return res
  3606. end
  3607.  
  3608.  
  3609. function del_room_from_database(uid)
  3610. assert(uid, "No UID supplied to del_room_from_database")
  3611.  
  3612. dbcheck(db:execute(string.format(
  3613. "DELETE FROM rooms WHERE uid = %s;",
  3614. fixsql(uid)
  3615. )))
  3616.  
  3617. dbcheck(db:execute(string.format(
  3618. "DELETE FROM rooms_lookup WHERE uid = %s;",
  3619. fixsql(uid)
  3620. )))
  3621.  
  3622. if (config2.show_database_mods) then
  3623. mapper.mapprint("Deleted room", uid, "from database")
  3624. end
  3625. end
  3626.  
  3627.  
  3628.  
  3629. ---------------------
  3630. -- delete bookmarks
  3631. ---------------------
  3632.  
  3633. function map_del_bookmark(id)
  3634. if (compatibility) then
  3635. ColourNote("tomato", "black", "GMCP Mapper: I can't edit bookmarks in compatibility mode. Please upgrade your database.")
  3636.  
  3637. else
  3638. if (id == "") then
  3639. id = uid -- current room is default
  3640. end
  3641.  
  3642. local notes = load_notes_from_database(id)
  3643.  
  3644. if (notes) then -- room is in the map
  3645. db:exec("BEGIN TRANSACTION;")
  3646.  
  3647. del_bookmark_from_database(id)
  3648.  
  3649. db:exec("COMMIT;")
  3650.  
  3651. -- update in-memory table
  3652. if (rooms[id]) then
  3653. rooms[id].notes = ""
  3654. end
  3655.  
  3656. mapper.mapprint("Bookmark for room", id, "deleted.")
  3657.  
  3658. else
  3659. mapper.mapprint("The room", id, "doesn't have notes, or isn't mapped.")
  3660. end
  3661. end
  3662. end
  3663.  
  3664.  
  3665. function del_bookmark_from_database(uid)
  3666. dbcheck(db:execute(string.format(
  3667. "DELETE FROM bookmarks WHERE uid = %s;",
  3668. fixsql(uid)
  3669. )))
  3670. end
  3671.  
  3672.  
  3673.  
  3674. ----------------
  3675. -- delete tags
  3676. ----------------
  3677.  
  3678. function del_tags_from_database(uid)
  3679. dbcheck(db:execute(string.format(
  3680. "DELETE FROM player_tags WHERE uid = %s;",
  3681. fixsql(uid)
  3682. )))
  3683. end
  3684.  
  3685.  
  3686.  
  3687. -----------------
  3688. -- delete exits
  3689. -----------------
  3690.  
  3691. function map_del_exits(fromid)
  3692. if (fromid == "") then
  3693. fromid = uid -- current room is default
  3694. end
  3695.  
  3696. local room = load_room_from_database(fromid)
  3697.  
  3698. if (room) then -- room fromid is in the map
  3699. db:exec("BEGIN TRANSACTION;")
  3700.  
  3701. del_exits_from_database(fromid)
  3702.  
  3703. db:exec("COMMIT;")
  3704.  
  3705. -- update in-memory table
  3706. if (rooms[fromid]) then
  3707. rooms[fromid].exits = {}
  3708. end
  3709.  
  3710. else
  3711. mapper.mapprint("The room", fromid, "isn't in the map.")
  3712. end
  3713. end
  3714.  
  3715.  
  3716. function map_del_exit(dir, fromid)
  3717. if (fromid == "") then
  3718. fromid = uid -- current room is default
  3719. end
  3720.  
  3721. local room = load_room_from_database(fromid)
  3722.  
  3723. if (room) then -- room fromid is in the map
  3724. if ((is_valid_direction(dir)) or (dir == "none")) then
  3725. db:exec("BEGIN TRANSACTION;")
  3726.  
  3727. del_exit_from_database(dir, fromid)
  3728.  
  3729. db:exec("COMMIT;")
  3730.  
  3731. -- update in-memory table
  3732. if (rooms[fromid]) then
  3733. rooms[fromid].exits[dir] = nil
  3734. end
  3735.  
  3736. mapper.draw(current_room)
  3737.  
  3738. else
  3739. mapper.mapprint("You must provide a valid direction (n, ne, etc.)")
  3740. end
  3741.  
  3742. else
  3743. mapper.mapprint("The room", fromid, "isn't in the map.")
  3744. end
  3745. end
  3746.  
  3747.  
  3748. function del_exits_from_database(uid)
  3749. assert(uid, "No UID supplied to del_room_from_database")
  3750.  
  3751. dbcheck(db:execute(string.format(
  3752. "DELETE FROM exits WHERE fromuid = %s;",
  3753. fixsql(uid) -- fromuid
  3754. )))
  3755.  
  3756. if (config2.show_database_mods) then
  3757. mapper.mapprint("Deleted all exits from room", uid, "from database")
  3758. end
  3759. end
  3760.  
  3761.  
  3762. function del_exit_from_database(dir, fromuid)
  3763. assert(dir, "No direction supplied to add_exit_to_database")
  3764. assert(fromuid, "No fromUID supplied to add_exit_to_database")
  3765.  
  3766. dbcheck(db:execute(string.format(
  3767. "DELETE FROM exits WHERE dir = %s AND fromuid = %s;",
  3768. fixsql(dir), -- dir
  3769. fixsql(fromuid) -- fromuid
  3770. )))
  3771.  
  3772. if (config2.show_database_mods) then
  3773. mapper.mapprint("Deleted exit from database,", dir, "from", fromuid)
  3774. end
  3775. end
  3776.  
  3777.  
  3778. function room_delete_exit(room, uid)
  3779. -- gui function
  3780. local available = {
  3781. n = "North",
  3782. s = "South",
  3783. e = "East",
  3784. w = "West",
  3785. u = "Up",
  3786. d = "Down",
  3787. ne = "Northeast",
  3788. sw = "Southwest",
  3789. nw = "Northwest",
  3790. se = "Southeast",
  3791. tprt = "Teleport",
  3792. prtl = "Portal",
  3793. }
  3794.  
  3795. -- remove non-existent exits
  3796. for k in pairs(available) do
  3797. if room.exits[k] then
  3798. available[k] = available[k] .. " --> " .. room.exits[k]
  3799. else
  3800. available[k] = nil
  3801. end -- if not a room exit
  3802. end
  3803.  
  3804. if (next(available) == nil) then
  3805. utils.msgbox("There are no exits from this room.", "No exits!", "ok", "!", 1)
  3806. return
  3807. end -- not known
  3808.  
  3809. local chosen_exit = utils.listbox("Choose exit to delete", "Exits ...", available)
  3810. if (not chosen_exit) then
  3811. return
  3812. end
  3813.  
  3814. dbcheck(db:execute(string.format(
  3815. "DELETE FROM exits WHERE dir = %s AND fromuid = %s;",
  3816. fixsql(chosen_exit), -- direction (eg. "n")
  3817. fixsql(uid) -- from current room
  3818. )))
  3819.  
  3820. if (config2.show_database_mods) then
  3821. mapper.mapprint("Deleted exit", available[chosen_exit], "from room", uid, "from database.")
  3822. end
  3823.  
  3824. -- update in-memory table
  3825. rooms[uid].exits[chosen_exit] = nil
  3826.  
  3827. mapper.draw(current_room)
  3828. end
  3829.  
  3830.  
  3831.  
  3832. -- ---------------
  3833. -- modifications
  3834. -- ---------------
  3835.  
  3836. -----------------
  3837. -- modify rooms
  3838. -----------------
  3839.  
  3840. function update_room(uid)
  3841. db:exec("BEGIN TRANSACTION;")
  3842.  
  3843. local oldarea, zone, oldname, name, oldterrain, terrain, oldterraininfo, terraininfo, oldflags, flags, cflags
  3844.  
  3845. if (not uid) then
  3846. uid = gmcpval("num")
  3847. end
  3848.  
  3849. zone = gmcpval("zone")
  3850.  
  3851. oldarea = rooms[uid].area -- if area has changed, then update/add it
  3852. if (oldarea ~= zone) then
  3853. room_update_area(uid, zone)
  3854. end
  3855.  
  3856. name = gmcpval("name")
  3857. oldname = rooms[uid].name -- if name has changed, then update/add it,
  3858. if (oldname ~= roomname) then
  3859. room_update_name(uid, roomname)
  3860. end
  3861.  
  3862. -- fix exits, in case some of them are missing
  3863. fix_exits(zone, uid, exits_str)
  3864.  
  3865. terrain = gmcpval("terrain")
  3866. oldterrain = rooms[uid].terrain -- if terrain has changed, then update/add it
  3867. if (oldterrain ~= terrain) then
  3868. room_update_terrain(uid, terrain)
  3869. end
  3870.  
  3871. terraininfo = gmcpval("terraininfo")
  3872. oldterraininfo = rooms[uid].terraininfo -- if terraininfo has changed, then update/add it
  3873. if (oldterraininfo ~= terraininfo) then
  3874. room_update_terraininfo(uid, terraininfo)
  3875. end
  3876.  
  3877. flags = gmcpval("flags")
  3878. if (flags == "_empty") then
  3879. flags = ""
  3880. end
  3881. oldflags = (rooms[uid].flags or "") -- if flags have changed, then update/add them,
  3882. cflags = flags
  3883. if (zone == "Tellerium") then
  3884. cflags = remove_anti_magic(flags)
  3885. oldflags = remove_anti_magic(flags)
  3886. end
  3887. if (oldflags ~= cflags) then
  3888. room_update_flags(uid, flags)
  3889. end
  3890.  
  3891. db:exec("COMMIT;")
  3892.  
  3893. mapper.draw(current_room)
  3894. end
  3895.  
  3896.  
  3897. function remove_anti_magic(flags)
  3898. flags = flags or ""
  3899. flags = string.gsub(flags, "anti%-magic, ", "")
  3900. flags = string.gsub(flags, ", anti%-magic", "")
  3901. flags = string.gsub(flags, "anti%-magic", "")
  3902. return flags
  3903. end
  3904.  
  3905.  
  3906.  
  3907. ----------------
  3908. -- modify area
  3909. ----------------
  3910.  
  3911. function room_update_area(uid, zone)
  3912. dbcheck(db:execute(string.format(
  3913. "UPDATE rooms SET area = %s WHERE uid = %s;",
  3914. fixsql(zone),
  3915. fixsql(uid)
  3916. )))
  3917.  
  3918. if (not compatibility) then
  3919. dbcheck(db:execute(string.format(
  3920. "UPDATE rooms_lookup SET area = %s WHERE uid = %s;",
  3921. fixsql(zone),
  3922. fixsql(uid)
  3923. )))
  3924. end
  3925.  
  3926. if (config2.show_database_mods) then
  3927. mapper.mapprint("Room", uid, "area updated")
  3928. end
  3929.  
  3930. if (rooms[id]) then
  3931. rooms[uid].area = zone
  3932. end
  3933. end -- room_update_area
  3934.  
  3935.  
  3936.  
  3937. ----------------
  3938. -- modify name
  3939. ----------------
  3940.  
  3941. function room_update_name(uid, name)
  3942. dbcheck(db:execute(string.format(
  3943. "UPDATE rooms SET name = %s WHERE uid = %s;",
  3944. fixsql(name),
  3945. fixsql(uid)
  3946. )))
  3947.  
  3948. dbcheck(db:execute(string.format(
  3949. "UPDATE rooms_lookup SET name = %s WHERE uid = %s;",
  3950. fixsql(name),
  3951. fixsql(uid)
  3952. )))
  3953.  
  3954. if (config2.show_database_mods) then
  3955. mapper.mapprint("Room", uid, "name updated")
  3956. end
  3957.  
  3958. if (rooms[id]) then
  3959. rooms[uid].name = name
  3960. end
  3961. end
  3962.  
  3963.  
  3964.  
  3965. ---------------------------------
  3966. -- modify terrain / terraintype
  3967. ---------------------------------
  3968.  
  3969. function room_update_terrain(uid, terrain)
  3970. dbcheck(db:execute(string.format(
  3971. "UPDATE rooms SET terrain = %s WHERE uid = %s;",
  3972. fixsql(terrain),
  3973. fixsql(uid)
  3974. )))
  3975.  
  3976. if (config2.show_database_mods) then
  3977. mapper.mapprint("Room", uid, "terrain updated")
  3978. end
  3979.  
  3980. if (rooms[id]) then
  3981. rooms[uid].terrain = terrain
  3982. end
  3983. end
  3984.  
  3985.  
  3986. function room_update_terraininfo(uid, terraininfo)
  3987. dbcheck(db:execute(string.format(
  3988. "UPDATE rooms SET terraininfo = %s WHERE uid = %s;",
  3989. fixsql(terraininfo),
  3990. fixsql(uid)
  3991. )))
  3992.  
  3993. if (config2.show_database_mods) then
  3994. mapper.mapprint("Room", uid, "terraininfo updated")
  3995. end
  3996.  
  3997. if (rooms[id]) then
  3998. rooms[uid].terraininfo = terraininfo
  3999. end
  4000. end
  4001.  
  4002.  
  4003.  
  4004. -----------------
  4005. -- modify flags
  4006. -----------------
  4007.  
  4008. function room_update_flags(uid, flags)
  4009. local use_column = "flags"
  4010. if (compatibility) then
  4011. use_column = "description"
  4012. end
  4013.  
  4014. dbcheck(db:execute(string.format(
  4015. "UPDATE rooms SET %s = %s WHERE uid = %s;",
  4016. use_column,
  4017. fixsql(flags),
  4018. fixsql(uid)
  4019. )))
  4020.  
  4021. if (compatibility) then
  4022. dbcheck(db:execute(string.format(
  4023. "UPDATE rooms_lookup SET description = %s WHERE uid = %s;",
  4024. fixsql(flags),
  4025. fixsql(uid)
  4026. )))
  4027. end
  4028.  
  4029. if (config2.show_database_mods) then
  4030. mapper.mapprint("Room", uid, "flags updated")
  4031. end
  4032.  
  4033. if (rooms[uid]) then
  4034. rooms[uid].flags = flags
  4035. end
  4036. end
  4037.  
  4038.  
  4039.  
  4040. ---------------------
  4041. -- modify bookmarks
  4042. ---------------------
  4043.  
  4044. function update_bookmark(uid, notes)
  4045. dbcheck(db:execute(string.format(
  4046. "UPDATE bookmarks SET notes = %s WHERE uid = %s;",
  4047. fixsql(notes),
  4048. fixsql(uid)
  4049. )))
  4050. end
  4051.  
  4052.  
  4053.  
  4054. ----------------
  4055. -- modify tags
  4056. ----------------
  4057.  
  4058. function map_toggle_tag(id, tag)
  4059. if (compatibility) then
  4060. ColourNote("tomato", "black", "GMCP Mapper: I can't tag rooms in compatibility mode. Please upgrade your database.")
  4061.  
  4062. else
  4063. if (id == "") then
  4064. id = uid -- current room is default
  4065. end
  4066.  
  4067. local room = rooms[id]
  4068.  
  4069. if (not room) then
  4070. room = load_room_from_database(uid)
  4071. end
  4072.  
  4073. if (not room) then
  4074. mapper.mapprint("The room", id, "isn't in the map.")
  4075.  
  4076. else
  4077. room_toggle_tag(room, id, tag)
  4078. end
  4079. end
  4080. end
  4081.  
  4082.  
  4083. function room_toggle_tag(room, uid, tag)
  4084. if (compatibility) then
  4085. ColourNote("tomato", "black", "GMCP Mapper: I can't tag rooms in compatibility mode. Please upgrade your database.")
  4086.  
  4087. else
  4088. if (has_tag(rooms[uid].tags, tag)) then
  4089. rooms[uid].tags = del_a_tag(rooms[uid].tags, tag)
  4090. else
  4091. rooms[uid].tags = add_a_tag(rooms[uid].tags, tag)
  4092. end
  4093.  
  4094. db:exec("BEGIN TRANSACTION;")
  4095.  
  4096. local tags = room.tags or ""
  4097. if (Trim(tags) == "") then
  4098. tags = nil
  4099. end
  4100.  
  4101. if (tags) then
  4102. if (rooms[uid].tags) then
  4103. save_tags_to_database(uid, rooms[uid].tags)
  4104. end
  4105.  
  4106. else
  4107. if (rooms[uid].tags) then
  4108. update_tags(uid, rooms[uid].tags)
  4109. else
  4110. del_tags_from_database(uid)
  4111. end
  4112. end
  4113.  
  4114. db:exec("COMMIT;")
  4115.  
  4116. if (has_flag(rooms[uid].tags, tag)) then
  4117. mapper.mapprint("Room", uid, "tagged as", tag)
  4118. else
  4119. mapper.mapprint("Room", uid, "no longer tagged as", tag)
  4120. end
  4121.  
  4122. mapper.draw(current_room)
  4123. end
  4124. end
  4125.  
  4126.  
  4127. function add_a_tag(tags, tag)
  4128. if (not tags) or (Trim(tags) == "") then
  4129. tags = tag
  4130. else
  4131. tags = tags .. ", " .. tag
  4132. end
  4133.  
  4134. return tags
  4135. end
  4136.  
  4137.  
  4138. function del_a_tag(tags, tag)
  4139. if (tags) and (has_tag(tags, tag)) then
  4140. tags = string.gsub(tags, escaped_str(tag) .. ", ", "")
  4141. tags = string.gsub(tags, ", " .. escaped_str(tag) .. "$", "")
  4142. tags = string.gsub(tags, escaped_str(tag), "")
  4143.  
  4144. tags = Trim(tags)
  4145.  
  4146. if (tags == "") then
  4147. tags = nil
  4148. end
  4149. end
  4150.  
  4151. return tags
  4152. end
  4153.  
  4154.  
  4155. function update_tags(uid, tags)
  4156. dbcheck(db:execute(string.format(
  4157. "UPDATE player_tags SET tags = %s WHERE uid = %s;",
  4158. fixsql(tags),
  4159. fixsql(uid)
  4160. )))
  4161. end
  4162.  
  4163.  
  4164.  
  4165. -----------------
  4166. -- modify exits
  4167. -----------------
  4168.  
  4169. function fix_exits(zone, uid, exits)
  4170. local dest, aux
  4171.  
  4172. for dir in string.gmatch(exits, "%a+") do
  4173. dest = gmcpval("exits." .. dir)
  4174.  
  4175. if (dest) and (dest ~= "none") and (dest ~= "-99")
  4176. and (not is_volatile(uid)) and (not is_volatile(dest)) then
  4177.  
  4178. if (dest ~= rooms[uid].exits[dir]) then -- exit changed, update it
  4179.  
  4180. dbcheck(db:execute(string.format(
  4181. "INSERT INTO exits(dir, fromuid, touid, date_added) VALUES(%s, %s, %s, DATETIME('NOW'));",
  4182. fixsql(dir), -- direction (eg. "n")
  4183. fixsql(uid), -- from current room
  4184. fixsql(dest) -- destination room
  4185. )))
  4186.  
  4187. -- update in-memory table
  4188. rooms[uid].exits[dir] = dest
  4189.  
  4190. if (config2.show_database_mods) then
  4191. mapper.mapprint("Room", uid, "-", dir, "exit updated")
  4192. end
  4193. end
  4194. end
  4195.  
  4196. end -- for each exit
  4197. end
  4198.  
  4199.  
  4200. function room_change_exit(room, uid)
  4201. -- gui function
  4202. local available = {
  4203. n = "North",
  4204. s = "South",
  4205. e = "East",
  4206. w = "West",
  4207. u = "Up",
  4208. d = "Down",
  4209. ne = "Northeast",
  4210. sw = "Southwest",
  4211. nw = "Northwest",
  4212. se = "Southeast",
  4213. tprt = "Teleport",
  4214. prtl = "Portal",
  4215. } -- end of available
  4216.  
  4217. -- remove non-existent exits
  4218. for k in pairs(available) do
  4219. if room.exits[k] then
  4220. available[k] = available[k] .. " --> " .. room.exits[k]
  4221. else
  4222. available[k] = nil
  4223. end -- if not a room exit
  4224. end
  4225.  
  4226. if (next(available) == nil) then
  4227. utils.msgbox("There are no exits from this room.", "No exits!", "ok", "!", 1)
  4228. return
  4229. end -- not known
  4230.  
  4231. local chosen_exit = utils.listbox("Choose exit to change destination of:", "Exits ...", available)
  4232. if not chosen_exit then
  4233. return
  4234. end
  4235.  
  4236. exit_destination = utils.inputbox("Enter destination room id for " .. available[chosen_exit], room.name, "")
  4237.  
  4238. if not exit_destination then
  4239. return
  4240. end -- cancelled
  4241.  
  4242. dbcheck(db:execute(string.format(
  4243. "UPDATE exits SET touid = %s WHERE dir = %s AND fromuid = %s;",
  4244. fixsql(exit_destination),
  4245. fixsql(chosen_exit), -- direction (eg. "n")
  4246. fixsql(uid) -- from current room
  4247. )))
  4248.  
  4249. if (config2.show_database_mods) then
  4250. mapper.mapprint("Modified exit", available[chosen_exit], "from room", uid, "to be to room", exit_destination, "in database.")
  4251. end
  4252.  
  4253. -- update in-memory table
  4254. rooms[uid].exits[chosen_exit] = exit_destination
  4255. mapper.draw(current_room)
  4256. end
  4257.  
  4258.  
  4259.  
  4260. -- ---------------
  4261. -- special areas
  4262. -- ---------------
  4263.  
  4264. function toggle_wilds_mapping(status)
  4265. config2.do_map_wilds = do_toggle(config2.do_map_wilds, status)
  4266.  
  4267. save_config2()
  4268.  
  4269. if (config2.do_map_wilds) then
  4270. Note("-- MM_GMCP_Mapper: wilds mapping ON --")
  4271.  
  4272. else
  4273. Note("-- MM_GMCP_Mapper: wilds mapping OFF --")
  4274. end
  4275.  
  4276. -- mapper.draw(current_room)
  4277. end
  4278.  
  4279.  
  4280.  
  4281. -- -------------
  4282. -- maintenance
  4283. -- -------------
  4284.  
  4285. --------------
  4286. -- room info
  4287. --------------
  4288.  
  4289. function show_room_info(id)
  4290. if (id == "") then
  4291. id = uid -- current room is default
  4292. end
  4293.  
  4294. local room = load_room_from_database(id)
  4295.  
  4296. if (room) then -- room is in the map
  4297. Tell("id: ")
  4298. ColourNote(fontcol, bgcol, id)
  4299. Tell("name: ")
  4300. ColourNote(fontcol, bgcol, room.name)
  4301. Tell("zone: ")
  4302. ColourNote(fontcol, bgcol, room.area)
  4303.  
  4304. if (room.terrain) then
  4305. Tell("terrain: ")
  4306. ColourNote(fontcol, bgcol, room.terrain)
  4307. end
  4308.  
  4309. if (room.terraininfo) then
  4310. Tell("terraininfo: ")
  4311. ColourNote(fontcol, bgcol, room.terraininfo)
  4312. end
  4313.  
  4314. Tell("flags: ")
  4315. ColourNote(fontcol, bgcol, room.flags or "-")
  4316.  
  4317. room.tags = load_tags_from_database(id)
  4318. Tell("tags: ")
  4319. ColourNote(fontcol, bgcol, room.tags or "-")
  4320.  
  4321. room.notes = load_notes_from_database(id)
  4322. if (room.notes) then
  4323. Tell("bookmarks: ")
  4324. ColourNote(fontcol, bgcol, room.notes)
  4325. end
  4326.  
  4327. if (room.exits) then
  4328. Tell("exits: ")
  4329. ColourNote(fontcol, bgcol, serialize.save_simple(room.exits))
  4330. end
  4331.  
  4332. else
  4333. mapper.mapprint("The room", id, "isn't in the map.")
  4334. end
  4335. end
  4336.  
  4337.  
  4338. function export_rooms(name)
  4339. -- name must be an exact room match
  4340.  
  4341. local sname = string.upper(name)
  4342. local t = {}
  4343.  
  4344. for row in db:nrows(string.format('SELECT * FROM rooms WHERE UPPER(name) = "%s"', sname)) do
  4345. t[#t + 1] = row.uid
  4346. end -- finding rooms
  4347.  
  4348. for i = 1, #t do
  4349. do_export_room(t[i])
  4350. end
  4351. end
  4352.  
  4353.  
  4354. function export_area(name)
  4355. local sname = string.upper(name)
  4356. local t = {}
  4357.  
  4358. for row in db:nrows(string.format('SELECT * FROM rooms WHERE UPPER(area) = "%s"', sname)) do
  4359. t[#t + 1] = row.uid
  4360. end -- finding rooms
  4361.  
  4362. for i = 1, #t do
  4363. do_export_room(t[i])
  4364. end
  4365. end
  4366.  
  4367.  
  4368. function do_export_room(num)
  4369. local room = load_room_from_database(num)
  4370.  
  4371. if (room) then
  4372. AppendToNotepad("exported rooms", "mapper addroom " .. num .. " n:" .. room.name .. " a:" .. room.area .. " f:" .. (room.flags or " ") .. " t:" .. (room.terrain or " ") .. " ti:" .. (room.terraininfo or " ") .. "\r\n")
  4373.  
  4374. if (Trim(room.notes or "") ~= "") then
  4375. AppendToNotepad("exported rooms", "mapper addbm " .. num .. " b:" .. room.notes .."\r\n")
  4376. end
  4377.  
  4378. if (has_tag(room.tags, "dt")) then
  4379. AppendToNotepad("exported rooms", "mapper dt " .. num .."\r\n")
  4380. end
  4381.  
  4382. if (has_tag(room.tags, "no-speed")) then
  4383. AppendToNotepad("exported rooms", "mapper nospeed " .. num .."\r\n")
  4384. end
  4385.  
  4386. if (has_tag(room.tags, "shop")) then
  4387. AppendToNotepad("exported rooms", "mapper shop " .. num .."\r\n")
  4388. end
  4389.  
  4390. if (has_tag(room.tags, "trainer")) then
  4391. AppendToNotepad("exported rooms", "mapper trainer " .. num .."\r\n")
  4392. end
  4393.  
  4394. for dir, touid in pairs(room.exits) do
  4395. AppendToNotepad("exported rooms", "mapper addexit " .. dir .. " f:" .. num .. " t:" .. touid .. "\r\n")
  4396. end
  4397. end
  4398. end
  4399.  
  4400.  
  4401.  
  4402. ----------------
  4403. -- purge stuff
  4404. ----------------
  4405.  
  4406. function purge_entire_area(name)
  4407. local arooms = {}
  4408. local aname = fixsql(string.upper(name))
  4409.  
  4410. -- make list of stuff to delete
  4411. for row in db:nrows(string.format("SELECT uid FROM rooms WHERE UPPER(area) = %s", aname)) do
  4412. arooms[#arooms + 1] = row.uid
  4413. end -- finding rooms
  4414.  
  4415. purge_stuff(arooms, name, false)
  4416. end
  4417.  
  4418.  
  4419. function purge_wilds(name)
  4420. local prooms = {}
  4421. local pname = fixsql(string.upper(name))
  4422.  
  4423. if (is_vmap(name)) then
  4424. -- make list of stuff to delete
  4425. for row in db:nrows(string.format("SELECT uid, name, terrain FROM rooms WHERE UPPER(area) = %s", pname)) do
  4426. if (not is_road(row.terrain)) or (is_cave(row.name)) then
  4427. prooms[#prooms + 1] = row.uid
  4428. end
  4429. end -- finding rooms
  4430.  
  4431. purge_stuff(prooms, name, false)
  4432.  
  4433. else
  4434. mapper.mapprint("'" .. name .. "' is not a valid plane name.")
  4435. end
  4436. end
  4437.  
  4438.  
  4439. function purge_pursuer()
  4440. local prooms = {}
  4441. local pname = "A Dizzying Array"
  4442.  
  4443. -- make lists of stuff to delete
  4444. for row in db:nrows(string.format("SELECT uid FROM rooms WHERE name = '%s'", pname)) do
  4445. prooms[#prooms + 1] = row.uid
  4446. end -- finding rooms
  4447.  
  4448. purge_bookmarks(prooms, pname)
  4449. purge_stuff(prooms, pname, true)
  4450. end
  4451.  
  4452.  
  4453. function purge_sandbox()
  4454. local srooms = {}
  4455. local sarea = "The Housing Sandbox"
  4456.  
  4457. -- make list of stuff to delete
  4458. for row in db:nrows(string.format("SELECT uid FROM rooms WHERE area = '%s'", sarea)) do
  4459. srooms[#srooms + 1] = row.uid
  4460. end -- finding rooms
  4461.  
  4462. purge_stuff(srooms, sarea, false)
  4463. end
  4464.  
  4465.  
  4466. function purge_molehill()
  4467. local mrooms = {}
  4468. local marea = "A Labyrinthine Molehill"
  4469. local mnotes = {}
  4470.  
  4471. -- make lists of stuff to delete
  4472. for row in db:nrows(string.format("SELECT uid FROM rooms WHERE area = '%s'", marea)) do
  4473. mrooms[#mrooms + 1] = row.uid
  4474.  
  4475. if (row.notes) and (row.notes ~= "NULL") and (row.notes ~= "") then
  4476. mnotes[#mnotes + 1] = row.uid
  4477. end
  4478. end -- finding rooms
  4479.  
  4480. purge_bookmarks(mnotes, marea)
  4481. purge_stuff(mrooms, marea, true)
  4482. end
  4483.  
  4484.  
  4485. function purge_bookmarks(t, name)
  4486. if (#t > 0) then
  4487. db:exec("BEGIN TRANSACTION;")
  4488.  
  4489. mapper.mapprint("Deleting " .. name .. " bookmarks...")
  4490. for i = 1, #t do
  4491. SetStatus("Erasing bookmark for room " .. t[i] .. "...")
  4492. map_del_bookmark(t[i])
  4493.  
  4494. -- update in-memory table
  4495. if (rooms[t[i]]) then
  4496. rooms[t[i]].notes = nil
  4497. end
  4498. end
  4499.  
  4500. db:exec("COMMIT;")
  4501.  
  4502. mapper.mapprint("Done.")
  4503. SetStatus("Ready")
  4504.  
  4505. else
  4506. mapper.mapprint("No bookmarks found for '" .. name .. "'")
  4507. end
  4508. end
  4509.  
  4510.  
  4511. function purge_list(list, name, unlink)
  4512. local t = utils.split(list, " ")
  4513.  
  4514. purge_stuff(t, name, unlink)
  4515. end
  4516.  
  4517.  
  4518. function purge_stuff(t, name, unlink)
  4519. if (#t > 0) then
  4520. db:exec("BEGIN TRANSACTION;")
  4521.  
  4522. if (unlink) then
  4523. mapper.mapprint("Unlinking " .. name .. "...")
  4524. else
  4525. mapper.mapprint("Purging " .. name .. "...")
  4526. end
  4527.  
  4528. for i = 1, #t do
  4529. if (unlink) then
  4530. unlink_room(t[i])
  4531. else
  4532. nuke_room(t[i])
  4533. end
  4534. end
  4535.  
  4536. db:exec("COMMIT;")
  4537.  
  4538. mapper.mapprint("Done.")
  4539. SetStatus("Ready")
  4540.  
  4541. mapper.draw(current_room)
  4542.  
  4543. else
  4544. mapper.mapprint("No rooms found for '" .. name .. "'")
  4545. end
  4546. end
  4547.  
  4548.  
  4549. function unlink_room(uid)
  4550. SetStatus("Unlinking room " .. uid .. "...")
  4551. del_exits_from_database(uid)
  4552.  
  4553. -- update in-memory table
  4554. if (rooms[uid]) then
  4555. rooms[uid].exits = {}
  4556. end
  4557. end
  4558.  
  4559.  
  4560. function nuke_room(uid)
  4561. SetStatus("Erasing room " .. uid .. "...")
  4562. del_exits_from_database(uid)
  4563. del_room_from_database(uid)
  4564.  
  4565. local notes = load_notes_from_database(uid)
  4566. if (notes) then
  4567. del_bookmark_from_database(uid)
  4568. end
  4569.  
  4570. local tags = load_tags_from_database(uid)
  4571. if (tags) then
  4572. del_tags_from_database(uid)
  4573. end
  4574.  
  4575. -- update in-memory table
  4576. rooms[uid] = nil
  4577. end
  4578.  
  4579.  
  4580.  
  4581. ------------------
  4582. -- privacy stuff
  4583. ------------------
  4584.  
  4585. function purge_clanhalls()
  4586. local row
  4587. local crooms = {}
  4588. local careas = "% Clan Hall"
  4589.  
  4590. db:exec("BEGIN TRANSACTION;")
  4591.  
  4592. -- make list of stuff to delete
  4593. for row in db:nrows(string.format("SELECT uid, area FROM rooms WHERE area like '%s'", careas)) do
  4594. if (string.find(row.area, "Old ") ~= 1)
  4595. and (string.find(row.area, "The Old ") ~= 1) then
  4596. crooms[#crooms + 1] = row.uid
  4597. end
  4598. end -- finding rooms
  4599.  
  4600. mapper.mapprint("Purging clan halls data...")
  4601. for i = 1, #crooms do
  4602. SetStatus("Erasing room " .. crooms[i] .. "...")
  4603.  
  4604. del_exits_from_database(crooms[i])
  4605.  
  4606. del_room_from_database(crooms[i])
  4607.  
  4608. -- update in-memory table
  4609. rooms[crooms[i]] = nil
  4610. end
  4611.  
  4612. db:exec("COMMIT;")
  4613.  
  4614. mapper.mapprint("Done.")
  4615. SetStatus("Ready")
  4616.  
  4617. mapper.draw(current_room)
  4618. end
  4619.  
  4620.  
  4621. function purge_player_homes()
  4622. local row
  4623. local hrooms = {}
  4624. local hareas = "Player Homes %"
  4625.  
  4626. db:exec("BEGIN TRANSACTION;")
  4627.  
  4628. -- make list of stuff to delete
  4629. for row in db:nrows(string.format("SELECT uid, area FROM rooms WHERE area like '%s'", hareas)) do
  4630. if (uid ~= "25022646") then -- The Pirate's Cove Housing District
  4631. hrooms[#hrooms + 1] = row.uid
  4632. end
  4633. end -- finding rooms
  4634.  
  4635. mapper.mapprint("Purging player homes data...")
  4636. for i = 1, #hrooms do
  4637. SetStatus("Erasing room " .. hrooms[i] .. "...")
  4638.  
  4639. del_exits_from_database(hrooms[i])
  4640.  
  4641. del_room_from_database(hrooms[i])
  4642.  
  4643. -- update in-memory table
  4644. rooms[hrooms[i]] = nil
  4645. end
  4646.  
  4647. db:exec("COMMIT;")
  4648.  
  4649. mapper.mapprint("Done.")
  4650. SetStatus("Ready")
  4651.  
  4652. mapper.draw(current_room)
  4653. end
  4654.  
  4655.  
  4656. function purge_notes()
  4657. local row
  4658. local brooms = {}
  4659.  
  4660. db:exec("BEGIN TRANSACTION;")
  4661.  
  4662. -- make lists of stuff to delete
  4663. for row in db:nrows(string.format("SELECT uid, notes, area FROM rooms")) do
  4664. if (not is_vmap())
  4665. and (row.notes) then
  4666. brooms[#brooms + 1] = row.uid
  4667. end
  4668. end -- finding rooms
  4669.  
  4670. -- delete bookmarks
  4671. mapper.mapprint("Deleting non-vmap bookmarks...")
  4672. for i = 1, #brooms do
  4673. SetStatus("Erasing bookmark for room " .. brooms[i] .. "...")
  4674. map_del_bookmark(brooms[i])
  4675. end
  4676.  
  4677. db:exec("COMMIT;")
  4678.  
  4679. mapper.mapprint("Done.")
  4680. SetStatus("Ready")
  4681.  
  4682. mapper.draw(current_room)
  4683. end
  4684.  
  4685.  
  4686.  
  4687. ------------------
  4688. -- rebuild stuff
  4689. ------------------
  4690.  
  4691. function rebuild_lookup()
  4692. db:exec("BEGIN TRANSACTION;")
  4693.  
  4694. mapper.mapprint("Rebuilding rooms_lookup table...")
  4695.  
  4696. -- delete all rows from rooms_lookup
  4697. dbcheck(db:execute(string.format(
  4698. "DELETE FROM rooms_lookup;"
  4699. )))
  4700.  
  4701. local use_column = "area"
  4702. if (compatibility) then
  4703. use_column = "description"
  4704. end
  4705.  
  4706. for row in db:nrows(string.format("SELECT uid, name, %s FROM rooms", use_column)) do
  4707. SetStatus("Recreating rooms_lookup entry for room " .. uid)
  4708.  
  4709. local use_field = row.area
  4710. if (compatibility) then
  4711. use_field = row.description
  4712. end
  4713.  
  4714. dbcheck(db:execute(string.format(
  4715. "INSERT INTO rooms_lookup(uid, name, %s) VALUES(%s, %s, %s);",
  4716. use_column,
  4717. fixsql(row.uid),
  4718. fixsql(row.name),
  4719. fixsql(use_field)
  4720. )))
  4721. end -- finding rooms
  4722.  
  4723. db:exec("COMMIT;")
  4724. SetStatus("Ready")
  4725.  
  4726. mapper.mapprint("Done.")
  4727. end
  4728.  
  4729.  
  4730. function recreate_database(cmd)
  4731. -- open databases on disk
  4732. if (cmd == "upgrade") and (compatibility) then
  4733. dbnew = assert(sqlite3.open(GetInfo(66) .. "mm_mapper.db"))
  4734. else
  4735. dbnew = assert(sqlite3.open(GetInfo(66) .. "mm_mapper_new.db"))
  4736. end
  4737.  
  4738. -- create rooms table
  4739. create_tables_new(dbnew)
  4740.  
  4741. dbnew:exec("BEGIN TRANSACTION;")
  4742.  
  4743. -- copy rooms from "old" table
  4744. local room
  4745.  
  4746. for row in db:nrows(string.format("SELECT * FROM rooms")) do
  4747. SetStatus("Copying room " .. row.uid .. " to the new database...")
  4748.  
  4749. room = do_load_room(row.uid)
  4750. room.uid = row.uid
  4751.  
  4752. if (compatibility) then
  4753. room.flags = fix_flag(room.flags, row.safe, "safe")
  4754. room.flags = fix_flag(room.flags, row.lpk, "player-kill-lawful")
  4755. room.flags = fix_flag(room.flags, row.npk, "player-kill-neutral")
  4756. room.flags = fix_flag(room.flags, row.cpk, "player-kill-chaotic")
  4757. end
  4758.  
  4759. dbcheck(dbnew:execute(string.format(
  4760. "INSERT INTO rooms(uid, name, flags, area, terrain, terraininfo, date_added) VALUES(%s, %s, %s, %s, %s, %s, %s);",
  4761. fixsql(room.uid),
  4762. fixsql(room.name),
  4763. fixsql(room.flags),
  4764. fixsql(room.area),
  4765. fixsql(room.terrain),
  4766. fixsql(room.terraininfo),
  4767. fixsql(room.date_added)
  4768. )))
  4769.  
  4770. if (room.notes) and (room.notes ~= "") then
  4771. dbcheck(dbnew:execute(string.format(
  4772. "INSERT INTO bookmarks(uid, notes) VALUES(%s, %s);",
  4773. fixsql(room.uid),
  4774. fixsql(row.notes)
  4775. )))
  4776. end
  4777.  
  4778. if (room.tags) and (room.tags ~= "") then
  4779. dbcheck(dbnew:execute(string.format(
  4780. "INSERT INTO player_tags(uid, tags) VALUES(%s, %s);",
  4781. fixsql(room.uid),
  4782. fixsql(room.tags)
  4783. )))
  4784. end
  4785. end
  4786.  
  4787. -- copy exits from "old" table
  4788.  
  4789. for row in db:nrows(string.format("SELECT * FROM exits")) do
  4790. SetStatus("Copying exits from room " .. row.fromuid .. " to the new database...")
  4791.  
  4792. dbcheck(dbnew:execute(string.format(
  4793. "INSERT INTO exits(dir, fromuid, touid, date_added) VALUES(%s, %s, %s, %s);",
  4794. fixsql(row.dir),
  4795. fixsql(row.fromuid),
  4796. fixsql(row.touid),
  4797. fixsql(row.date_added)
  4798. )))
  4799. end
  4800.  
  4801. SetStatus("Committing changes...")
  4802.  
  4803. dbnew:exec("COMMIT;")
  4804.  
  4805. SetStatus("Ready.")
  4806.  
  4807. if (cmd == "upgrade") and (compatibility) then
  4808. ColourTell("white", "navy", "GMCP Mapper: your database has been upgraded to the new structure - ")
  4809. ColourTell("lime", "navy", "reinstall this plugin")
  4810. ColourNote("white", "navy", " to start using the new file.")
  4811.  
  4812. else
  4813. ColourNote("white", "black", "GMCP Mapper: your database has been recreated as ")
  4814. ColourTell("lime", "black", "mm_mapper_new.db")
  4815. ColourNote("white", "black", " in your MUSHclient folder.")
  4816. end
  4817. end
  4818.  
  4819.  
  4820.  
  4821. -- ------
  4822. -- misc
  4823. -- ------
  4824.  
  4825. ------------------------
  4826. -- scripting functions
  4827. ------------------------
  4828.  
  4829. function speeding()
  4830. return (not mapper.check_we_can_find())
  4831. end
  4832.  
  4833.  
  4834. function handled_door()
  4835. return (config2.auto_open)
  4836. end
  4837.  
  4838.  
  4839.  
  4840. ------------------------
  4841. -- sapi / reader stuff
  4842. ------------------------
  4843.  
  4844. function detect_reader()
  4845. local res = reader_plugin_present()
  4846.  
  4847. if (res) then
  4848. config2.visible = false
  4849. save_config2()
  4850. end
  4851.  
  4852. return res
  4853. end
  4854.  
  4855.  
  4856. function reader_plugin_present()
  4857. return is_plugin_present("MushReader", "925cdd0331023d9f0b8f05a7")
  4858. end
  4859.  
  4860.  
  4861. function sapi_plugin_present()
  4862. return is_plugin_present("Sapi_speaker", "463242566069ebfd1b379ec1") or is_plugin_present("Text_To_Speech", "463242566069ebfd1b379ec1")
  4863. end
  4864.  
  4865.  
  4866. function sapi_say(text)
  4867. if (sapi_present) then
  4868. local res = CallPlugin("463242566069ebfd1b379ec1", "say", text)
  4869. end
  4870. end
  4871.  
  4872.  
  4873. ]]>
  4874.  
  4875. </script>
  4876.  
  4877. </muclient>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement