Advertisement
Guest User

Untitled

a guest
May 10th, 2016
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.40 KB | None | 0 0
  1. -- full of bugs
  2.  
  3. local MT = {}
  4. MT.__index = MT
  5.  
  6. function Node(name, attributes)
  7. return setmetatable({name = name, children = { }, attributes = attributes or { }}, MT)
  8. end
  9.  
  10. function MT:getChild(name)
  11. for _, node in ipairs(self.children) do
  12. if node.name == name then
  13. return node
  14. end
  15. end
  16. return nil
  17. end
  18.  
  19. function MT:getChildren(name)
  20. if not name then
  21. local idx = 1
  22. return function(lol)
  23. local child = self.children[idx]
  24. if child then
  25. idx = idx + 1
  26. return child
  27. end
  28. end
  29. end
  30.  
  31. local idx = 1
  32. return function()
  33. for i = idx, #self.children do
  34. local child = self.children[i]
  35. if child and child.name == name then
  36. idx = i + 1
  37. return child
  38. end
  39. end
  40. end
  41. end
  42.  
  43. function MT:getAttribute(name, func)
  44. local attr = self.attributes[name]
  45. if attr then
  46. return func and func(attr) or attr
  47. end
  48. end
  49.  
  50. local XML_PARENTNODE = 0
  51. local XML_CLOSENODE = 1
  52. local XML_SIMPLENODE = 2
  53.  
  54. local function parseNode(s)
  55. local c1, name, attrString, c2 = s:match('^<%s*(/?)%s*([%w_]+)%s-(.-)(/?)%s*>$')
  56. assert(name, 'XML Error in:\n' .. s .. '\nNode name not found.')
  57.  
  58. if c1 == '/' then
  59. return XML_CLOSENODE, name
  60. end
  61.  
  62. local attributes = {}
  63. if attrString then
  64. for name, value in attrString:gmatch([[([%w_]-)%s*=%s*(%b"")%s*]]) do
  65. assert(name and value, 'XML Error in:\n' .. s .. '\nCould not parse attribute name and value.')
  66. attributes[name] = value:sub(2, -2)
  67. end
  68.  
  69. for name, value in attrString:gmatch([[([%w_]-)%s*=%s*(%b'')%s*]]) do
  70. assert(name and value, 'XML Error in:\n' .. s .. '\nCould not parse attribute name and value.')
  71. attributes[name] = value:sub(2, -2)
  72. end
  73. end
  74.  
  75. if c2 == '/' then
  76. return XML_SIMPLENODE, name, attributes
  77. else
  78. return XML_PARENTNODE, name, attributes
  79. end
  80. end
  81.  
  82.  
  83. local function parseString(s)
  84. local doc = Node()
  85. local stack = {doc}
  86. for n in s:gmatch('%b<>') do
  87. local current = stack[#stack]
  88. local ret, name, attributes = parseNode(n)
  89. if ret == XML_SIMPLENODE then
  90. table.insert(current.children, Node(name, attributes))
  91. elseif ret == XML_PARENTNODE then
  92. local node = Node(name, attributes)
  93. table.insert(current.children, node)
  94. table.insert(stack, node)
  95. elseif ret == XML_CLOSENODE then
  96. assert(current.name == name, 'XML Error in:\n' .. n .. '\nAttempt to close unknown node.')
  97. table.remove(stack, #stack)
  98. end
  99. end
  100. return doc
  101. end
  102.  
  103. local function parseFile(filename)
  104. local handle = assert(io.open(filename, 'r'))
  105. local data = assert(handle:read('*all'))
  106. handle:close()
  107. data = data:gsub("<%?.-%?>", "")
  108. data = data:gsub("<!%-%-.-%-%->", "")
  109. return parseString(data)
  110. end
  111.  
  112. if not isInArray then
  113. function isInArray(t, v)
  114. for i, x in pairs(t) do
  115. if x == v then
  116. return true
  117. end
  118. end
  119. return false
  120. end
  121. end
  122.  
  123. -- Configure it here
  124. local path = "./data/spells/"
  125. local data = parseFile(path .. "spells.xml")
  126. local output = "output.xml"
  127. local TFS = "1.x" -- "1.x" or "0.3.x"
  128. local convert = {"conjureRune", "conjureItem"}
  129.  
  130. -- 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"
  131. local mkdir = os.execute("mkdir" .. path:gsub("/", "\\") .. "\\scripts\\conjure\\")
  132. if mkdir == 1 then
  133. print("Error in mkdir")
  134. return false
  135. end
  136.  
  137. -- Now stop changing
  138. local script1x = [[function onCastSpell(creature, variant)
  139. <!1
  140. if creature:getItemCount(%reagentId%) == 0 then
  141. creature:sendCancelMessage(RETURNVALUE_YOUNEEDAMAGICITEMTOCASTSPELL)
  142. creature:getPosition():sendMagicEffect(CONST_ME_POFF)
  143. return false
  144. end
  145.  
  146. creature:removeItem(%reagentId%, 1)
  147. !>
  148. creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
  149. creature:addItem(%conjureId%, %conjureCount%)
  150. return true
  151. end]]
  152.  
  153. local script03x = [[function onCastSpell(cid, var)
  154. <!1
  155. if getPlayerItemCount(cid, %reagentId%) == 0 then
  156. doPlayerSendDefaultCancel(cid, RETURNVALUE_YOUNEEDAMAGICITEMTOCASTSPELL)
  157. doSendMagicEffect(getThingPosition(cid), CONST_ME_POFF)
  158. return false
  159. end
  160.  
  161. doPlayerRemoveItem(cid, %reagentId%, 1)
  162. !>
  163. doSendMagicEffect(getThingPosition(cid), CONST_ME_MAGIC_RED)
  164. doPlayerAddItem(cid, %conjureId%, %conjureCount%)
  165. end]]
  166.  
  167. local script = TFS:find("^1%.") and script1x or script03x
  168. local ret = {}
  169. local func = TFS:find("^1%.") and "function" or "value"
  170. for node in data:getChild("spells"):getChildren("conjure") do
  171. local conjureId = tonumber(node:getAttribute("conjureId"))
  172. local conjureCount = tonumber(node:getAttribute("conjureCount") or nil) or 1
  173. local reagentId = tonumber(node:getAttribute("reagentId") or nil)
  174. if not conjureId then
  175. print("Warning! Spell " .. node:getAttribute("name") .. " has no conjureId.")
  176. elseif isInArray(convert, node:getAttribute(func)) then
  177. table.insert(ret, {node, conjureId, conjureCount, reagentId})
  178. end
  179. end
  180.  
  181. local outfile = io.open(path .. output, "w")
  182. local out = ""
  183. for i = 1, #ret do
  184. local node = ret[i][1]
  185. local conjureId = ret[i][2]
  186. local conjureCount = ret[i][3]
  187. local reagentId = ret[i][4]
  188. out = out .. "\n\t<instant "
  189. for attr, value in pairs(node.attributes) do
  190. if not isInArray({"conjureId", "conjureCount", "reagentId", func}, attr) then
  191. if attr == "event" then
  192. value = "script"
  193. end
  194. out = out .. attr .. "=\"" .. value .. "\" "
  195. end
  196. end
  197. local children = node:getChildren("vocation")
  198. if TFS:find("^1%.") then
  199. out = out .. "script=\"conjure/" .. node:getAttribute("words") .. ".lua\""
  200. else
  201. out = out .. "value=\"conjure/" .. node:getAttribute("words") .. ".lua\""
  202. end
  203.  
  204. local scriptfile = io.open(path .. "scripts/conjure/" .. node:getAttribute("words") .. ".lua", "w")
  205. if not scriptfile then
  206. print("Warning! Failed to create " .. path .. "scripts/conjure/" .. node:getAttribute("words") .. ".lua")
  207. else
  208. local tmp = script:gsub("%%conjureId%%", tostring(conjureId))
  209. tmp = tmp:gsub("%%conjureCount%%", tostring(conjureCount))
  210. tmp = tmp:gsub("%%reagentId%%", tostring(reagentId) or "")
  211. if not reagentId then
  212. tmp = tmp:gsub("<!1.-!>", "")
  213. else
  214. tmp = tmp:gsub("<!1", "")
  215. tmp = tmp:gsub("!>", "")
  216. end
  217. scriptfile:write(tmp)
  218. scriptfile:close()
  219. end
  220. if node:getChild("vocation") then
  221. out = out .. ">"
  222. for child in children do
  223. out = out .. "\n\t\t<vocation name=\"" .. child:getAttribute("name") .. "\" />"
  224. end
  225. out = out .. "\n\t</instant>"
  226. else
  227. out = out .. " />"
  228. end
  229.  
  230. end
  231. outfile:write(out)
  232. outfile:close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement