最近没有研究mush的地图插件了么?求指导啊
最近没有研究mush的地图插件了么?求指导啊创建地图,快速寻路,移动什么的~~~求指导啊
北大侠客行MUD,中国最好的MUD 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/"]+)$"
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>我是完全看不懂啊 这个不适用于北侠 回复 3# nsonline
修改一下呢?能否就适应呢? 回复 4# jizong
改肯定可以啊,不过改动会灰常大
页:
[1]