Advertisement
Tmrectop

[FR] XML Editor

Nov 27th, 2013
487
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.84 KB | None | 0 0
  1. local xml=nil
  2. local author=nil
  3. local groundTypes={[0]='Bois','Glace','Trampoline','Lave','Chocolat','Terre','Herbe','Sable','Nuage','Eau','Pierre','Neige','Couleur','Cercle'}
  4. local options={Collision=false, Soulmate=false, Portals=false, Night=false, Wind=0, Gravity=10, Background=nil, Width=800, Height=400}
  5. local grounds={}
  6. local keys={}
  7. local players={}
  8.  
  9. function main()
  10. --tfm.exec.newGame()
  11. tfm.exec.disableAutoNewGame(true)
  12. tfm.exec.disableAutoTimeLeft(true)
  13. for name in pairs(tfm.get.room.playerList) do eventNewPlayer(name) end
  14. ui.addTextArea(989,"<p align='center'>Ce script est développé par <VP>Transforcips <N>et <VP>Kmlcan.",nil,200,-25,400,30,1,0,0.8)
  15. end
  16.  
  17. function readOptions()
  18. if xml then
  19. options={Collision=false, Soulmate=false, Portals=false, Night=false, Wind=0, Gravity=10, Background=nil, Width=800, Height=400}
  20. grounds={}
  21. for attr, val in xml:match('<P .->'):gmatch('(%S+)=(%S+)') do
  22. if attr == 'C' then options.Collision = true
  23. elseif attr == 'A' then options.Soulmate = true
  24. elseif attr == 'P' then options.Portals = true
  25. elseif attr == 'N' then options.Night = true
  26. elseif attr == 'G' then
  27. options.Wind, options.Gravity = val:match('"([%-%d]+),([%-%d]+)"')
  28. elseif attr == 'F' then
  29. options.Background = val:match('"([%-%d]+)"')
  30. elseif attr == 'L' then
  31. options.Width = val:match('"([%-%d]+)"')
  32. elseif attr == 'H' then
  33. options.Height = val:match('"([%-%d]+)"')
  34. end
  35. end
  36. local array = {}
  37. for attributes in xml:match('<S>(.-)</S>'):gmatch('<S (.-)/>') do
  38. array = {}
  39. for attr, val in attributes:gmatch('(%S+)="(%S*)"') do
  40. array[attr] = val or ""
  41. end
  42. if array.P then
  43. array.P = string.split(array.P or "")
  44. end
  45. table.insert(grounds, array)
  46. end
  47. end
  48. end
  49.  
  50. function table.swap(t, key, key2)
  51. local tmp = t[key]
  52. t[key] = t[key2]
  53. t[key2] = tmp
  54. end
  55.  
  56. function string.split(str, delimiter)
  57. local delimiter=delimiter or ','
  58. local array={}
  59. for part in str:gmatch('[^'..delimiter..']+') do
  60. table.insert(array, part)
  61. end
  62. return array
  63. end
  64.  
  65. function getOptionsText()
  66. return string.format("<p align='center'>%s<a href='event:optionCollision'>Collision</a> <G>|%s <a href='event:optionNight'>Nuit</a> <G>|%s <a href='event:optionPortals'>Portails</a> <G>|%s <a href='event:optionSoulmate'>Âme-Soeur</a> <G>|<J> <a href='event:changeGravity'>Gravité: <font color='#c2c2da'>%d</font></a> <G>|<J> <a href='event:changeWind'>Vent: <font color='#c2c2da'>%d</font></a> <G>|<J> <a href='event:changeBackground'>Arrière Plan: <font color='#c2c2da'>%s</font></a> <G>|<J> <a href='event:changeL'>Longueur: <font color='#c2c2da'>%d</font></a> <G>|<J> <a href='event:changeH'>Hauteur: <N>%d",
  67. options.Collision and '<CH>' or '<R>', options.Night and '<CH>' or '<R>', options.Portals and '<CH>' or '<R>',
  68. options.Soulmate and '<CH>' or '<R>', options.Gravity, options.Wind, options.Background or 'Yok',
  69. options.Width, options.Height)
  70. end
  71.  
  72. function showGUI(name)
  73. ui.addTextArea(333,getOptionsText(),name,40,20,720,nil,1,0,0.8)
  74. end
  75.  
  76. function updateGUI()
  77. ui.updateTextArea(333,getOptionsText())
  78. end
  79.  
  80. function updateXML()
  81. local pTag = xml:match('<P .->')
  82. local attributes = {}
  83. for attr, val in pTag:gmatch('(%S+)=(%S+)') do
  84. attributes[attr] = val
  85. end
  86. attributes.C = options.Collision and '""' or nil
  87. attributes.A = options.Soulmate and '""' or nil
  88. attributes.P = options.Portals and '""' or nil
  89. attributes.N = options.Night and '""' or nil
  90. attributes.L = options.Width and '"' .. options.Width .. '"' or nil
  91. attributes.H = options.Height and '"' .. options.Height .. '"' or nil
  92. attributes.F = options.Background and '"' .. options.Background .. '"' or nil
  93. attributes.G = '"' .. options.Wind .. "," .. options.Gravity .. '"'
  94. local newPTag = '<P '
  95. for attr, val in pairs(attributes) do
  96. newPTag = newPTag .. attr .. '=' .. val .. ' '
  97. end
  98. newPTag = newPTag .. '/>'
  99. xml = xml:gsub('<P .->', newPTag, 1)
  100. local groundStr = ''
  101. local gStr = ''
  102. for _, ground in pairs(grounds) do
  103. gStr = ''
  104. for key, val in pairs(ground) do
  105. if key ~= 'P' then
  106. gStr = gStr .. key .. '="' .. tostring(val) .. '" '
  107. end
  108. end
  109. if ground.P then
  110. gStr = gStr .. 'P="' .. table.concat(ground.P, ',') .. '" '
  111. end
  112. groundStr = groundStr .. string.format('<S %s/>', gStr)
  113. end
  114. xml = xml:gsub('<S>.-</S>', '<S>'..groundStr..'</S>', 1)
  115. print("XML has been updated.")
  116. end
  117.  
  118. function eventNewGame()
  119. if tfm.get.room.xmlMapInfo and tfm.get.room.xmlMapInfo.xml
  120. and tfm.get.room.currentMap == '@' .. tfm.get.room.xmlMapInfo.mapCode then
  121. xml = tfm.get.room.xmlMapInfo.xml
  122. print("La carte a bien été chargée.")
  123. readOptions()
  124. showGUI(name)
  125. ui.addTextArea(666,"<p align='center'><a href='event:groundSettings'>Options des sols</a> <G>| <N><a href='event:reloadMap'>Jouer la carte</a>",nil,300,380,200,nil,1,0,0.8)
  126. tfm.exec.setGameTime(5)
  127. if tfm.get.room.xmlMapInfo and tfm.get.room.xmlMapInfo.author ~= "#Module" and tfm.get.room.xmlMapInfo.xml then
  128. author = tfm.get.room.xmlMapInfo.author.." <BL>- @"..tfm.get.room.xmlMapInfo.mapCode
  129. tfm.exec.setUIMapName(author)
  130. else tfm.exec.setUIMapName(author.." - <VP>Modifiée") end
  131. else
  132. tfm.exec.setUIMapName(tfm.get.room.currentMap)
  133. for id=0,985 do ui.removeTextArea(id) end
  134. end
  135. end
  136.  
  137. function eventNewPlayer(name)
  138. keys[name] = {}
  139. players[name]={edit=nil}
  140. tfm.exec.bindKeyboard(name, 80, true, true) tfm.exec.bindKeyboard(name, 80, false, true)
  141. tfm.exec.bindKeyboard(name, 79, true, true) tfm.exec.bindKeyboard(name, 79, false, true)
  142. system.bindMouse(name, true)
  143. end
  144.  
  145. function eventPlayerLeft(name)
  146. keys[name] = nil
  147. end
  148.  
  149. function eventKeyboard(name, key, down)
  150. if keys[name] then
  151. keys[name][key] = down
  152. end
  153. end
  154.  
  155. function eventMouse(name, x, y)
  156. if keys[name] then
  157. if keys[name][80] then
  158. tfm.exec.movePlayer(name, x, y)
  159. elseif keys[name][79] then
  160. local gID = 0
  161. for ID, ground in pairs(grounds) do
  162. if math.abs(ground.X-x) < 11 and math.abs(ground.Y-y) < 11 then
  163. gID = ID
  164. end
  165. end
  166. if gID ~= 0 then
  167. eventTextAreaCallback(ID, name, 'groundEdit'..gID)
  168. end
  169. end
  170. end
  171. end
  172.  
  173. function eventChatCommand(name, cmd)
  174. if cmd:sub(1,4) == "map " then
  175. tfm.exec.newGame(cmd:sub(5))
  176. end
  177. end
  178.  
  179. function eventPopupAnswer(ID, name, answer)
  180. if ID == 40 then
  181. options.Wind = tonumber(answer) or options.Wind
  182. elseif ID == 41 then
  183. options.Gravity = tonumber(answer) or options.Gravity
  184. elseif ID == 42 then
  185. if tonumber(answer) then
  186. local answer = tonumber(answer)
  187. if answer>=0 and answer<=8 then
  188. options.Background = answer
  189. end
  190. elseif answer:lower() == 'x' then
  191. options.Background = nil
  192. end
  193. elseif ID == 43 then
  194. if tonumber(answer) then
  195. local answer = tonumber(answer)
  196. if answer>=800 and answer<=1600 then
  197. options.Width = answer
  198. end
  199. end
  200. elseif ID == 44 then
  201. if tonumber(answer) then
  202. local answer = tonumber(answer)
  203. if answer>=400 and answer<=800 then
  204. options.Height = answer
  205. end
  206. end
  207. elseif ID == 53 then
  208. if players[name] and players[name].edit and players[name].edit.ID and answer:len()>0 then
  209. local ground = grounds[players[name].edit.ID]
  210. if ground then
  211. if players[name].edit.type == 'type' and tonumber(answer)>=0 and tonumber(answer)<=13 then
  212. ground.T = tonumber(answer)
  213. elseif players[name].edit.type == 'x' then
  214. ground.X = tonumber(answer)
  215. elseif players[name].edit.type == 'y' then
  216. ground.Y = tonumber(answer)
  217. elseif players[name].edit.type == 'l' and tonumber(answer)>=10 and tonumber(answer)<=2000 then
  218. ground.L = tonumber(answer)
  219. elseif players[name].edit.type == 'h' and tonumber(answer)>=10 and tonumber(answer)<=2000 then
  220. ground.H = tonumber(answer)
  221. elseif players[name].edit.type == 'fri' then
  222. ground.P[3] = answer
  223. elseif players[name].edit.type == 'res' then
  224. ground.P[4] = answer
  225. elseif players[name].edit.type == 'angle' then
  226. ground.P[5] = answer
  227. elseif players[name].edit.type == 'color' and answer:len()>=0 and answer:len()<=6 then
  228. ground.o = tonumber(answer) or tonumber('0x'..answer) or 0
  229. end
  230. eventTextAreaCallback(ID, name, 'groundEdit'..players[name].edit.ID)
  231. end
  232. end
  233. end
  234. updateGUI()
  235. end
  236.  
  237. function eventTextAreaCallback(ID, name, callback)
  238. if callback == 'close' then
  239. ui.removeTextArea(ID, name)
  240. ui.removeTextArea(121, name)
  241. elseif callback:sub(1,6) == 'option' and callback:len() > 6 then
  242. options[callback:sub(7)] = not options[callback:sub(7)]
  243. updateGUI()
  244. elseif callback == 'changeWind' then
  245. ui.addPopup(40,2,"<p align='center'>Entrez une valeur pour déterminer le vent</p>",name,300,55,200)
  246. elseif callback == 'changeGravity' then
  247. ui.addPopup(40,2,"<p align='center'>Entrez une valeur pour déterminer la gravité</p>",name,300,55,200)
  248. elseif callback == 'changeBackground' then
  249. ui.addPopup(42,2,"<p align='center'>Entrez une valeur pour déterminer l'arrière plan</p>",name,300,55,200)
  250. elseif callback == 'changeL' then
  251. ui.addPopup(43,2,"<p align='center'>Entrez une valeur pour déterminer la longueur</p>",name,300,55,200)
  252. elseif callback == 'changeH' then
  253. ui.addPopup(44,2,"<p align='center'>Entrez une valeur pour déterminer la hauteur</p>",name,300,55,200)
  254. elseif callback:sub(1,14) == 'groundSettings' then
  255. local startID = callback:sub(15)
  256. startID = startID and tonumber(startID) or 1
  257. local groundsStr = ''
  258. for i,ground in ipairs(grounds) do
  259. if i >= startID then
  260. if i >= (startID+8) then break end
  261. groundsStr = groundsStr .. '<N>' .. i .. '<G> - <V><a href="event:groundEdit' .. i .. '">' .. (groundTypes[tonumber(ground.T)] or 'Unknown') .. '</a> <G>-<R> <a href="event:groundDel' .. i .. '">Supprimer</a> <G>-<J> <a href="event:groundZ+' .. i .. '">↑</a> <a href="event:groundZ-' .. i .. '">↓</a>\n'
  262. end
  263. end
  264. groundsStr = groundsStr .. "\n\n<p align='center'>"
  265. if #grounds > 8 then
  266. if startID > 8 then
  267. groundsStr = groundsStr .. string.format('<a href="event:groundSettings%d">&lt; <font color="#c2c2da">%d-%d</font></a>', startID-8, startID-8, startID-1)
  268. end
  269. if #grounds > startID+8 then
  270. startID = startID+8
  271. groundsStr = groundsStr .. string.format(' %s<a href="event:groundSettings%d">&gt; <font color="#c2c2da">%d-%d</font></a>', startID > 8 and "<G>|<V> " or "", startID, startID, startID+7)
  272. end
  273. end
  274. groundsStr = groundsStr .. "\n<V> Total: <N>" .. #grounds .. " <G>|<V> <R><b><a href='event:close'>Fermer</a></b>"
  275. ui.addTextArea(45,"<p align='center'><J><font size='20'>Options des sols</font>\n\n<a href='event:groundAdd'>Ajouter</a><p align='left'>\n\n"..groundsStr,name,300,50,200,317,1,0,0.8)
  276. elseif callback == 'groundAdd' then
  277. table.insert(grounds, { L=10, H=10, X=0, Y=0, T=0, P=string.split('0,0,0.3,0.2,0,0,0,0') })
  278. eventTextAreaCallback(ID, name, 'groundSettings')
  279. elseif callback:sub(1,9) == 'groundDel' then
  280. local gID = tonumber(callback:sub(10) or 0)
  281. table.remove(grounds, gID)
  282. eventTextAreaCallback(ID, name, 'groundSettings')
  283. elseif callback:sub(1,10) == 'groundEdit' then
  284. local gID = tonumber(callback:sub(11)) -- zemin id
  285. if grounds[gID] then
  286. ui.addTextArea(121,"",name,grounds[gID].X-5,grounds[gID].Y-5,10,10,0xe9c764,0xe9c764,0.5)
  287. ui.removeTextArea(45, name)
  288. ui.addTextArea(71,string.format("<p align='center'><b><font color='#BABD2F'>Cliquez sur une de ces options pour modifier le sol</font></b><br><N><a href='event:changeValue%itype'>Type: %s</a> </font><G>|<N> <a href='event:changeValue%ix'>X: %i</a> <G>|<N> <a href='event:changeValue%iy'>Y: %i</a> <G>|<N> Z: %i <G>|<N> <a href='event:changeValue%il'>Longueur: %i</a> <G>|<N> <a href='event:changeValue%ih'>Hauteur: %i</a> <G>|<N> <a href='event:changeValue%ifri'>Friction: %s</a> <G>|<N> <a href='event:changeValue%ires'>Restitution: %s</a> <G>|<N> <a href='event:changeValue%iangle'>Angle: %i</a> <G>|<N> <a href='event:changeValue%icolor'>Couleur: %s</a><br><R><b><p align='left'><a href='event:close'>[Fermer]</a>",
  289. gID, groundTypes[tonumber(grounds[gID].T or 0)] or 'Unknown', gID, grounds[gID].X or 0, gID, grounds[gID].Y or 0, gID, gID, grounds[gID].L or 0, gID, grounds[gID].H or 0, gID, grounds[gID].P[3] or 0, gID, grounds[gID].P[4] or 0, gID, grounds[gID].P[5] or 0, gID, string.format('%x',grounds[gID].o or '0')),name,40,50,720,nil,1,0,0.8)
  290. else
  291. eventTextAreaCallback(ID, name, 'groundSettings')
  292. end
  293. elseif callback:sub(1,11) == 'changeValue' and callback:len() > 11 then
  294. local gID, editType = callback:match('changeValue(%d+)(.+)')
  295. if gID and editType then
  296. players[name].edit = { type=editType, ID=tonumber(gID) }
  297. ui.addPopup(53,2,"Entrez une nouvelle valeur",name,300,105,200)
  298. print(name.." - "..editType)
  299. end
  300. elseif callback:sub(1,7) == 'groundZ' then
  301. local o, gID = callback:match('groundZ([%+%-])(%d+)')
  302. gID = gID and tonumber(gID) or 0
  303. if grounds[gID] and #grounds > 1 then
  304. if o == '+' then
  305. table.swap(grounds, gID, gID == 1 and #grounds or gID-1)
  306. elseif o == '-' then
  307. table.swap(grounds, gID, gID == #grounds and 1 or gID+1)
  308. end
  309. eventTextAreaCallback(ID, name, 'groundSettings')
  310. end
  311. elseif callback == 'reloadMap' then
  312. updateXML()
  313. tfm.exec.newGame(xml)
  314. end
  315. end
  316. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement