lzkd 发表于 2014-11-8 09:32:53

mapper.lua心得(完)

本帖最后由 lzkd 于 2014-12-6 07:41 PM 编辑

.
前言

  大家好,真的是好久不见了。好象小刀离开了很长一段时间吧,再次进入北侠的时候,许多人都不见了,许多人都不认识了。还好,总是有那么几个人留了下来。八科在,静电清水在,hash在,howoldareyou在……不过,更多的都是不认识的新面孔了。呵呵,一笑。
  就小刀个人而言,北侠现在被改到几乎不认识了。又是一种从新开始的感觉。这种感觉,无所谓好,或者不好。不管如何,既然再想进入北侠,总是要面对的。这些就不多说

  因为地图都变了,所以小刀一时间找不到进入的感觉了。所以,先把这段时间琢磨的mapper.lua的心得给到大家吧。希望对大家有所帮助,也希望在写的过程中,慢慢恢复以前在北侠的感觉。
  好了,不多说那些有的没的,说说mapper.lua。这个文件,是MUSHclient自带的一个文件,也可以理解成一个摇件包。主要是处理一些地图相关的东西。许多人把它想的很神秘,老觉得,如果会了,可能一切都简单了。
  事实上,小刀以前也是这么想的。不过,真实的情况是,mapper.lua是强大的,但也不是万能的(当然,这也可能只是小刀功力不够的缘故。呵呵,一笑)。下面,让我们一起来感受一下mapper.lua的魅力吧。

—————————— 我就是可爱的分割线 ———————————写作日志
2014.11.13 完成结束语
2014.11.11 完成第五章(光棍节,今天是光棍节的说)
2014.11.11 完成第五章(光棍节,今天是光棍节哦)
2014.11.10 完成第四章
2014.11.09 完成第三章(因为一个比较爽的事情,加更,说的好象是在起点似的)
2014.11.09 完成第二章
2014.11.08 完成前言、启用,两个部分
2014.11.08 因为想恢复状态(这理由,啧啧)开始写本文。

—————————— 这是传说中的下载区 ———————————
一、启用(配套插件)

二、得到你的第一个房间(配套插件)

三、载入多个房间(配套插件)
.

四、载入在北侠的第一个房间(配套插件)

五、在北侠的即视行走



—————————— 下载区真的结束鸟哦 ———————————

一、启用

  既然是插件篇,当然写的东西,都是以插件的形式来表达,我们先看第一个插件,如何最简单的调用mapper.lua。

  首先,我们要加载插件。具体代码见下面,当然,也可以到本帖顶部下载区下载。(如果连加载插件都不会的,拉出去tjj100遍,然后去看完我或者静电的教程再过来)。
  如果加载完以后,可以看见如下所示图片,则恭喜你,mapper.lua的调用成功了。你已经跨出了具有里程碑意义的一步(记得有机会请小刀和晓晓吃饭哈)




<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<muclient>
<plugin
name="Example_Mapper"
author="PkuXkx Lzkd"
id="63e6909083318cf63707c044"
language="Lua"
purpose="Example mapper"
save_state="y"
date_written="2014-11-8"
requires="4.61"
version="1.0"
>

<description trim="y">
<![CDATA[
Description here.
]]>
</description>

</plugin>

<!-- Script -->

<script>
<![CDATA[

-- mapper.lua 载入
require "mapper"

-- configuration table
config = { }

-- -----------------------------------------------------------------
-- mapper 'get_room' callback - 得到一个房间的uid(即唯一房间标志)
-- -----------------------------------------------------------------
function get_room (uid)
return room
end -- get_room

-- -----------------------------------------------------------------
-- Plugin Install
-- -----------------------------------------------------------------
function OnPluginInstall ()
-- 加载 mapper
mapper.init {
config = config, -- ie. colours, sizes
get_room = get_room, -- info about room (uid)
}

mapper.mapprint (string.format ("MUSHclient mapper installed, version %0.1f", mapper.VERSION)) --这里应该可以打印出中文的,有兴趣的可以自己琢磨
end

]]>
</script>
</muclient>

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

lzkd 发表于 2014-11-8 09:33:06

本帖最后由 lzkd 于 2014-11-9 05:27 PM 编辑

二、得到你的第一个房间
  在这里,提醒一下大家。插件里的东西,和一般的,还是有些不同的。比如说,你无法直接运行插件里的函数。但可以用一些变通的方法。比如说,象今天我展示的这个——在插件里写alias,然后通过alias调用函数。
  得到第一个房间的语句很简单。大家注意,这个1,是房间的唯一标志码,在mapper.lua中,被称为uid。
mapper.draw (1)-- draw room 1
  载入插件后,我们在命令窗口,输入:"mapper test",(去掉引号)就可以得到如下的图。那个红圈里,就是我们的第一个房间,眼神不好的人,整近一点看吧。



  插件代码:
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<muclient>
<plugin
   name="Example_Mapper"
   author="PkuXkx Lzkd"
   id="63e6909083318cf63707c044"
   language="Lua"
   purpose="Example mapper"
   save_state="y"
   date_written="2014-11-9"
   requires="4.61"
   version="1.0"
   >

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

ACTIONS

mapper help         --> this help(or click the "?" button on the bottom right)
]]>
</description>

</plugin>

<aliases>

<alias
   match="mapper test"
   script="test"
   enabled="y"
>
</alias>

</aliases>

<!--Script-->

<script>
<![CDATA[

-- mapper module
require "mapper"

-- configuration table
config = { }   

-- -----------------------------------------------------------------
-- mapper 'get_room' callback - 得到一个 room uid
-- -----------------------------------------------------------------
function get_room (uid)
return room
end -- get_room

-- -----------------------------------------------------------------
-- Plugin Install      --加载插件
-- -----------------------------------------------------------------
function OnPluginInstall ()
-- initialize mapper
mapper.init {
            config   = config,   -- ie. colours, sizes
            get_room   = get_room, -- info about room (uid)
            show_help= OnHelp,   -- to show help
            }
               
mapper.mapprint (string.format ("MUSHclient mapper installed, version %0.1f", mapper.VERSION))
end -- OnPluginInstall

-- -----------------------------------------------------------------
-- test                --载入你的第一个房间
-- -----------------------------------------------------------------
function test (name, line, wildcards)
mapper.draw (1)-- draw room 1
end -- test

]]>
</script>
</muclient>

lzkd 发表于 2014-11-8 09:33:13

本帖最后由 lzkd 于 2014-11-10 05:09 PM 编辑

三、载入多个房间

  我们来设想一下,一般地图显示的基本过程。首先,是得到地图数据;然后,要将数据以符合要求的格式排列;最后才是显示。现有,我们假设,我们已经有了一部分地图资料,具体如下:
rooms = {

= {
      name = "Pkuxkx Palace",
      exits = { n = 2, s = 3, e = 4}
      },

= {
      name = "Lzkd's House",
      exits = { s = 1 }
      },

= {
      name = "Lxiao's House",
      exits = { n = 1}
      },
               
= {
      name = "Lkyun's House",
      exits = { w = 1, e = 5}
      },

= {
      name = "Ajump and Hash and Laobeng's House",
      exits = {w = 4}
      },
               
      }-- rooms table样版
  大家一定要关注这个结构,在mapper.lua里,地图的基本结构,就是这样的。换句话说,如果你想使用mapper.lua,就得把自己的数据,整成这种结构。 

  然后,我们来看一下,如何通过mapper.lua得到地图。载入插件后,输入:"mapper test",(去掉引号),得到如下图所:

  大家注意看,地图顶部的--"Pkuxkx Palace"--这是房间的名字,理论上,修改mapper.lua,可以让这里变成中文。不过暂时小刀是没这本事了,期待大牛的出现。另外,将鼠标悬停在地图的房间上面,也可以看见房间名。如下图:(大家可以试看看,最后一个房间的房间名,嘿嘿)

  好了,最后放出插件,同样顶部提供下载。

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<muclient>
<plugin
   name="Example_Mapper"
   author="PkuXkx Lzkd"
   id="63e6909083318cf63707c044"
   language="Lua"
   purpose="Example mapper"
   save_state="y"
   date_written="2014-11-9"
   requires="4.61"
   version="1.0"
   >

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

ACTIONS

mapper help         --> this help(or click the "?" button on the bottom right)
]]>
</description>

</plugin>

<aliases>

<alias
   match="mapper test"
   script="test"
   enabled="y"
>
</alias>

</aliases>

<!--Script-->

<script>
<![CDATA[

-- mapper module
require "mapper"

-- configuration table
config = { }   

rooms = {

= {
      name = "Pkuxkx Palace",
      exits = { n = 2, s = 3, e = 4}
      },

= {
      name = "Lzkd's House",
      exits = { s = 1 }
      },

= {
      name = "Lxiao's House",
      exits = { n = 1}
      },
               
= {
      name = "Lkyun's House",
      exits = { w = 1, e = 5}
      },

= {
      name = "Ajump and Hash and Laobeng's House",
      exits = {w = 4}
      },
               
      }-- rooms table样版
      
-- -----------------------------------------------------------------
-- mapper 'get_room' callback - 得到当前房间的uid
-- -----------------------------------------------------------------
function get_room (uid)

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

room.area = "The swamp"-- OK, let's assume every room is in this area
room.hovermessage = room.name

return room
end -- get_room

-- -----------------------------------------------------------------
-- Plugin Install      --插件安装
-- -----------------------------------------------------------------
function OnPluginInstall ()
-- initialize mapper
mapper.init {
            config   = config,   -- ie. colours, sizes
            get_room   = get_room, -- info about room (uid)
            show_help= OnHelp,   -- to show help
            }
               
mapper.mapprint (string.format ("MUSHclient mapper installed, version %0.1f", mapper.VERSION))
end -- OnPluginInstall


-- -----------------------------------------------------------------
-- test                --这里跟上次一样
-- -----------------------------------------------------------------
function test (name, line, wildcards)
mapper.draw (1)-- draw room 1
end -- test

]]>
</script>
</muclient>

lzkd 发表于 2014-11-8 09:33:20

本帖最后由 lzkd 于 2014-11-10 06:13 PM 编辑

四、生成在北侠的第一个房间

  要在MUD里定位房间,一个难点,就是如何保证这个房间的唯一性。为了琢磨mapper.lua小刀前段时间跑国外的MUD去学习了。发现国外有的MUD,会直接在LOOK以后,告诉你,这个房间的唯一ID是什么,这真是太幸福了。  那,作为一个教程,怎么来给所抓的房间定唯一ID呢?mapper.lua的作者Nick给了一个很有趣的方案——根据房间名+当地描述,然后用MD5加密以后,作为唯一的标志。大家可以在后面的代码中,感受到这一点。

  先上两张图,大家可以看到,移动后,房间的uid就变了,为了清晰,我在屏幕上print了uid,在地图窗口上,我也将uid显示出来了。





  说一下怎么做到的。载入插件,进入北侠以后,先unset brief,这是为统一显示,然后随意行走。大家可以看见地图上的房间在不停的变动。下面给出代码,因为已经在代码中写了很详细的注释,就不在这里多说了。

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<muclient>
<plugin
   name="Example_Mapper"
   author="PkuXkx Lzkd"
   id="63e6909083318cf63707c044"
   language="Lua"
   purpose="Example mapper"
   save_state="y"
   date_written="2014-11-10"
   requires="4.61"
   version="1.0"
   >

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

ACTIONS

mapper help         --> this help(or click the "?" button on the bottom right)
]]>
</description>

</plugin>

<aliases>

</aliases>

<triggers>
<trigger
   enabled="y"
   keep_evaluating="y"
   match="^(> )*    这里.*的出口是(.*)$"
   regexp="y"
   script="got_prompt"
   sequence="100">
</trigger>

<trigger
   enabled="y"
   keep_evaluating="y"
   match="^(> )*([^>;:+-.,]{1,16}) \- $"
   regexp="y"
   script="got_room_name"
   sequence="10"
>
</trigger>
</triggers>

<!--Script-->

<script>
<![CDATA[

-- mapper module
require "mapper"

-- 配置文件
config = { }   

-- 地图数据存放变量
rooms = { }

-- -----------------------------------------------------------------
-- mapper 'get_room' callback - 得到房间的唯一uid
-- -----------------------------------------------------------------
function get_room (uid)

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

room.area = "The swamp"-- OK, let's assume every room is in this area
room.hovermessage = room.name
return room
end -- get_room

-- -----------------------------------------------------------------
-- Plugin Install        --载入插件
-- -----------------------------------------------------------------
function OnPluginInstall ()
-- initialize mapper
mapper.init {
            config   = config,   -- ie. colours, sizes
            get_room   = get_room, -- info about room (uid)
            show_help= OnHelp,   -- to show help
            }
               
mapper.mapprint (string.format ("MUSHclient mapper installed, version %0.1f", mapper.VERSION))
end -- OnPluginInstall


-- -----------------------------------------------------------------
-- Here on prompt        --显示地图
-- -----------------------------------------------------------------
function got_prompt (name, line, wildcards)
room_name = uid.."'s House"                --uid + "House",这里可以进行各种变化
-- 将数据添加到rooms变量
if not rooms then
    rooms = { name = room_name, exits = {}}        --大家注意这里,exites都是空的
end -- if

-- 显示地图
mapper.draw (uid)
end -- got_prompt

-- -----------------------------------------------------------------
-- Here on room name        --这里应该得到room_name的地方,现在我用来生成唯一的uid
-- -----------------------------------------------------------------
function got_room_name (name, line, wildcards)
local name = wildcards         --这句目前没什么意义
print(wildcards )        --按正常的思路,这个值,应该就是room_name,但目前mapper.lua不支付中文,为了看出效果,先这样
uid = utils.tohex (utils.md5 (wildcards ))                --取北侠当前房间名的MD5码
uid = uid:sub (1, 10)    -- 仅取前10位数,以简化数据
print(uid)                --为了让教程看出效果,加了这句

room_name = name        --这句目前没什么意义,只是为了表示这里应该取room_name
end -- got_room_name


]]>
</script>
</muclient>

lzkd 发表于 2014-11-8 09:33:24

本帖最后由 lzkd 于 2014-12-6 07:42 PM 编辑

五、在北侠的即视行走

  这个章节名,起的比较文艺范。也许,小刀只是一个伪装的教程作者,骨子里其实是一个那啥青年,谁知道呢。
  好了,说了些好象没用的东西。其实,小刀想表达的是,这一章的视觉效果是比较惊人的。假设一下,我们在一个陌生的MUD里,我们对于眼前的一切,一无所知。在这种情况下,我们的每一步行走,都如破开迷雾般的,在地图上留下了痕迹,就是何等一种惊人。

  我们来看一下效果。

  ==>这是在武庙,当然,第一张,看不出什么来的。


  ==>然后,走到巫师会客室。怎么样,有点样子了吧。


  ==>现在,我们来到了北大街。注意黑框哈。


  ==>继续,我们east一下,到了醉仙楼(楼底下)
.



  ==>好,现在我们up一下,上楼。


  ==>醉仙楼,里面不止一个房间,我们再往前走。

lzkd 发表于 2014-11-8 09:33:28

本帖最后由 lzkd 于 2014-11-11 07:35 PM 编辑

下面,放出插件代码。同样,顶部下载区提供下载。代码中有详细的解释,应该都能看明白了。就不在这里多话了。
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<muclient>
<plugin
   name="Example_Mapper"
   author="PkuXkx Lzkd"
   id="63e6909083318cf63707c044"
   language="Lua"
   purpose="Example mapper"
   save_state="y"
   date_written="2014-10-22"
   requires="4.61"
   version="1.0"
   >

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

ACTIONS

mapper help         --> this help(or click the "?" button on the bottom right)
]]>
</description>

</plugin>

<aliases>

</aliases>

<triggers>
<trigger
   enabled="y"
   keep_evaluating="y"
   match="^(> )*    这里.*的出口是(.*)$"
   regexp="y"
   script="got_prompt"
   sequence="100">
</trigger>

<trigger
   enabled="y"
   keep_evaluating="y"
   match="^(> )*([^>;:+-.,]{1,16}) \- $"
   regexp="y"
   script="got_room_name"
   sequence="10"
>
</trigger>
</triggers>

<!--Script-->

<script>
<![CDATA[

-- mapper module
require "mapper"

-- 参数设置
config = {
      OUR_ROOM_COLOUR         = { name = "Our room",colour =ColourNameToRGB "black", },
         }   

-- 地图数据存放变量
rooms = { }


-- -----------------------------------------------------------------
-- 房间变动的命令记录
-- -----------------------------------------------------------------
local 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

-- 返回路径
local inverse_direction = {
n = "s",
s = "n",
e = "w",
w = "e",
u = "d",
d = "u",
ne = "sw",
sw = "ne",
nw = "se",
se = "nw",
['in'] = "out",
out = "in",
}-- end of inverse_direction

-- -----------------------------------------------------------------
-- mapper 'get_room' callback - 得到房间的唯一uid
-- -----------------------------------------------------------------
function get_room (uid)

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


-- 如何画出一个房间
room.bordercolour = config.ROOM_COLOUR.colour
room.borderpen = miniwin.pen_solid
room.borderpenwidth = 1
room.fillbrush = miniwin.brush_null-- no fill

-- 当前房间做出不同的颜色标记
if uid == current_room then
    room.bordercolour = config.OUR_ROOM_COLOUR.colour
    room.borderpenwidth = 2
end -- not in this area

room.area = "The swamp"-- 假设每个房间都在这个区域(这里是以后进阶的分城地图所用,你懂的)
room.hovermessage = room.name
return room
end -- get_room

-- -----------------------------------------------------------------
-- Plugin Install        --载入插件
-- -----------------------------------------------------------------
function OnPluginInstall ()
-- initialize mapper
mapper.init {
            config   = config,   -- ie. colours, sizes
            get_room   = get_room, -- info about room (uid)
            show_help= OnHelp,   -- to show help
            }
               
mapper.mapprint (string.format ("MUSHclient mapper installed, version %0.1f", mapper.VERSION))
end -- OnPluginInstall

-- -----------------------------------------------------------------
-- Here on prompt        --显示地图
-- -----------------------------------------------------------------
function got_prompt (name, line, wildcards)
room_name = uid.."'s House"                --uid + "House",这里可以进行各种变化
-- 假设我们知道房间名字
-- 如果rooms表中,该房间不存在,则添加
if not rooms then
    rooms = { name = room_name, exits = {} }       --大家注意这里,到这里exites都是空的
end -- if

-- rooms的改变,最后都在这里体现。
if uid ~= current_room
      and current_room
      and last_direction_moved then
    -- 大家注意,exits在这里体现
    rooms .exits = uid
    -- 同时,将反方向的一起处理了
    rooms .exits ] = current_room
end -- if

-- 这是当前房间
current_room = uid

-- 显示
mapper.draw (current_room)

end -- got_prompt

-- -----------------------------------------------------------------
-- Here on room name        --这里应该得到room_name的地方,现在我用来生成唯一的uid
-- -----------------------------------------------------------------
function got_room_name (name, line, wildcards)
local name = wildcards       --这句目前没什么意义
print(wildcards )      --按正常的思路,这个值,应该就是room_name,但目前mapper.lua不支付中文,为了看出效果,先这样
uid = utils.tohex (utils.md5 (wildcards ))                --取北侠当前房间名的MD5码
uid = uid:sub (1, 10)    -- 仅取前10位数,以简化数据
print(uid)                --为了让教程看出效果,加了这句

room_name = name      --这句目前没什么意义,只是为了表示这里应该取room_name
end -- got_room_name

-- -----------------------------------------------------------------
-- try to detect when we send a movement command
-- -----------------------------------------------------------------
function OnPluginSent (sText)
last_direction_moved = valid_direction
end -- OnPluginSent

]]>
</script>
</muclient>

lzkd 发表于 2014-11-8 09:33:32

本帖最后由 lzkd 于 2014-11-13 08:20 PM 编辑

五、结束语

  写这部分内容,是比较轻松的。因为,主体部分已经完成了。小刀也可以随意跟大家扯几句,这种感觉,不错。
  先说正题吧。避免有些同学看得不耐烦,直接就关闭了。呵呵,玩笑。

  这个东西,看起来,很强大的样子,到底有什么用。
  这个问题,可能要稍微多花一点笔墨来说明。玩MUD,机器人绝对不是全部,但也占了很大一部分。这个东西,实际上,是可以做机器人用的。那么,肯定有人会问——怎么用呢?
  我们先来看一下,机器人,到底是什么。
  在小刀看来,MUD中的机器人无非是由三部分组成,判断,数据,行动。
  从MUD得到的东西(hp,score,cha,是否busy,是否在战斗状态……等等),这些东西无非就是一个判断的依据(或者说,条件)。
  讲的通俗一点,气血少于30%可以视为危险,要考虑跑人了;不busy,内力又充足,可以考虑放pfm,等等。
  而——气血少于30%——这个是判断的标准,也就是数据(听着可能有些玄,忍一下,我只是想把MUD中的机器人行为进行归类),最后归于行动。

  好,我们回到地图。我们怎么来确定自己在MUD中的位置。先look一下,把看到的东西抓进来。这些就是我们进行判断的条件,是吧。然后,我们进行比对。不管是当前描述也好,房间名也好。我们都得有一个比对的标准(这个比对的对象,就是数据)。最后,我们弄明白自己在哪里了,才可以进行行动。
  在这种情况下,全地图库,就是我们的数据(比对的标准)。
  而这次,小刀教程写的,目前小刀整明白的功能,可以理解为,一个地图采集和显示工具,当然,是手动的。大家应该都明白了哈。
 
  再说一下,如果将采集到的数据保存。可以一路走,一路将数据存到数据库里,建议使用SQLite3。至于,怎么存,这个,大家可以到论坛搜索相关内容,或者等小刀有时间开个SQLite教程。
  好了,正经事说完了。小刀突然也失去了和大家扯几句的兴趣,那就到这里结束吧。希望大家都能玩的开心。

                      小刀(lzkd)
                     于2014年11月13日

lzkd 发表于 2014-11-8 10:03:53

弄点干货再给你精华!
yhzzyahoo 发表于 2014-11-8 10:02 AM http://www.pkuxkx.net/forum/images/common/back.gif


   
我能保证教会有基础的人使用mapper.lua,而且,我能保证,全国关于mapper.lua的中文教程,这是第一篇。难道还不够干吗!!对我这么没信心~~随你了,随你了。你是版主,你说了算哈

redcoat 发表于 2014-11-8 10:09:29

来晚了。。。占个座,期待精彩内容ttk_03

lzkd 发表于 2014-11-8 10:11:41

KAO。。。。搜狗乱搞,把我刚改的东西给吞了。。我了个去~~~
还好,没改太多
页: [1] 2 3 4 5 6 7 8 9
查看完整版本: mapper.lua心得(完)