init.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. local map_def={
  2. example = {
  3. p1x=168,
  4. p1z=530,
  5. p2x=780,
  6. p2z=1016,
  7. background="itm_example.png",
  8. },
  9. }
  10. local itm_cache={}
  11. local itm_pdata={}
  12. local itm_conf_mindia=0.1
  13. minetest.register_privilege("itm", { description = "Allows to display train map", give_to_singleplayer = true, default = false })
  14. local function create_map_form_with_bg(d)
  15. local minx, minz, maxx, maxz = math.min(d.p1x, d.p2x), math.min(d.p1z, d.p2z), math.max(d.p1x, d.p2x), math.max(d.p1z, d.p2z)
  16. local form_x, form_z=10,10
  17. local edge_x, edge_z = form_x/(maxx-minx), form_z/(maxz-minz)
  18. local len_x, len_z=math.max(edge_x, itm_conf_mindia), math.max(edge_z, itm_conf_mindia)
  19. local form="size["..(form_x+edge_x)..","..(form_z+edge_z).."] background[0,0;0,0;"..d.background..";true] "
  20. local lbl={}
  21. for pts, tid in pairs(advtrains.detector.on_node) do
  22. local pos=minetest.string_to_pos(pts)
  23. form=form.."box["..(edge_x*(pos.x-minx))..","..(form_z-(edge_z*(pos.z-minz)))..";"..len_x..","..len_z..";red]"
  24. lbl[sid(tid)]=pos
  25. end
  26. for t_id, xz in pairs(lbl) do
  27. form=form.."label["..(edge_x*(xz.x-minx))..","..(form_x-(edge_z*(xz.z-minz)))..";"..t_id.."]"
  28. end
  29. return form
  30. end
  31. local function create_map_form(d)
  32. if d.background then
  33. return create_map_form_with_bg(d)
  34. end
  35. local minx, minz, maxx, maxz = math.min(d.p1x, d.p2x), math.min(d.p1z, d.p2z), math.max(d.p1x, d.p2x), math.max(d.p1z, d.p2z)
  36. local form_x, form_z=10,10
  37. local edge_x, edge_z = form_x/(maxx-minx), form_z/(maxz-minz)
  38. local len_x, len_z=math.max(edge_x, itm_conf_mindia), math.max(edge_z, itm_conf_mindia)
  39. local form="size["..(form_x+edge_x)..","..(form_z+edge_z).."]"
  40. local lbl={}
  41. for x,itx in pairs(itm_cache) do
  42. if x>=minx and x<=maxx then
  43. for z,y in pairs(itx) do
  44. if z>=minz and z<=maxz then
  45. local adn=advtrains.detector.get({x=x, y=y, z=z})
  46. local color="gray"
  47. if adn then
  48. color="red"
  49. lbl[sid(adn)]={x=x, z=z}
  50. end
  51. form=form.."box["..(edge_x*(x-minx))..","..(form_z-(edge_z*(z-minz)))..";"..len_x..","..len_z..";"..color.."]"
  52. end
  53. end
  54. end
  55. end
  56. for t_id, xz in pairs(lbl) do
  57. form=form.."label["..(edge_x*(xz.x-minx))..","..(form_x-(edge_z*(xz.z-minz)))..";"..t_id.."]"
  58. end
  59. return form
  60. end
  61. local function cache_ndb()
  62. itm_cache={}
  63. local ndb_nodes=advtrains.ndb.get_nodes()
  64. for y, xzt in pairs(ndb_nodes) do
  65. for x, zt in pairs(xzt) do
  66. for z, _ in pairs(zt) do
  67. if not itm_cache[x] then
  68. itm_cache[x]={}
  69. end
  70. itm_cache[x][z]=y
  71. end
  72. end
  73. end
  74. end
  75. minetest.register_chatcommand("itm", {
  76. params="[x1 z1 x2 z2] or [mdef]",
  77. description="Display advtrains train map of given area.\nFirst form:[x1 z1 x2 z2] - specify area directly.\nSecond form:[mdef] - Use a predefined map background(see init.lua)\nThird form: No parameters - use WorldEdit position markers.",
  78. privs={itm=true},
  79. func = function(name, param)
  80. local mdef=string.match(param, "^(%S+)$")
  81. if mdef then
  82. local d=map_def[mdef]
  83. if not d then
  84. return false, "Map definiton not found: "..mdef
  85. end
  86. itm_pdata[name]=map_def[mdef]
  87. minetest.show_formspec(name, "itrainmap", create_map_form(d))
  88. return true, "Showing train map: "..mdef
  89. end
  90. local x1, z1, x2, z2=string.match(param, "^(%S+) (%S+) (%S+) (%S+)$")
  91. if not (x1 and z1 and x2 and z2) then
  92. if worldedit then
  93. local wep1, wep2=worldedit.pos1[name], worldedit.pos2[name]
  94. if wep1 and wep2 then
  95. x1, z1, x2, z2=wep1.x, wep1.z, wep2.x, wep2.z
  96. end
  97. end
  98. end
  99. if not (x1 and z1 and x2 and z2) then
  100. return false, "Invalid parameters and no WE positions set"
  101. end
  102. local d={p1x=x1, p1z=z1, p2x=x2, p2z=z2}
  103. itm_pdata[name]=d
  104. minetest.show_formspec(name, "itrainmap", create_map_form(d))
  105. return true, "Showing ("..x1..","..z1..")-("..x2..","..z2..")"
  106. end,
  107. })
  108. minetest.register_chatcommand("itm_cache_ndb", {
  109. params="",
  110. description="Cache advtrains node database again. Run when tracks changed.",
  111. privs={itm=true},
  112. func = function(name, param)
  113. cache_ndb()
  114. return true, "Done caching node database."
  115. end,
  116. })
  117. local timer=0
  118. function advtrains_itm_mainloop(dtime)
  119. timer=timer-math.min(dtime, 0.1)
  120. if timer<=0 then
  121. for pname,d in pairs(itm_pdata) do
  122. minetest.show_formspec(pname, "itrainmap", create_map_form(d))
  123. end
  124. timer=2
  125. end
  126. end
  127. minetest.register_on_player_receive_fields(function(player, formname, fields)
  128. if formname=="itrainmap" and fields.quit then
  129. itm_pdata[player:get_player_name()]=nil
  130. end
  131. end)
  132. function advtrains_itm_init()
  133. --automatically run itm_cache_ndb
  134. minetest.after(2, cache_ndb)
  135. end