jizong 发表于 2013-4-7 17:34:11

最近没有研究mush的地图插件了么?求指导啊

最近没有研究mush的地图插件了么?求指导啊

创建地图,快速寻路,移动什么的~~~求指导啊

北大侠客行MUD,中国最好的MUD

jizong 发表于 2013-4-7 17:37:47

plugins / Materia_Magica_Mapper.xml<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient [
<!ENTITY show_vnums "true" >
<!ENTITY show_timing "false" >
<!ENTITY show_completed "false" >
<!ENTITY show_database_mods "true" >
<!ENTITY show_other_areas "false" >
<!ENTITY show_area_exits "false" >
<!ENTITY show_up_down "true" >
<!ENTITY speedwalk_prefix "" >
]>

<muclient>
<plugin
   name="Materia_Magica_Mapper"
   author="Nick Gammon"
   id="1c17ac2c83b2b66c402c80c6"
   language="Lua"
   purpose="Mapper for Materia Magica"
   save_state="y"
   date_written="2010-10-12"
   date_modified="2010-10-18 07:05"
   requires="4.61"
   version="1.5"
   >

   <description trim="y">
<![CDATA[
AUTOMATIC MAPPER ...by Nick Gammon

The window can be dragged to a new location by dragging the room name.

Your current room is always in the center with a bolder border.

LH-click on a room to speed-walk to it. RH-click on a room for options.

LH-click on the "*" button on the bottom-left corner to configure it.

** WHY DOES THE MAP CHANGE? **

The mapper draws from your room outwards - that is, it draws your room's exits
first, then the rooms leading from those rooms, and so on.

Eventually it finds an overlap, and draws a short "stub" line to indicate there
is a room there which there isn't space to draw. If you get closer to that
room the stub will disappear and the room(s) in question will be drawn.

ACTIONS

mapper help         --> this help(or click the "?" button on the bottom right)
mapper zoom out   --> zoom out
mapper zoom in      --> zoom in
mapper hide         --> hide map
mapper show         --> show map

FINDING THINGS

mapper bookmarks    --> show nearby rooms that you bookmarked
mapper find <text>--> full-text search(eg. shop OR baker)
mapper shop         --> show nearby shops/banks etc.
mapper train      --> show nearby trainers
mapper where <room> --> show directions to a room

MOVING

mapper goto <room>--> walk to a room by its room number (partial)
mapper stop         --> cancel any current speedwalk
mapper resume       --> resume last speedwalk or hyperlinked speedwalk

]]>
</description>


</plugin>


<!--Triggers-->

<triggers>

<trigger
   back_colour="8"
   bold="y"
   enabled="y"
   match=" *"
   match_back_colour="y"
   match_bold="y"
   match_inverse="y"
   match_italic="y"
   match_text_colour="y"
   name="Shop_Line"
   script="Shop_Line"
   sequence="200"
   text_colour="11"
   
>
</trigger>

<trigger
   back_colour="8"
   bold="y"
   enabled="y"
   match=" *"
   match_back_colour="y"
   match_bold="y"
   match_inverse="y"
   match_italic="y"
   match_text_colour="y"
   name="Train_Line"
   script="Train_Line"
   sequence="200"
   text_colour="11"
   
>
</trigger>
   
<trigger
   back_colour="8"
   bold="y"
   enabled="y"
   match="*"
   match_back_colour="y"
   match_bold="y"
   match_inverse="y"
   match_italic="y"
   match_text_colour="y"
   name="Name_Line"
   script="Name_Line"
   sequence="100"
   text_colour="11"
   keep_evaluating="y"
   
>
</trigger>

<trigger
   back_colour="8"
   bold="y"
   enabled="n"
   match="(-------------------------------------------------)*"
   match_back_colour="y"
   match_bold="y"
   match_inverse="y"
   match_italic="y"
   match_text_colour="y"
   name="Hyphen_Line"
   script="Hyphen_Line"
   sequence="100"
   text_colour="12"
   
>
</trigger>
   
   
<trigger
   back_colour="8"
   enabled="n"
   match="*"
   match_back_colour="y"
   match_bold="y"
   match_inverse="y"
   match_italic="y"
   match_text_colour="y"
   name="Map_Line"
   script="Map_Line"
   sequence="100"
   text_colour="15"
>
</trigger>

<trigger
   enabled="n"
   match="*"
   name="Other_Line"
   script="Other_Line"
   sequence="110"
   keep_evaluating="y"
>
</trigger>
   
<trigger
   enabled="n"
   match="Visible Exits: *"
   name="Exits_Line"
   script="Exits_Line"
   sequence="100"
>

</trigger>
      
<trigger
   enabled="y"
   match="^The (door|gate) is closed\.$"
   regexp="y"
   name="Door_Closed"
   script="Door_Closed"
   sequence="100"
>
</trigger>

<!--various messages that cancel speedwalks -->

<trigger
   enabled="y"
   match="You are too exhausted. Better rest for a bit."
   regexp="y"
   script="mapper.cancel_speedwalk"
   sequence="100"
>
</trigger>
   
</triggers>


<aliases>

<!--zooming aliases -->

<alias
   match="mapper zoom out"
   enabled="y"
   sequence="100"
   omit_from_command_history="y"
   omit_from_output="y"
   script="mapper.zoom_out"
>
</alias>

<alias
   match="mapper zoom in"
   enabled="y"
   sequence="100"
   omit_from_command_history="y"
   omit_from_output="y"
   script="mapper.zoom_in"
>
</alias>
   
   
<alias
   match="mapper goto *"
   enabled="y"
   sequence="100"
   script="map_goto"
>

</alias>
   
<!--finding aliases -->

<alias
   match="^mapper find ([\w* %d/&quot;]+)$"
   enabled="y"
   sequence="100"
   script="map_find"
   regexp="y"
>

</alias>

<alias
   match="^mapper book\w*$"
   regexp="y"
   enabled="y"
   sequence="100"
   script="map_bookmarks"
>

</alias>

<alias
   match="mapper where *"
   enabled="y"
   sequence="100"
   script="map_where"
>

</alias>
   
<alias
   match="^mapper shops?$"
   regexp="y"
   enabled="y"
   sequence="100"
   script="map_shops"
>

</alias>

<alias
   match="^mapper train\w*$"
   regexp="y"
   enabled="y"
   sequence="100"
   script="map_trainers"
>

</alias>

<alias
   match="mapper resume"
   enabled="y"
   sequence="100"
   script="map_resume"
>

</alias>
   
<alias
   script="OnHelp"
   match="mapper help"
   enabled="y"
>
</alias>
   
<!--cancel speedwalking -->

<alias
   match="mapper stop"
   enabled="y"
   sequence="100"
   script="mapper.cancel_speedwalk"
>
</alias>

<!--show/hide mapper -->
      
<alias
   match="mapper hide"
   enabled="y"
   sequence="100"
   script="mapper.hide"
>
</alias>

   <alias
   match="mapper show"
   enabled="y"
   sequence="100"
   script="mapper.show"
>
</alias>

</aliases>

<!--Script-->


<script>

local show_vnums = &show_vnums;
local show_timing = &show_timing;
local show_completed = &show_completed;
local show_database_mods = &show_database_mods;
local show_other_areas = &show_other_areas;
local show_up_down = &show_up_down;
local show_area_exits = &show_area_exits;
local speedwalk_prefix = "&speedwalk_prefix;"

<![CDATA[

require "mapper"
require "serialize"
require "copytable"

rooms = {}
areas = {}

valid_direction = {
n = "n",
s = "s",
e = "e",
w = "w",
u = "u",
d = "d",
ne = "ne",
sw = "sw",
nw = "nw",
se = "se",
north = "n",
south = "s",
east = "e",
west = "w",
up = "u",
down = "d",
northeast = "ne",
northwest = "nw",
southeast = "se",
southwest = "sw",
['in'] = "in",
out = "out",
}-- end of valid_direction

-- -----------------------------------------------------------------
-- 1. Here on yellow line - room name
-- -----------------------------------------------------------------

function Name_Line (name, line, wildcards, styles)

if string.match (line, "^%[") then
    return
end -- if chat line
   
got_hyphens = false
roomname = Trim (styles .text:sub (1, 50))
roomdesc = ""
exits = {}
exits_str = ""
map_str = ""
got_exits = false
EnableTrigger ("Hyphen_Line", true)
EnableTrigger ("Other_Line", true)
EnableTrigger ("Name_Line", false)
end -- Name_Line


-- -----------------------------------------------------------------
-- 2. Here on: (-------------------------------------------------)
-- -----------------------------------------------------------------

function Hyphen_Line (name, line, wildcards)
got_hyphens = true
EnableTrigger ("Map_Line", true)
EnableTrigger ("Hyphen_Line", false)
EnableTrigger ("Other_Line", false)
end -- Hyphen_Line

-- -----------------------------------------------------------------
-- 3. Here on third line (rest of compass)
-- -----------------------------------------------------------------

function Map_Line (name, line, wildcards)
EnableTrigger ("Map_Line", false)
EnableTrigger ("Other_Line", true)
EnableTrigger ("Exits_Line", true)

end -- Map_Line

-- -----------------------------------------------------------------
-- 4. Here on exits line
-- -----------------------------------------------------------------

function Exits_Line (name, line, wildcards)

exits_str = string.gsub (wildcards :lower (), "[()]", "")

EnableTrigger ("Exits_Line", false)
got_exits = true
end -- Exits_Line

-- -----------------------------------------------------------------
-- 5. Here on description, or line *after* the description
-- -----------------------------------------------------------------

function Other_Line (name, line, wildcards, styles)
EnableTrigger ("Exits_Line", false)

-- if totally spaces, (and no description yet) skip it
if #line == 0 or not string.match (line, "%S") then
    if roomdesc == "" and map_str == "" then
      return
    end -- if
end -- if

-- see if a world map line

local char_count = 0
local letter_count = 0

for ch in string.gmatch (line, "[^A-HJ-Za-z]") do-- allow "I"
    char_count = char_count + 1
end -- for

for ch in string.gmatch (line, "%a") do
    letter_count = letter_count + 1
end -- for

-- if mainly dots and stuff, assume world map line
if char_count >= 12 and letter_count < char_count / 2 then
    map_str = map_str .. line
    return
end -- if

if #styles == 1 and map_str == "" then

    if styles .textcolour == GetNormalColour (8) and
       styles .backcolour == GetNormalColour (1) then
      -- description lines do not start with spaces, except the first one
      if roomdesc == "" or string.match (line, "^%S") then
      roomdesc = roomdesc .. " " .. line
      return
      end -- if not start with spaces
    end -- if right colours
end -- if a description line


-- ready for next time

EnableTrigger ("Other_Line", false)
EnableTrigger ("Name_Line", true)
   
if not got_hyphens then
    return
end -- no hyphens line
   
-- generate a "room ID" by hashing the room name, description and exits
uid = utils.tohex (utils.md5 (roomname .. roomdesc .. exits_str .. map_str))
uid = uid:sub (1, 10)    -- more manageable length

-- save so we know current room later on
current_room = uid

--ColourNote ("rosybrown", "", roomdesc)
--ColourNote ("olive", "", uid)

local room = rooms

-- not cached - see if in database
if not room then
    -- print ("Loading room", current_room, "from database")
    room = load_room_from_database (current_room)
end -- not in cache

if not got_exits then
    ColourNote ("palevioletred", "", [[
   
WARNING: I did not see a "Visible Exits:" line.
The mapper will not connect rooms to other rooms without it.
Please turn on the exits by typing:
]])
    ColourNote ("yellow", "", [[
         set show-exits
         
]])         
end -- if

if not room then
    -- print ("Added room", uid)-- debugging
    -- print ("Name", roomname)
    -- ColourNote ("rosybrown", "", roomdesc)
   
    db:exec ("BEGIN TRANSACTION;")

    save_room_to_database (current_room, roomname, Trim (roomdesc))
    save_exits_to_database (current_room, exits_str)
   
    db:exec ("COMMIT;")

    -- get it back now
    room = load_room_from_database (current_room)

end -- if room not there

-- call mapper to draw this rom
mapper.draw (current_room)    -- redraw room with name

-- try to work out where previous room's exit led
if expected_exit ~= uid and from_room then
    fix_up_exit ()
end -- exit was wrong

end -- Other_Line


function Shop_Line (name, line, wildcards)

-- location not known?
if not current_room then
    return
end -- if

if rooms .shop then
    return
end -- already a shop

-- mark as shop
rooms .shop = true

-- update database
dbcheck (db:execute (string.format (
      "UPDATE rooms SET shop = %i WHERE uid = %s;",
      fixbool (rooms .shop),
      fixsql (current_room)
      )))

-- note it
mapper.mapprint ("Room", current_room, "marked as a shop")

-- redraw
mapper.draw (current_room)

end -- Shop_Line

function Train_Line (name, line, wildcards)

-- location not known?
if not current_room then
    return
end -- if

if rooms .train then
    return
end -- already a train

-- mark as train
rooms .train = true

-- update database
dbcheck (db:execute (string.format (
      "UPDATE rooms SET train = %i WHERE uid = %s;",
      fixbool (rooms .train),
      fixsql (current_room)
      )))

-- note it
mapper.mapprint ("Room", current_room, "marked as a training room")

-- redraw
mapper.draw (current_room)

end -- Train_Line

-- -----------------------------------------------------------------
-- mapper 'get_room' callback - it wants to know about room uid
-- -----------------------------------------------------------------

function get_room (uid)

-- check we got room at all
if not uid then
   -- return nil
end -- if

-- look it up
local ourroom = rooms

-- not cached - see if in database
if not ourroom then
    ourroom = load_room_from_database (uid)
    rooms = ourroom -- cache for later
end -- not in cache

if not ourroom then
   return nil
end -- if

local room = copytable.deep (ourroom)

room.area = "Materia Magica"

if uid == current_room then
    current_area = room.area
end -- if

-- build hover message


local shop = ""
if room.shop then
    shop = "\nRoom is shop"
end -- if shop

local train = ""
if room.train then
    train = "\nRoom has trainer"
end -- if train
   
local notes = ""
if room.notes then
    notes = "\nBookmark: " .. room.notes
end -- if notes

local texits = {}
for dir in pairs (room.exits) do
    table.insert (texits, dir)
end -- for
table.sort (texits)
   
room.hovermessage = string.format (
      "%s\tExits: %s\nRoom: %s%s%s%s",
      room.name,
      table.concat (texits, ", "),
      uid,
      shop,
      train,
      notes
      -- depth,
      -- table.concat (path, ",")
      )
      
room.bordercolour = config.ROOM_COLOUR.colour
room.borderpen = 0 -- solid
room.borderpenwidth = 1
room.fillcolour = 0xff0000
room.fillbrush = 1 -- no fill
            
-- special room fill colours

if room.shop then
    room.fillcolour = config.SHOP_FILL_COLOUR.colour
    room.fillbrush = 8
end -- if

if room.train then
    room.fillcolour = config.TRAINER_FILL_COLOUR.colour
    room.fillbrush = 8
end -- if
         
if uid == current_room then
    room.bordercolour = config.OUR_ROOM_COLOUR.colour
    room.borderpenwidth = 2
elseif room.area ~= current_area then
    room.bordercolour = config.DIFFERENT_AREA_COLOUR.colour
end -- not in this area

return room      
      
end -- get_room

-- -----------------------------------------------------------------
-- We have changed rooms - work out where the previous room led to
-- -----------------------------------------------------------------

function fix_up_exit ()

-- where we were before
local room = rooms

-- print ("Moved from", from_room, "to", current_room, "in direction", last_direction_moved)

-- leads to here
if from_room ~= current_room then

    dbcheck (db:execute (string.format ([[
      UPDATE exits SET touid = %s WHERE fromuid = %s AND dir = %s;
      ]],
          fixsql(current_room),   -- destination room
          fixsql(from_room),       -- from previous room
          fixsql(last_direction_moved)-- direction (eg. "n")
          )))
   
    if show_database_mods then
      mapper.mapprint ("Fixed exit", last_direction_moved, "from room", from_room, "to be to", current_room)
    end -- if

    room.exits = current_room
end -- if
   
-- clear for next time
last_direction_moved = nil
from_room = nil

end -- fix_up_exit

-- -----------------------------------------------------------------
-- try to detect when we send a movement command
-- -----------------------------------------------------------------

function OnPluginSent (sText)
if valid_direction then
    last_direction_moved = valid_direction
    -- print ("Just moved", last_direction_moved)
    if current_room and rooms then
      expected_exit = rooms .exits
      if expected_exit then
      from_room = current_room
      end -- if
    -- print ("expected exit for this direction is to room", expected_exit)
    end -- if
end -- if
end -- function


default_config = {
-- assorted colours
BACKGROUND_COLOUR       = { name = "Background",      colour =ColourNameToRGB "lightseagreen", },
ROOM_COLOUR             = { name = "Room",            colour =ColourNameToRGB "cyan", },
EXIT_COLOUR             = { name = "Exit",            colour =ColourNameToRGB "darkgreen", },
EXIT_COLOUR_UP_DOWN   = { name = "Exit up/down",      colour =ColourNameToRGB "darkmagenta", },
EXIT_COLOUR_IN_OUT      = { name = "Exit in/out",       colour =ColourNameToRGB "#3775E8", },
OUR_ROOM_COLOUR         = { name = "Our room",          colour =ColourNameToRGB "black", },
UNKNOWN_ROOM_COLOUR   = { name = "Unknown room",      colour =ColourNameToRGB "#00CACA", },
DIFFERENT_AREA_COLOUR   = { name = "Another area",      colour =ColourNameToRGB "#009393", },
SHOP_FILL_COLOUR      = { name = "Shop",            colour =ColourNameToRGB "darkolivegreen", },
POSTOFFICE_FILL_COLOUR= { name = "Post Office",       colour =ColourNameToRGB "yellowgreen", },
BANK_FILL_COLOUR      = { name = "Bank",            colour =ColourNameToRGB "gold", },
NEWSROOM_FILL_COLOUR    = { name = "Newsroom",          colour =ColourNameToRGB "lightblue", },
TRAINER_FILL_COLOUR   = { name = "Trainer",         colour =ColourNameToRGB "lightgreen" },

ROOM_NAME_TEXT          = { name = "Room name text",    colour = ColourNameToRGB "#BEF3F1", },
ROOM_NAME_FILL          = { name = "Room name fill",    colour = ColourNameToRGB "#105653", },
ROOM_NAME_BORDER      = { name = "Room name box",   colour = ColourNameToRGB "black", },

AREA_NAME_TEXT          = { name = "Area name text",    colour = ColourNameToRGB "#BEF3F1",},
AREA_NAME_FILL          = { name = "Area name fill",    colour = ColourNameToRGB "#105653", },   
AREA_NAME_BORDER      = { name = "Area name box",   colour = ColourNameToRGB "black", },
               
FONT = { name =get_preferred_font {"Dina","Lucida Console","Fixedsys", "Courier", "Sylfaen",} ,
         size = 8
         } ,
         
-- size of map window
WINDOW = { width = 400, height = 400 },

-- how far from where we are standing to draw (rooms)
SCAN = { depth = 30 },

-- speedwalk delay
DELAY = { time = 0.3 },

-- how many seconds to show "recent visit" lines (default 3 minutes)
LAST_VISIT_TIME = { time = 60 * 3 },

}


-- -----------------------------------------------------------------
-- Plugin Install
-- -----------------------------------------------------------------

function OnPluginInstall ()

config = {}-- in case not found

-- get saved configuration
assert (loadstring (GetVariable ("config") or "")) ()

-- allow for additions to config
for k, v in pairs (default_config) do
    config = config or v
end -- for

-- initialize mapper

mapper.init { config = config,
                get_room = get_room,
                show_help = OnHelp,         -- to show help
                room_click = room_click,    -- called on RH click on room square
                timing = show_timing,       -- want to see timing
                show_completed = show_completed,-- want to see "Speedwalk completed." message
                show_other_areas = show_other_areas,-- want to see areas other than the current one?
                show_up_down = show_up_down,          -- want to follow up/down exits?
                show_area_exits = show_area_exits,    -- want to see area exits?
                speedwalk_prefix = speedwalk_prefix,-- how to speedwalk
}
mapper.mapprint (string.format ("MUSHclient mapper installed, version %0.1f", mapper.VERSION))

-- open databases on disk
db    = assert (sqlite3.open(GetInfo (66) .. Trim (WorldAddress ()) .. "_" .. WorldPort () .. ".db"))

create_tables ()    -- create database structure if necessary

end -- OnPluginInstall

-- -----------------------------------------------------------------
-- Plugin Save State
-- -----------------------------------------------------------------

function OnPluginSaveState ()
mapper.save_state ()
SetVariable ("config", "config = " .. serialize.save_simple (config))
end -- OnPluginSaveState

function map_resume (name, line, wildcards)

local wanted = mapper.last_hyperlink_uid or mapper.last_speedwalk_uid

if not wanted then
    mapper.print "No outstanding speedwalks or hyperlinks."
    return
end -- if nothing to do

-- find desired room
mapper.find (
    function (uid)
      return uid == wanted, uid == wanted
    end,-- function
    show_vnums,-- show vnum?
    1,      -- how many to expect
    true    -- just walk there
    )
      
end -- map_resume

function map_goto (name, line, wildcards)

local wanted = wildcards

-- check valid string
if string.match (wanted, "%X") then
    mapper.maperror ("Room number must be hex string (0-9, A-F), you entered: " .. wanted)
    return
end -- if

-- internally rooms are upper-case hex
wanted = wanted:upper ()

-- see if already there
if current_room and string.match (current_room, "^" .. wanted) then
    mapper.mapprint ("You are already in that room.")
    return
end -- if

-- find desired room
mapper.find (
    function (uid)
      local found = string.match (uid, "^" .. wanted)
      return found, found
    end,-- function
    show_vnums,-- show vnum?
    1,          -- how many to expect
    true      -- just walk there
    )
      
end -- map_goto

function map_where (name, line, wildcards)

if not mapper.check_we_can_find () then
    return
end -- if

local wanted = wildcards

if current_room and wanted == current_room then
    mapper.mapprint ("You are already in that room.")
    return
end -- if

local paths = mapper.find_paths (current_room,
         function (uid)
             return uid == wanted,-- wanted room?
                  uid == wanted   -- stop searching?
            end)

local uid, item = next (paths, nil) -- extract first (only) path

-- nothing? room not found
if not item then
    mapper.mapprint (string.format ("Room %s not found", wanted))
    return
end -- if

-- turn into speedwalk
local path = mapper.build_speedwalk (item.path)

-- display it
mapper.mapprint (string.format ("Path to %s is: %s", wanted, path))

end -- map_where

function OnHelp ()
mapper.mapprint (string.format ("", mapper.VERSION))
mapper.mapprint (world.GetPluginInfo (world.GetPluginID (), 3))
end



room_not_in_database = {}
room_in_database = {}

function dbcheck (code)

if code ~= sqlite3.OK and    -- no error
    code ~= sqlite3.ROW and   -- completed OK with another row of data
    code ~= sqlite3.DONE then -- completed OK, no more rows
    local err = db:errmsg ()-- the rollback will change the error message
    db:exec ("ROLLBACK")      -- rollback any transaction to unlock the database
    error (err, 2)            -- show error in caller's context
end -- if

end -- dbcheck

function fixsql (s)

if s then
    return "'" .. (string.gsub (s, "'", "''")) .. "'" -- replace single quotes with two lots of single quotes
else
    return "NULL"
end -- if
end -- fixsql

function fixbool (b)
if b then
    return 1
else
    return 0
end -- if
end -- fixbool

function load_room_from_database (uid)

local room

assert (uid, "No UID supplied to load_room_from_database")

-- if not in database, don't look again
if room_not_in_database then
    return nil
end -- no point looking

for row in db:nrows(string.format ("SELECT * FROM rooms WHERE uid = %s", fixsql (uid))) do
   room = {
       name = row.name,
       area = row.area,
       description = row.description,
       shop = row.shop,
       train = row.train,
       notes = row.notes,

       exits = {} }
      
    for exitrow in db:nrows(string.format ("SELECT * FROM exits WHERE fromuid = %s", fixsql (uid))) do
       room.exits = tostring (exitrow.touid)
    end -- for each exit
   
end   -- finding room

if room then
    rooms = room
    return room
end -- if found

room_not_in_database = true
return nil
   
end -- load_room_from_database


function save_room_to_database (uid, title, description)

assert (uid, "No UID supplied to save_room_to_database")

dbcheck (db:execute (string.format (
      "INSERT INTO rooms (uid, name, description, date_added) VALUES (%s, %s, %s, DATETIME('NOW'));",
          fixsql (uid),
          fixsql (title),
          fixsql (description)
      )))
      
dbcheck (db:execute (string.format ([[
      INSERT INTO rooms_lookup (uid, name, description) VALUES (%s, %s, %s);
      ]], fixsql(uid),      
          fixsql(title),
          fixsql(description)
          )))
      
room_not_in_database = false

if show_database_mods then
    mapper.mapprint ("Added room", uid, "to database. Name:", title)
end -- if

end -- function save_room_to_database
      
function save_exits_to_database (uid, exits)

for dir in string.gmatch (exits, "%a+") do

    -- fix up in and out
    dir = ({ ['i'] = "in", o = "out", }) or dir
   
    dbcheck (db:execute (string.format ([[
      INSERT INTO exits (dir, fromuid, touid, date_added)
          VALUES (%s, %s, %s, DATETIME('NOW'));
    ]], fixsql(dir),-- direction (eg. "n")
      fixsql(uid),         -- from current room
      fixsql(0)   -- destination room (not known)
      )))
    if show_database_mods then
      -- mapper.mapprint ("Added unknown exit", dir, "from room", uid, "to database.")
    end -- if

end -- for each exit

end -- function save_exits_to_database


function create_tables ()
-- create rooms table
dbcheck (db:execute[[

PRAGMA foreign_keys = ON;
PRAGMA journal_mode = WAL;

CREATE TABLE IF NOT EXISTS rooms (
      roomid      INTEGER PRIMARY KEY AUTOINCREMENT,
      uid         TEXT NOT NULL,   -- vnum or how the MUD identifies the room
      name          TEXT,            -- name of room
      description   TEXT,            -- description
      building      TEXT,            -- which building it is in
      shop          INTEGER,         -- 1 = shop here
      train         INTEGER,         -- 1 = trainer here
      notes         TEXT,            -- player notes
      date_added    DATE,            -- date added to database
      UNIQUE (uid)
    );
CREATE INDEX IF NOT EXISTS shop_index ON rooms (shop);
CREATE INDEX IF NOT EXISTS train_index ON rooms (train);

CREATE TABLE IF NOT EXISTS exits (
      exitid      INTEGER PRIMARY KEY AUTOINCREMENT,
      dir         TEXT    NOT NULL, -- direction, eg. "n", "s"
      fromuid   TEXT    NOT NULL, -- exit from which room (in rooms table)
      touid       TEXT    NOT NULL, -- exit to which room (in rooms table)
      date_addedDATE,             -- date added to database
      FOREIGN KEY(fromuid) REFERENCES rooms(uid)
    );
CREATE INDEX IF NOT EXISTS fromuid_index ON exits (fromuid);
CREATE INDEX IF NOT EXISTS touid_index   ON exits (touid);

]])

-- check if rooms_lookup table exists
local table_exists
for a in db:nrows "SELECT * FROM sqlite_master WHERE name = 'rooms_lookup' AND type = 'table'" do
    table_exists = true
end-- for

if not table_exists then
    dbcheck (db:execute "CREATE VIRTUAL TABLE rooms_lookup USING FTS3(uid, name, description);")
    -- in case we only deleted the rooms_lookup table to save space in the download
    dbcheck (db:execute "INSERT INTO rooms_lookup (uid, name, description) SELECT uid, name, description FROM rooms;")
end -- if
   
      
end -- function create_tables

function room_edit_bookmark (room, uid)

local notes = room.notes or ""

if notes ~= "" then
    newnotes = utils.inputbox ("Modify room comment (clear it to delete from database)", room.name, notes)
else
    newnotes = utils.inputbox ("Enter room comment (creates a bookmark for this room)", room.name, notes)
end -- if

if not newnotes then
    return
end -- if cancelled

if newnotes == "" then
    if notes == "" then
      mapper.mapprint ("No comment entered, bookmark not saved.")
      return
    else
      dbcheck (db:execute (string.format (
      "UPDATE rooms SET notes = NULL WHERE uid = %s;",
          fixsql (uid)
      )))
      mapper.mapprint ("Bookmark for room", uid, "deleted. Was previously:", notes)
      rooms .notes = nil
      return
    end -- if
end -- if

if notes == newnotes then
    return -- no change made
end -- if

dbcheck (db:execute (string.format (
      "UPDATE rooms SET notes = %s WHERE uid = %s;",
      fixsql (newnotes),
      fixsql (uid)
      )))
   
if notes ~= "" then
   mapper.mapprint ("Bookmark for room", uid, "changed to:", newnotes)
else
   mapper.mapprint ("Bookmark added to room", uid, ":", newnotes)
   end -- if   
   
   rooms .notes = newnotes
   
end -- room_edit_bookmark

function room_toggle_shop (room, uid)
   
rooms .shop = not rooms .shop

dbcheck (db:execute (string.format (
      "UPDATE rooms SET shop = %i WHERE uid = %s;",
      fixbool (rooms .shop),
      fixsql (uid)
      )))

if rooms .shop then
    mapper.mapprint ("Room", uid, "marked as a shop")
else
    mapper.mapprint ("Room", uid, "not a shop any more")
end   

mapper.draw (current_room)
   
end -- room_toggle_shop

function room_toggle_train (room, uid)
   
rooms .train = not rooms .train

dbcheck (db:execute (string.format (
      "UPDATE rooms SET train = %i WHERE uid = %s;",
      fixbool (rooms .train),
      fixsql (uid)
      )))

if rooms .train then
    mapper.mapprint ("Room", uid, "marked as a training room")
else
    mapper.mapprint ("Room", uid, "not a training room any more")
end   

mapper.draw (current_room)
   
end -- room_toggle_train



function room_add_exit (room, uid)

local available ={
n = "North",
s = "South",
e = "East",
w = "West",
u = "Up",
d = "Down",
ne = "Northeast",
sw = "Southwest",
nw = "Northwest",
se = "Southeast",
['in'] = "In",
out = "Out",
}-- end of available

-- remove existing exits
for k in pairs (room.exits) do
    available = nil
end -- for

if next (available) == nil then
    utils.msgbox ("All exits already used.", "No free exits!", "ok", "!", 1)
    return
end -- not known

local chosen_exit = utils.listbox ("Choose exit to add", "Exits ...", available )
if not chosen_exit then
    return
end

exit_destination = utils.inputbox ("Enter destination room identifier (number) for " .. available , room.name, "")

if not exit_destination then
    return
end -- cancelled

    -- look it up
local dest_room = rooms

-- not cached - see if in database
if not dest_room then
    dest_room = load_room_from_database (exit_destination)
    rooms = dest_room -- cache for later
end -- not in cache

if not dest_room then
    utils.msgbox ("Room " .. exit_destination .. " does not exist.", "Room does not exist!", "ok", "!", 1)
    return
end -- if still not there

dbcheck (db:execute (string.format ([[
    INSERT INTO exits (dir, fromuid, touid, date_added)
      VALUES (%s, %s, %s, DATETIME('NOW'));
]], fixsql(chosen_exit),-- direction (eg. "n")
      fixsql(uid),-- from current room
      fixsql(exit_destination) -- destination room
      )))
if show_database_mods then
    mapper.mapprint ("Added exit", available , "from room", uid, "to room", exit_destination, "to database.")
end -- if

-- update in-memory table
rooms .exits = exit_destination

mapper.draw (current_room)
   
end -- room_add_exit


function room_delete_exit (room, uid)

local available ={
n = "North",
s = "South",
e = "East",
w = "West",
u = "Up",
d = "Down",
ne = "Northeast",
sw = "Southwest",
nw = "Northwest",
se = "Southeast",
['in'] = "In",
out = "Out",
}-- end of available

-- remove non-existent exits
for k in pairs (available) do
    if room.exits then
      available = available .. " --> " .. room.exits
    else
      available = nil
    end -- if not a room exit
end -- for

if next (available) == nil then
    utils.msgbox ("There are no exits from this room.", "No exits!", "ok", "!", 1)
    return
end -- not known

local chosen_exit = utils.listbox ("Choose exit to delete", "Exits ...", available )
if not chosen_exit then
    return
end

dbcheck (db:execute (string.format ([[
    DELETE FROM exits WHERE dir = %s AND fromuid = %s;
]], fixsql(chosen_exit),-- direction (eg. "n")
      fixsql(uid)-- from current room
      )))
if show_database_mods then
    mapper.mapprint ("Deleted exit", available , "from room", uid, "from database.")
end -- if

-- update in-memory table
rooms .exits = nil

mapper.draw (current_room)
   
end -- room_delete_exit


function room_change_exit (room, uid)

local available ={
n = "North",
s = "South",
e = "East",
w = "West",
u = "Up",
d = "Down",
ne = "Northeast",
sw = "Southwest",
nw = "Northwest",
se = "Southeast",
['in'] = "In",
out = "Out",
}-- end of available

-- remove non-existent exits
for k in pairs (available) do
    if room.exits then
      available = available .. " --> " .. room.exits
    else
      available = nil
    end -- if not a room exit
end -- for

if next (available) == nil then
    utils.msgbox ("There are no exits from this room.", "No exits!", "ok", "!", 1)
    return
end -- not known

local chosen_exit = utils.listbox ("Choose exit to change destination of:", "Exits ...", available )
if not chosen_exit then
    return
end

exit_destination = utils.inputbox ("Enter destination room identifier (number) for " .. available , room.name, "")

if not exit_destination then
    return
end -- cancelled

    -- look it up
local dest_room = rooms

-- not cached - see if in database
if not dest_room then
    dest_room = load_room_from_database (exit_destination)
    rooms = dest_room -- cache for later
end -- not in cache

if not dest_room then
    utils.msgbox ("Room " .. exit_destination .. " does not exist.", "Room does not exist!", "ok", "!", 1)
    return
end -- if still not there
   
dbcheck (db:execute (string.format ([[
    UPDATE exits SET touid = %s WHERE dir = %s AND fromuid = %s;
]], fixsql(exit_destination),
      fixsql(chosen_exit),-- direction (eg. "n")
      fixsql(uid)-- from current room
      )))
      
if show_database_mods then
    mapper.mapprint ("Modified exit", available , "from room", uid, "to be to room", exit_destination, "in database.")
end -- if

-- update in-memory table
rooms .exits = exit_destination
mapper.draw (current_room)
   
end -- room_change_exit

function room_click (uid, flags)

-- check we got room at all
if not uid then
    return nil
end -- if

-- look it up
local room = rooms

-- not cached - see if in database
if not room then
    room = load_room_from_database (uid)
    rooms = room -- cache for later
end -- not in cache

if not room then
    return
end -- if still not there

local handlers = {
      { name = "Edit bookmark", func = room_edit_bookmark} ,
      { name = "-", } ,
      { name = "Add Exit", func = room_add_exit} ,
      { name = "Change Exit", func = room_change_exit} ,
      { name = "Delete Exit", func = room_delete_exit} ,
      { name = "-", } ,
      { name = "Toggle Shop", func = room_toggle_shop } ,
      { name = "Toggle Trainer", func = room_toggle_train } ,
   } -- handlers
      
local t, tf = {}, {}
for _, v in pairs (handlers) do
    table.insert (t, v.name)
    tf = v.func
end -- for
      
local choice = WindowMenu (mapper.win,
                            WindowInfo (mapper.win, 14),
                            WindowInfo (mapper.win, 15),
                            table.concat (t, "|"))
   
local f = tf

if f then
    f (room, uid)
end -- if handler found
                           
end -- room_click


function map_find (name, line, wildcards)

local rooms = {}
local count = 0
local snippets = {}
local reset = ANSI (0)
local bold = ANSI (1)
local unbold = ANSI (22)

function show_snippet (uid)
    AnsiNote (reset .. snippets )
end -- show_snippet


-- find matching rooms using FTS3
for row in db:nrows(string.format (
   [[
   SELECT uid, name, snippet(rooms_lookup, '%s', '%s', ' ... ', -1, -10) AS snippet
      FROM rooms_lookup
      WHERE rooms_lookup MATCH %s]],
      bold, unbold,
      fixsql (wildcards ))) do
   rooms = true
   snippets = row.snippet
   count = count + 1
end   -- finding room

-- see if nearby
mapper.find (
    function (uid)
      local room = rooms
      if room then
      rooms = nil
      end -- if
      return room, next (rooms) == nil
    end,-- function
    show_vnums,-- show vnum?
    count,      -- how many to expect
    false,       -- don't auto-walk
    show_snippet -- show find snippet
    )

end -- map_find

function map_bookmarks (name, line, wildcards)

local rooms = {}
local count = 0

-- build table of special places (with info in them)
for row in db:nrows(string.format ("SELECT uid, notes FROM rooms WHERE notes IS NOT NULL")) do
   rooms = capitalize (row.notes)
   count = count + 1
end   -- finding room

-- find such places
mapper.find (
    function (uid)
      local room = rooms
      if room then
      rooms = nil
      end -- if
      return room, next (rooms) == nil-- room will be type of info (eg. shop)
    end,-- function
    show_vnums,-- show vnum?
    count,       -- how many to expect
    false      -- don't auto-walk
    )
      
end -- map_bookmarks

function map_find_special (which)

local rooms = {}
local count = 0

-- build table of special places (with info in them)
for row in db:nrows(string.format ("SELECT uid, name FROM rooms WHERE %s = 1", which)) do
    rooms = true
    count = count + 1
end   -- finding room

-- find such places
mapper.find (
    function (uid)
      local room = rooms
      if room then
      rooms = nil
      end -- if
      return room, next (rooms) == nil-- room will be type of info (eg. shop)
    end,-- function
    show_vnums,-- show vnum?
    count,      -- how many to expect
    false       -- don't auto-walk
    )
      
end -- map_find_special

function map_shops (name, line, wildcards)
map_find_special ("shop")
end -- map_shops

function map_trainers (name, line, wildcards)
map_find_special ("train")
end -- map_trainers


function Door_Closed (name, line, wildcards)

local dirs ={
n = "north",
s = "south",
e = "east",
w = "west",
u = "up",
d = "down",
ne = "northeast",
sw = "southwest",
nw = "northwest",
se = "southeast",
['in'] = "in",
out = "out",
}-- end of available

if last_direction_moved then
    Send ("open " .. dirs )
    Send (dirs )
end -- if

end -- Door_Closed

]]>
</script>


</muclient>我是完全看不懂啊

nsonline 发表于 2013-4-7 17:44:04

这个不适用于北侠

jizong 发表于 2013-4-8 15:40:26

回复 3# nsonline


    修改一下呢?能否就适应呢?

nsonline 发表于 2013-4-8 17:39:04

回复 4# jizong


    改肯定可以啊,不过改动会灰常大
页: [1]
查看完整版本: 最近没有研究mush的地图插件了么?求指导啊