Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- full of bugs
- local MT = {}
- MT.__index = MT
- function Node(name, attributes)
- return setmetatable({name = name, children = { }, attributes = attributes or { }}, MT)
- end
- function MT:getChild(name)
- for _, node in ipairs(self.children) do
- if node.name == name then
- return node
- end
- end
- return nil
- end
- function MT:getChildren(name)
- if not name then
- local idx = 1
- return function(lol)
- local child = self.children[idx]
- if child then
- idx = idx + 1
- return child
- end
- end
- end
- local idx = 1
- return function()
- for i = idx, #self.children do
- local child = self.children[i]
- if child and child.name == name then
- idx = i + 1
- return child
- end
- end
- end
- end
- function MT:getAttribute(name, func)
- local attr = self.attributes[name]
- if attr then
- return func and func(attr) or attr
- end
- end
- local XML_PARENTNODE = 0
- local XML_CLOSENODE = 1
- local XML_SIMPLENODE = 2
- local function parseNode(s)
- local c1, name, attrString, c2 = s:match('^<%s*(/?)%s*([%w_]+)%s-(.-)(/?)%s*>$')
- assert(name, 'XML Error in:\n' .. s .. '\nNode name not found.')
- if c1 == '/' then
- return XML_CLOSENODE, name
- end
- local attributes = {}
- if attrString then
- for name, value in attrString:gmatch([[([%w_]-)%s*=%s*(%b"")%s*]]) do
- assert(name and value, 'XML Error in:\n' .. s .. '\nCould not parse attribute name and value.')
- attributes[name] = value:sub(2, -2)
- end
- for name, value in attrString:gmatch([[([%w_]-)%s*=%s*(%b'')%s*]]) do
- assert(name and value, 'XML Error in:\n' .. s .. '\nCould not parse attribute name and value.')
- attributes[name] = value:sub(2, -2)
- end
- end
- if c2 == '/' then
- return XML_SIMPLENODE, name, attributes
- else
- return XML_PARENTNODE, name, attributes
- end
- end
- local function parseString(s)
- local doc = Node()
- local stack = {doc}
- for n in s:gmatch('%b<>') do
- local current = stack[#stack]
- local ret, name, attributes = parseNode(n)
- if ret == XML_SIMPLENODE then
- table.insert(current.children, Node(name, attributes))
- elseif ret == XML_PARENTNODE then
- local node = Node(name, attributes)
- table.insert(current.children, node)
- table.insert(stack, node)
- elseif ret == XML_CLOSENODE then
- assert(current.name == name, 'XML Error in:\n' .. n .. '\nAttempt to close unknown node.')
- table.remove(stack, #stack)
- end
- end
- return doc
- end
- local function parseFile(filename)
- local handle = assert(io.open(filename, 'r'))
- local data = assert(handle:read('*all'))
- handle:close()
- data = data:gsub("<%?.-%?>", "")
- data = data:gsub("<!%-%-.-%-%->", "")
- return parseString(data)
- end
- if not isInArray then
- function isInArray(t, v)
- for i, x in pairs(t) do
- if x == v then
- return true
- end
- end
- return false
- end
- end
- -- Configure it here
- local path = "./data/spells/"
- local data = parseFile(path .. "spells.xml")
- local output = "output.xml"
- local TFS = "1.x" -- "1.x" or "0.3.x"
- local convert = {"conjureRune", "conjureItem"}
- -- You may remove the lines below if you already have scripts\conjure folder. May not work in linux create it manually and remove those lines"
- local mkdir = os.execute("mkdir" .. path:gsub("/", "\\") .. "\\scripts\\conjure\\")
- if mkdir == 1 then
- print("Error in mkdir")
- return false
- end
- -- Now stop changing
- local script1x = [[function onCastSpell(creature, variant)
- <!1
- if creature:getItemCount(%reagentId%) == 0 then
- creature:sendCancelMessage(RETURNVALUE_YOUNEEDAMAGICITEMTOCASTSPELL)
- creature:getPosition():sendMagicEffect(CONST_ME_POFF)
- return false
- end
- creature:removeItem(%reagentId%, 1)
- !>
- creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
- creature:addItem(%conjureId%, %conjureCount%)
- return true
- end]]
- local script03x = [[function onCastSpell(cid, var)
- <!1
- if getPlayerItemCount(cid, %reagentId%) == 0 then
- doPlayerSendDefaultCancel(cid, RETURNVALUE_YOUNEEDAMAGICITEMTOCASTSPELL)
- doSendMagicEffect(getThingPosition(cid), CONST_ME_POFF)
- return false
- end
- doPlayerRemoveItem(cid, %reagentId%, 1)
- !>
- doSendMagicEffect(getThingPosition(cid), CONST_ME_MAGIC_RED)
- doPlayerAddItem(cid, %conjureId%, %conjureCount%)
- end]]
- local script = TFS:find("^1%.") and script1x or script03x
- local ret = {}
- local func = TFS:find("^1%.") and "function" or "value"
- for node in data:getChild("spells"):getChildren("conjure") do
- local conjureId = tonumber(node:getAttribute("conjureId"))
- local conjureCount = tonumber(node:getAttribute("conjureCount") or nil) or 1
- local reagentId = tonumber(node:getAttribute("reagentId") or nil)
- if not conjureId then
- print("Warning! Spell " .. node:getAttribute("name") .. " has no conjureId.")
- elseif isInArray(convert, node:getAttribute(func)) then
- table.insert(ret, {node, conjureId, conjureCount, reagentId})
- end
- end
- local outfile = io.open(path .. output, "w")
- local out = ""
- for i = 1, #ret do
- local node = ret[i][1]
- local conjureId = ret[i][2]
- local conjureCount = ret[i][3]
- local reagentId = ret[i][4]
- out = out .. "\n\t<instant "
- for attr, value in pairs(node.attributes) do
- if not isInArray({"conjureId", "conjureCount", "reagentId", func}, attr) then
- if attr == "event" then
- value = "script"
- end
- out = out .. attr .. "=\"" .. value .. "\" "
- end
- end
- local children = node:getChildren("vocation")
- if TFS:find("^1%.") then
- out = out .. "script=\"conjure/" .. node:getAttribute("words") .. ".lua\""
- else
- out = out .. "value=\"conjure/" .. node:getAttribute("words") .. ".lua\""
- end
- local scriptfile = io.open(path .. "scripts/conjure/" .. node:getAttribute("words") .. ".lua", "w")
- if not scriptfile then
- print("Warning! Failed to create " .. path .. "scripts/conjure/" .. node:getAttribute("words") .. ".lua")
- else
- local tmp = script:gsub("%%conjureId%%", tostring(conjureId))
- tmp = tmp:gsub("%%conjureCount%%", tostring(conjureCount))
- tmp = tmp:gsub("%%reagentId%%", tostring(reagentId) or "")
- if not reagentId then
- tmp = tmp:gsub("<!1.-!>", "")
- else
- tmp = tmp:gsub("<!1", "")
- tmp = tmp:gsub("!>", "")
- end
- scriptfile:write(tmp)
- scriptfile:close()
- end
- if node:getChild("vocation") then
- out = out .. ">"
- for child in children do
- out = out .. "\n\t\t<vocation name=\"" .. child:getAttribute("name") .. "\" />"
- end
- out = out .. "\n\t</instant>"
- else
- out = out .. " />"
- end
- end
- outfile:write(out)
- outfile:close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement