duno 发表于 2009-5-5 03:08:34

[模块] 地图定位

依赖:
  前面发的地图数据rooms.xml及room.lua库
功能:
  定位当前所在位置
使用方法:
  引用本库
  调用function CurrentRoom.GetCurrentRoom (callback),
  参数callback为回调函数,要求接受参数为room数组,数组中每一room的结构为{id,name,desp,entry,adjacent,path}
思路:
  获取当前房间信息,尝试定位,
    若唯一定位,返回结果(回调callback,将定位结果传入)
    若不能唯一定位,检查四周邻接房间信息,作为adj_info,再次尝试定位
      返回结果(回调callback,将定位结果传入,这里结果可能为多个)
说明:
  每次调用结束后,会EnableGroup(false),不会主动和其他模块Trigger发生冲突
  
  这里是取数据,稍加改为写数据,就是画地图工具了
  如果再加上自动漫游或遍历,就是画地图机器人了

duno 发表于 2009-5-5 03:11:59

使用举例
script 文件内容

require "module.current_room";
function callback (roomList)
    Note ("***Result***")
    for k, v in pairs (roomList) do
      Note ("id=", v.id, " name=",v.name, "entry=", table.concat (v.entry, ","))
    end
end
CurrentRoom.GetCurrentRoom (callback)

Log输出

***** load rooms *****
l
say current room try pos 1
                                             
                                    
               大官道----大官道----函谷关   
                                    
                                             
大官道 -
    这是一条宽阔笔直,尘土飞扬的大官道,足可容得下十马并驰。往东
通向函谷关可以达扬州城,往西不远便是东都洛阳古城的东城边了。
    「早春」: 夜幕低垂,天上飘着如絮的云朵,星星眨着眼。
    这里明显的出口是 west 和 east。
> 你说道:「current room try pos 1」
l west
say current room adj west
l east
say current room adj east
say current room try pos 2
>                                                
                                    
               大官道----大官道----大官道   
                                    
                                             
大官道 -
    这是一条宽阔笔直,尘土飞扬的大官道,足可容得下十马并驰。往东
通向函谷关可以达扬州城,往西不远便是东都洛阳古城的东城边了。
    「早春」: 夜幕低垂,天上飘着如絮的云朵,星星眨着眼。
    这里明显的出口是 west 和 east。
    剑客(Jian ke)
> 你说道:「current room adj west」
>                                                
                                    
               大官道----函谷关            
                                  \
                                     官道      
函谷关 -
      这里就是古函古关。它东起崤山,西接潼津,关设谷中。当年强秦一
隅之地,制关东六国而不敢稍动,最后横扫天下,就是因为它据此,进可
攻,退可守,乃天下形胜之处。老子西出化胡,也是在此留下两册道德经,
千载以下,后人仍研读不尽。
    「早春」: 夜幕低垂,天上飘着如絮的云朵,星星眨着眼。
    这里明显的出口是 west 和 southeast。
> 你说道:「current room adj east」
> 你说道:「current room try pos 2」
***Result***
id=26005 name=大官道entry=west,east


[ 本帖最后由 duno 于 2009-5-5 10:44 PM 编辑 ]

duno 发表于 2009-5-5 03:16:11

鉴于很小,直接发出来,供参考

require "module.room";
CurrentRoom = {}
CurrentRoom.callback = nil    --回调函数,要求接受 room数组 为参数
CurrentRoom.hasInit = false
function CurrentRoom.GetCurrentRoom (callback)
    if callback and type (callback) ~= "function" then
      Note ("CurrentRoom.GetCurrentRoom ()param callback is not a func")
      return
    end
    if not hasInit then
      hasInit = true
      CurrentRoom.Init ()
    else
      EnableGroup ("current_room", true)
    end
    if not t_rooms or t_rooms.maxid == 0 then
      load_rooms ()
    end
    CurrentRoom.callback = callback      --初始化
    CurrentRoom.room = {}
    CurrentRoom.room.name = nil
    CurrentRoom.room.desp = nil
    CurrentRoom.room.entry = nil
    CurrentRoom.room.adj_info = nil
    CurrentRoom.temp = nil            --临时room,辅助获取邻接房间信息
    Send ("l")
    Send ("say current room try pos 1")
end
--增加Trigger
function CurrentRoom.AddTrigger (name, match, action, sent_to, group)
    DeleteTrigger(name)
    AddTriggerEx (name, match, action, 1 + 32 + 16384, -1, 0, "", "", sent_to, 50)
    if group and group ~= "" then
      SetTriggerOption (name, "group", group)
    end
end
function CurrentRoom.Init ()
    CurrentRoom.AddTrigger ("current_entry_line", "^    这里.{4}的出口是 (.*)[。]*$", "CurrentRoom.GetRoomInfo (\"%1\")", 12, "current_room")
    CurrentRoom.AddTrigger ("current_try_pos", "^[> ]*你说道:「current room try pos (.*)」$", "CurrentRoom.TryPos ('%1')", 12, "current_room")
    CurrentRoom.AddTrigger ("current_adj", "^[> ]*你说道:「current room adj (.*)」$", "CurrentRoom.Adj ('%1')", 12, "current_room")
end
function CurrentRoom.GetRoomInfo (entryStr)
    local name, desp, entry = getRoomInfo (entryStr)
    CurrentRoom.temp = {name=name, desp=desp, entry=entry}
end
function CurrentRoom.TryPos (flag)
    if flag == "1" then
      CurrentRoom.room.name = CurrentRoom.temp.name
      CurrentRoom.room.desp = CurrentRoom.temp.desp
      CurrentRoom.room.entry = CurrentRoom.temp.entry
      CurrentRoom.temp = nil
    end
    local temp = CurrentRoom.room
    local t = getRooms (temp.name, temp.desp, temp.entry, nil, temp.adj_info)
    if #t == 1 then
      CurrentRoom.close ()
      CurrentRoom.callback (t)
    elseif #t == 0 then    --出现问题了
      CurrentRoom.close ()
      Note ("can not pos current room")
      CurrentRoom.callback (nil)
    else            --数量超过1
      if flag == "1" then    --尚未check邻接房间
            for _, v in pairs (temp.entry) do
                Send ("l " .. v)
                Send ("say current room adj " .. v)
            end
            Send ("say current room try pos 2")
      elseif flag == "2" then    --已经check邻接房间
            CurrentRoom.close ()
            CurrentRoom.callback (t)
      end
    end
end
function CurrentRoom.Adj (dir)
    if not CurrentRoom.room.adj_info then
      CurrentRoom.room.adj_info = {}
    end
    CurrentRoom.room.adj_info = CurrentRoom.temp
    CurrentRoom.temp = nil
end

function CurrentRoom.close ()
    EnableGroup ("current_room", false)
end

ddid 发表于 2009-5-5 03:31:10

不行了,今天困了,有时间好好研究。yct13

duno 发表于 2009-5-5 22:56:15

Yeah,精华喽,俺的头一个精华ttk_18

ddid 发表于 2009-5-5 23:18:00

gongxi

greney 发表于 2009-5-11 08:39:54

在zmud721 map中的定位 可以根据 房间名+描述+出口 来定位
更高级的可以根据相邻房间来定位

ddid 发表于 2009-5-17 15:42:25

不太明白,如何把房间描述的多行数据存进table里的呢?

duno 发表于 2009-5-17 15:49:02

从出口行触发,调用getRoomInfo(s),参数为出口串

--获取房间信息 名称、描述、出口
function getRoomInfo(s)
      local line, total_lines, line_name;
      local name, desp, entry;
      total_lines = GetLinesInBufferCount ()
      line_name = -1;
      name = "";
      for line = total_lines, total_lines-40, -1 do      --从当前触发行向前遍历,寻找name行
                local str = GetLineInfo (line, 1)
                if string.match(str, "^.* [-] $") ~= nil then      
                        line_name = line;
                        name = string.match(str, "^(.*) [-] $")
                        break;
                end;
      end
      local desp = {};                              --从name行向回到触发行遍历,筛选desp
--      Note ("total_lines : ", total_lines)
      for line = line_name + 1, total_lines - 1 do
                local str = GetLineInfo (line, 1)
                if str == nil then
                elseif line == total_lines - 1 and string.match (str, "    「.*」: ") then--天气
                else
                        desp[#desp + 1] = str;
                end;
      end;
      local entryList = FormatEntris (s)                --根据当前触发行串,计算出口列表
      entry = table.join(entryList);                        --合并之前筛选的desp
      for i = 1, #desp do
                if desp == nil then      
                        AnsiNote(ANSI(32, 1, 1), "************* Nil -> desp value ****************")
                        Send("look")
                        break
                end
      end
      local str_desp = ""
      for i = 1, #desp do
                str_desp = str_desp .. desp
      end
      return name, str_desp, entryList
end;


[ 本帖最后由 duno 于 2009-5-17 03:51 PM 编辑 ]

ddid 发表于 2009-5-17 15:50:55

噢,table.join(entryList); 需要研究一下

谢谢啦!
页: [1] 2 3
查看完整版本: [模块] 地图定位