A module to support few zmud command

Posted by Yanwuhuan on Tue 11 Nov 2008 03:05 AM — 2 posts, 11,721 views.

#0
In my game, there are many zmud resources. I'm tired translate to mush. So this module born.
Now it can support #wait command, and #n command.

For example, if you have a zmud alias,like
#Alias {dosomthing} {do1;do2;do3;#wa 1000;#3 do4}
You can do like below:
require "zmud"
local dosomething "do1;do2;do3;#wa 1000;#3 do4"
zmud.run(dosomething)



----- zmud.lua ------
--!/usr/bin/env lua
-- --*-- encoding: cp936 --*--

-- ----------------------------------------------------------
-- "zmud" - lets you do something like in zmud, to keep your zmud experience
-- ----------------------------------------------------------

--[[
Now only support zmud command sequence,
support:
1. #wa NNN or #wait NNN
   NNN: micro-second, like zmud
2. #n action
   n  : integer, any you want if lua support
3. Automatically add interval for too many command
   ie. in my game, 20 commands/one second is allowed, so for me
    step_count_max_limit is 20
    minimal_interval  is 50 (micro-second)
   You can modify to fit your game
4. I use Execute to parse the command, it support mush-alias.

Limitation:
  Now I can not find a way to support nesting wait. so ...
  If there is also wait/zmud.run inside alias, can not support correctly.
  So now the only way is just make zmud command sequence, concat them and zmud.run it


Sample:
require "zmud"

local mypath="dive;#wa 2000;#4 e;s;#3 w;enter hole;#wa 2500;d"
zmud.run(mypath)



--]]

require "wait"
require "string"

module (..., package.seeall)


local step_count_max_limit = 20
local minimal_interval = 50

-- judge whether wait time, otherwise return nil
-- #wa xx ,#wait xx
local function judgewait(str)
  local _,_, num=string.find(str,"^%s*#%s*wa[it]*%s+(%d+)")
  return (tonumber(num))
end

-- judge whether multi-action, otherwise return nil
-- #N action
local function judgemulti(str)
  local _,_,num,action = string.find(str,"^%s*#%s*(%d+)%s*(.-)%s*$")
  return tonumber(num),action
end


-- run a sequence of command, format like zmud
function run(steps)
wait.make(function()
  local tstep={}
  string.gsub(steps, "([^%;]+)%;?", function(n)
      table.insert(tstep, n)
    end)   -- seems utils.split is better
  local step_count=0
  local step_count_all=0
  for _,v in pairs(tstep) do
    local wa=judgewait(v)
    if (wa == nil) then
      -- not #wait
      local num,act = judgemulti(v)
      if (act == nil) then
        -- not multi action
        step_count = step_count+1
        -- auto interval
        if (step_count>=step_count_max_limit) then
          local realwait = step_count*minimal_interval / 1000
          wait.time(realwait)
          step_count = 0
        end
        step_count_all = step_count_all+1
        Execute(v)
      else
        -- is multi action
        for i=1,num do
          step_count = step_count+1
          -- auto interval
          if (step_count>=step_count_max_limit) then
            local realwait = step_count*minimal_interval / 1000
            wait.time(realwait)
            step_count = 0
          end
          step_count_all = step_count_all+1
          Execute(act)
        end -- end for
      end -- end judge wait
    else
      -- convert from zmud time to mush time(ms -> sec)
      local realwait = wa/1000.0
      if (realwait < 0.1) then
        realwait = 0.1
      end
      -- reduce auto interval
      if (realwait*1000 >= step_count*minimal_interval) then
        step_count = 0
      else
        local reduce_to = math.ceil((step_count*minimal_interval - realwait*1000)/minimal_interval)
        step_count = reduce_to
      end
      wait.time(realwait)
    end
  end -- end for
  --Note("--total steps: " .. step_count_all)
end)
end


Amended by Nick Gammon to put [code] tags around the code.
Amended on Tue 11 Nov 2008 07:07 PM by Nick Gammon
Australia Forum Administrator #1
Thanks for posting that, I'm sure people will find it helpful.

A few coding tips:

  • You don't need to require the string library, that is built in.
  • Instead of:

    
    local _,_, num=string.find(str,"^%s*#%s*wa[it]*%s+(%d+)")
    


    You can do:

    
    local num=string.match(str,"^%s*#%s*wa[it]*%s+(%d+)")