init.lua 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. if not minetest.global_exists("marker") then marker = {} end
  2. marker.modpath = minetest.get_modpath("marker")
  3. marker.players = marker.players or {}
  4. marker.gui = marker.gui or {}
  5. marker.steptime = 1
  6. marker.max_waypoints = 100
  7. marker.max_lists = 50
  8. -- Max distance of players who wish to share marker lists.
  9. marker.proximity_range = 10
  10. -- Min/max ranges for visual particles.
  11. marker.pr_min = 40
  12. marker.pr_max = 50
  13. -- Min/max ranges for HUD text objects.
  14. marker.ht_min = 12
  15. marker.ht_max1 = 100
  16. marker.ht_max2 = 110
  17. -- Localize for performance.
  18. local vector_distance = vector.distance
  19. local vector_round = vector.round
  20. local timer = 0
  21. local delay = marker.steptime
  22. function marker.on_globalstep(dtime)
  23. timer = timer + dtime
  24. if timer < delay then return end
  25. timer = 0
  26. marker.update_huds()
  27. end
  28. function marker.update_huds()
  29. -- localize
  30. -- create gui for player if not created already
  31. local players = marker.players
  32. for k, v in pairs(players) do
  33. marker.update_single_hud(k)
  34. end
  35. end
  36. function marker.on_leaveplayer(pref, timeout)
  37. local pname = pref:get_player_name()
  38. marker.players[pname] = nil
  39. marker.gui[pname] = nil
  40. end
  41. function marker.update_single_hud(player)
  42. local allgui = marker.gui
  43. if not allgui[player] then
  44. marker.create_gui(player)
  45. end
  46. local gui = allgui[player]
  47. local waypoints = gui.waypoints
  48. local pref = minetest.get_player_by_name(player)
  49. if not pref or not pref:is_player() then
  50. return
  51. end
  52. local d = vector.distance
  53. local p2 = pref:get_pos()
  54. for i = 1, #waypoints, 1 do
  55. local data = waypoints[i]
  56. local dist = d(data.pos, p2)
  57. if dist > marker.ht_min and dist < marker.ht_max1 then
  58. -- add hud element if nearby and not already added
  59. if not data.hnd then
  60. local wp = vector.add(data.pos, {x=0, y=1, z=0})
  61. local number = "7902626"
  62. if data.highlight then
  63. number = "8739932"
  64. end
  65. data.hnd = pref:hud_add({
  66. hud_elem_type = "waypoint",
  67. name = "Marker",
  68. number = number,
  69. world_pos = wp,
  70. })
  71. end
  72. elseif dist < marker.ht_min or dist > marker.ht_max2 then
  73. -- remove hud element if too far and not yet removed
  74. if data.hnd then
  75. pref:hud_remove(data.hnd)
  76. data.hnd = nil
  77. end
  78. end
  79. if dist < marker.pr_min then
  80. if not data.pts then
  81. local wp = vector.add(data.pos, {x=0, y=0.5, z=0})
  82. local particles = {
  83. amount = 20,
  84. time = 0,
  85. minpos = vector.add(wp, {x=-0.1, y=-0.1, z=-0.1}),
  86. maxpos = vector.add(wp, {x=0.1, y=0.1, z=0.1}),
  87. minvel = vector.new(-0.5, -0.5, -0.5),
  88. maxvel = vector.new(0.5, 0.5, 0.5),
  89. minacc = {x=0, y=0, z=0},
  90. maxacc = {x=0, y=0, z=0},
  91. minexptime = 0.5,
  92. maxexptime = 2.0,
  93. minsize = 1,
  94. maxsize = 1,
  95. collisiondetection = false,
  96. collision_removal = false,
  97. vertical = false,
  98. texture = "quartz_crystal_piece.png",
  99. glow = 14,
  100. playername = player,
  101. }
  102. data.pts = minetest.add_particlespawner_single(particles)
  103. end
  104. elseif dist > marker.pr_max then
  105. if data.pts then
  106. minetest.delete_particlespawner(data.pts, player)
  107. data.pts = nil
  108. end
  109. end
  110. end
  111. end
  112. function marker.update_hud_markers(player, list, highlight)
  113. -- localize
  114. local allgui = marker.gui
  115. if not allgui[player] then
  116. marker.create_gui(player)
  117. end
  118. local gui = allgui[player]
  119. local waypoints = gui.waypoints
  120. -- remove all existing hud elements
  121. local pref = minetest.get_player_by_name(player)
  122. if not pref or not pref:is_player() then
  123. return
  124. end
  125. for i = 1, #waypoints, 1 do
  126. local data = waypoints[i]
  127. if data.hnd then
  128. pref:hud_remove(data.hnd)
  129. data.hnd = nil
  130. end
  131. if data.pts then
  132. minetest.delete_particlespawner(data.pts, player)
  133. data.pts = nil
  134. end
  135. if data.highlight then
  136. data.highlight = nil
  137. end
  138. end
  139. -- update waypoint list data
  140. gui.waypoints = {}
  141. waypoints = gui.waypoints
  142. if gui.show and list and list ~= "" then
  143. local data = marker.get_list(player, list)
  144. for i = 1, #data, 1 do
  145. waypoints[#waypoints + 1] = {pos=table.copy(data[i])}
  146. if highlight and highlight == i then
  147. waypoints[#waypoints].highlight = true
  148. end
  149. end
  150. end
  151. marker.update_single_hud(player)
  152. end
  153. function marker.highlight_marker(player, index)
  154. -- localize
  155. local allgui = marker.gui
  156. if not allgui[player] then
  157. marker.create_gui(player)
  158. end
  159. local gui = allgui[player]
  160. local waypoints = gui.waypoints
  161. for i = 1, #waypoints, 1 do
  162. local data = waypoints[i]
  163. if data.highlight then
  164. data.highlight = nil
  165. -- return marker to regular color
  166. if data.hnd then
  167. local pref = minetest.get_player_by_name(player)
  168. if pref and pref:is_player() then
  169. pref:hud_change(data.hnd, "number", "7902626")
  170. end
  171. end
  172. end
  173. end
  174. if index >= 1 and index <= #waypoints then
  175. local data = waypoints[index]
  176. if not data.highlight then
  177. data.highlight = true
  178. -- change (highlight) marker color
  179. if data.hnd then
  180. local pref = minetest.get_player_by_name(player)
  181. if pref and pref:is_player() then
  182. pref:hud_change(data.hnd, "number", "8739932")
  183. end
  184. end
  185. end
  186. end
  187. end
  188. -- private: load player data
  189. function marker.load_player(player)
  190. -- localize
  191. local players = marker.players
  192. -- load player data from mod storage
  193. local str = marker.storage:get_string(player)
  194. assert(type(str) == "string")
  195. if str == "" then
  196. players[player] = {}
  197. return
  198. end
  199. local lists = minetest.deserialize(str)
  200. if not lists then
  201. players[player] = {}
  202. return
  203. end
  204. -- data is now loaded
  205. assert(type(lists) == "table")
  206. players[player] = lists
  207. end
  208. -- private: save player data
  209. function marker.save_player(player)
  210. -- localize
  211. local players = marker.players
  212. -- localize
  213. local lists = players[player] or {}
  214. local str = minetest.serialize(lists)
  215. assert(type(str) == "string")
  216. -- send data to mod storage
  217. marker.storage:set_string(player, str)
  218. end
  219. -- api: player name, position, list name
  220. function marker.add_waypoint(player, pos, list)
  221. -- localize
  222. local players = marker.players
  223. -- load data for player if not loaded already
  224. if not players[player] then
  225. marker.load_player(player)
  226. end
  227. -- localize
  228. local lists = players[player]
  229. -- create waypoint list if not created already
  230. local found = false
  231. local positions
  232. for i = 1, #lists, 1 do
  233. if lists[i].name == list then
  234. found = true
  235. positions = lists[i].data
  236. break
  237. end
  238. end
  239. if not found then
  240. lists[#lists + 1] = {name=list, data={}}
  241. positions = lists[#lists].data
  242. end
  243. -- add position
  244. positions[#positions + 1] = vector_round(pos)
  245. -- save changes
  246. marker.save_player(player)
  247. end
  248. -- api: player name, index, list name
  249. function marker.remove_waypoint(player, index, list)
  250. -- localize
  251. local players = marker.players
  252. -- load data for player if not loaded already
  253. if not players[player] then
  254. marker.load_player(player)
  255. end
  256. -- localize
  257. local lists = players[player]
  258. -- search player data for named list
  259. -- ignore if list doesn't exist
  260. local found = false
  261. local positions
  262. for i = 1, #lists, 1 do
  263. if lists[i].name == list then
  264. found = true
  265. positions = lists[i].data
  266. break
  267. end
  268. end
  269. if not found then
  270. return
  271. end
  272. -- localize
  273. local equals = vector.equals
  274. local changed = false
  275. local pos
  276. -- erase position from positions list
  277. if index >= 1 and index <= #positions then
  278. pos = positions[index]
  279. table.remove(positions, index)
  280. changed = true
  281. end
  282. -- save changes if needed
  283. if changed then
  284. marker.save_player(player)
  285. end
  286. -- return pos or nil
  287. return pos
  288. end
  289. -- private: get the list of positions for a given list name
  290. --
  291. -- important: the list can be modified, and if modified, must be saved afterward
  292. -- by calling marker.save_player(), otherwise changes will be lost eventually
  293. function marker.get_list(player, list)
  294. assert(type(list) == "string" and list ~= "")
  295. -- localize
  296. local players = marker.players
  297. -- load data for player if not loaded already
  298. if not players[player] then
  299. marker.load_player(player)
  300. end
  301. -- localize
  302. local lists = players[player]
  303. -- if named list doesn't exist, create it
  304. local found = false
  305. local positions
  306. for i = 1, #lists, 1 do
  307. if lists[i].name == list then
  308. found = true
  309. positions = lists[i].data
  310. break
  311. end
  312. end
  313. if not found then
  314. lists[#lists + 1] = {name=list, data={}}
  315. positions = lists[#lists].data
  316. -- a new list was added, need to save data
  317. marker.save_player(player)
  318. end
  319. -- return the named list
  320. -- the list can be modifed
  321. -- remember to save the data
  322. return positions
  323. end
  324. -- api: player name, list index
  325. function marker.get_list_name(player, index)
  326. -- localize
  327. local players = marker.players
  328. -- load data for player if not loaded already
  329. if not players[player] then
  330. marker.load_player(player)
  331. end
  332. -- localize
  333. local lists = players[player]
  334. local name = ""
  335. for i = 1, #lists, 1 do
  336. if lists[i].name == "default" then
  337. if index >= i then
  338. index = index + 1
  339. -- fix corner case
  340. if index > #lists then
  341. index = #lists
  342. end
  343. end
  344. end
  345. if i == index then
  346. name = lists[i].name
  347. break
  348. end
  349. end
  350. return name
  351. end
  352. -- api: player name, list name
  353. function marker.have_list(player, list)
  354. local players = marker.players
  355. if not players[player] then
  356. return false
  357. end
  358. local alists = players[player]
  359. local found = false
  360. for i = 1, #alists, 1 do
  361. if alists[i].name == list then
  362. found = true
  363. break
  364. end
  365. end
  366. return found
  367. end
  368. -- api: player name, list name
  369. function marker.list_size(player, list)
  370. local players = marker.players
  371. if not players[player] then
  372. return 0
  373. end
  374. local alists = players[player]
  375. local size = 0
  376. for i = 1, #alists, 1 do
  377. if alists[i].name == list then
  378. size = #(alists[i].data)
  379. break
  380. end
  381. end
  382. return size
  383. end
  384. function marker.list_count(player)
  385. local players = marker.players
  386. if not players[player] then
  387. return 0
  388. end
  389. local alists = players[player]
  390. local size = 0
  391. for i = 1, #alists, 1 do
  392. if alists[i].name ~= "default" then
  393. size = size + 1
  394. end
  395. end
  396. return size
  397. end
  398. -- api: player name, list name
  399. function marker.remove_list(player, list)
  400. local players = marker.players
  401. if not players[player] then
  402. return
  403. end
  404. local changed = false
  405. local alists = players[player]
  406. for i = 1, #alists, 1 do
  407. if alists[i].name == list then
  408. table.remove(alists, i)
  409. changed = true
  410. break
  411. end
  412. end
  413. if changed then
  414. marker.save_player(player)
  415. end
  416. end
  417. -- private: create gui-data for player
  418. function marker.create_gui(player)
  419. marker.gui[player] = {
  420. index1 = -1,
  421. index2 = -1,
  422. index3 = -1,
  423. listname = "",
  424. playername = "",
  425. waypoints = {},
  426. }
  427. end
  428. -- private: assemble a formspec string
  429. function marker.get_formspec(player)
  430. -- localize
  431. local players = marker.players
  432. local allgui = marker.gui
  433. -- load data for player if not loaded already
  434. if not players[player] then
  435. marker.load_player(player)
  436. end
  437. local alists = players[player]
  438. -- create gui for player if not created already
  439. if not allgui[player] then
  440. marker.create_gui(player)
  441. end
  442. local gui = allgui[player]
  443. local deflist = marker.get_list(player, "default")
  444. local formspec = "size[9,7]" ..
  445. default.gui_bg ..
  446. default.gui_bg_img ..
  447. default.gui_slots
  448. formspec = formspec ..
  449. "item_image[0,0;1,1;passport:passport_adv]" ..
  450. "label[1,0;Key Device Marker System]" ..
  451. "field[0.3,1.3;2.9,1;listname;;" .. minetest.formspec_escape(gui.listname) .. "]" ..
  452. "field[0.3,2.15;2.9,1;player;;" .. minetest.formspec_escape(gui.playername) .. "]"
  453. formspec = formspec ..
  454. "textlist[5.0,0.0;3.7,2.6;lists;"
  455. local comma = ""
  456. --minetest.log(dump(alists))
  457. for i = 1, #alists, 1 do
  458. local k = alists[i].name
  459. if k ~= "default" then
  460. formspec = formspec .. comma .. minetest.formspec_escape(k)
  461. comma = ","
  462. end
  463. end
  464. formspec = formspec .. ";" .. gui.index1 .. "]" ..
  465. "textlist[0.0,3.0;3.7,3.0;markers;"
  466. for i = 1, #deflist, 1 do
  467. local s = rc.pos_to_namestr(deflist[i])
  468. formspec = formspec .. minetest.formspec_escape(s)
  469. if i < #deflist then
  470. formspec = formspec .. ","
  471. end
  472. end
  473. formspec = formspec .. ";" .. gui.index2 .. "]" ..
  474. "textlist[5.0,3.0;3.7,4.0;positions;"
  475. local lname = marker.get_list_name(player, gui.index1)
  476. if lname and lname ~= "" then
  477. local data = marker.get_list(player, lname)
  478. comma = ""
  479. for i = 1, #data, 1 do
  480. local s = minetest.formspec_escape(rc.pos_to_namestr(data[i]))
  481. formspec = formspec .. comma .. s
  482. comma = ","
  483. end
  484. end
  485. formspec = formspec .. ";" .. gui.index3 .. "]"
  486. formspec = formspec ..
  487. "button[3.0,1.0;1,1;addlist;>]" ..
  488. "button[4.0,1.0;1,1;dellist;X]" ..
  489. "button[3.0,1.85;2,1;sendlist;Send List]" ..
  490. "button[4.0,3.0;1,1;ls;<]" ..
  491. "button[4.0,4.0;1,1;mark;Mark]" ..
  492. "button[4.0,5.0;1,1;rs;>]" ..
  493. "button[0.0,6.25;1,1;done;Done]" ..
  494. "button[1.0,6.25;1,1;delete;Erase]"
  495. if not gui.show then
  496. formspec = formspec .. "button[2.0,6.25;3,1;show;Enable Scan]"
  497. else
  498. formspec = formspec .. "button[2.0,6.25;3,1;hide;Disable Scan]"
  499. end
  500. return formspec
  501. end
  502. -- api: show formspec to player
  503. function marker.show_formspec(player)
  504. local formspec = marker.get_formspec(player)
  505. minetest.show_formspec(player, "marker:fs", formspec)
  506. end
  507. marker.on_receive_fields = function(player, formname, fields)
  508. if formname ~= "marker:fs" then return end
  509. local pname = player:get_player_name()
  510. -- security check to make sure player can use this feature
  511. local inv = player:get_inventory()
  512. if not inv:contains_item("main", "passport:passport_adv") then
  513. return true
  514. end
  515. -- ensure user-data is loaded and available
  516. if not marker.players[pname] then
  517. marker.load_player(pname)
  518. end
  519. -- localize
  520. -- create gui for player if not created already
  521. local allgui = marker.gui
  522. if not allgui[pname] then
  523. marker.create_gui(pname)
  524. end
  525. local gui = allgui[pname]
  526. if fields.done then
  527. passport.show_formspec(pname)
  528. return true
  529. end
  530. if fields.quit then
  531. return true
  532. end
  533. if fields.listname then
  534. gui.listname = fields.listname
  535. end
  536. if fields.player then
  537. gui.playername = fields.player
  538. end
  539. if fields.show then
  540. gui.show = true
  541. if gui.listname and gui.listname ~= "" then
  542. marker.update_hud_markers(pname, gui.listname)
  543. end
  544. end
  545. if fields.hide then
  546. gui.show = nil
  547. marker.update_hud_markers(pname)
  548. end
  549. if fields.addlist then
  550. if marker.list_count(pname) < marker.max_lists then
  551. local name = fields.listname or ""
  552. name = name:trim()
  553. if name == "" then
  554. minetest.chat_send_player(pname, "# Server: Cannot add list with empty name.")
  555. elseif name == "default" then
  556. minetest.chat_send_player(pname, "# Server: Cannot add list with reserved name.")
  557. else
  558. if marker.have_list(pname, name) then
  559. minetest.chat_send_player(pname, "# Server: Cannot add list, it already exists.")
  560. else
  561. -- this automatically adds the list if it doesn't exist
  562. local pos = player:get_pos()
  563. pos.y = pos.y + 1
  564. marker.add_waypoint(pname, pos, name)
  565. gui.index1 = #(marker.players[pname])
  566. gui.index3 = -1
  567. marker.update_hud_markers(pname, name)
  568. minetest.chat_send_player(pname, "# Server: Added list.")
  569. end
  570. end
  571. else
  572. minetest.chat_send_player(pname, "# Server: Marker list roster is full, cannot create a new marker list.")
  573. end
  574. elseif fields.dellist then
  575. local name = fields.listname or ""
  576. name = name:trim()
  577. if name == "" then
  578. minetest.chat_send_player(pname, "# Server: Cannot remove list with empty name.")
  579. elseif name == "default" then
  580. minetest.chat_send_player(pname, "# Server: Cannot remove list with reserved name.")
  581. else
  582. if marker.have_list(pname, name) then
  583. marker.remove_list(pname, name)
  584. gui.index1 = -1
  585. gui.listname = ""
  586. marker.update_hud_markers(pname)
  587. minetest.chat_send_player(pname, "# Server: Removed marker list.")
  588. else
  589. minetest.chat_send_player(pname, "# Server: Cannot remove non-existent list.")
  590. end
  591. end
  592. elseif fields.sendlist then
  593. local targetname = fields.player or ""
  594. targetname = targetname:trim()
  595. if targetname ~= "" then
  596. targetname = rename.grn(targetname)
  597. if targetname ~= pname then
  598. local ptarget = minetest.get_player_by_name(targetname)
  599. if ptarget and ptarget:is_player() then
  600. if vector_distance(ptarget:get_pos(), player:get_pos()) < marker.proximity_range then
  601. local inv = ptarget:get_inventory()
  602. if inv:contains_item("main", "passport:passport_adv") then
  603. local name = marker.get_list_name(pname, gui.index1)
  604. if name and name ~= "" then
  605. -- load data for target player if not loaded already
  606. -- otherwise checking to see if player already has list could fail
  607. -- in a very wrong way
  608. if not marker.players[targetname] then
  609. marker.load_player(targetname)
  610. end
  611. if marker.have_list(targetname, name) then
  612. minetest.chat_send_player(pname, "# Server: The other Key already hosts a marker list with that name. Cannot transfer data!")
  613. else
  614. if marker.list_count(targetname) < marker.max_lists then
  615. local datafrom = marker.get_list(pname, name)
  616. -- because we checked to make sure the target key doesn't have this list already,
  617. -- we have assured that this will create it for the first time, and it will be empty
  618. local datato = marker.get_list(targetname, name)
  619. for i = 1, #datafrom, 1 do
  620. datato[#datato + 1] = table.copy(datafrom[i])
  621. end
  622. minetest.chat_send_player(pname, "# Server: Marker list sent!")
  623. minetest.chat_send_player(targetname, "# Server: <" .. rename.gpn(pname) .. "> sent a marker list to your Key!")
  624. else
  625. minetest.chat_send_player(pname, "# Server: The other Key's marker list storage is full! Cannot transfer data.")
  626. end
  627. end
  628. else
  629. minetest.chat_send_player(pname, "# Server: You must select a marker list, first.")
  630. end
  631. else
  632. minetest.chat_send_player(pname, "# Server: The other player does not have a Key!")
  633. end
  634. else
  635. minetest.chat_send_player(pname, "# Server: You need to stand close to the other player's Key to transfer a marker list.")
  636. end
  637. else
  638. minetest.chat_send_player(pname, "# Server: The specified player is not available.")
  639. end
  640. else
  641. minetest.chat_send_player(pname, "# Server: Cannot send marker list to your own Key.")
  642. end
  643. else
  644. minetest.chat_send_player(pname, "# Server: You must specify the name of a player to send a marker list to.")
  645. end
  646. elseif fields.ls then
  647. local name = marker.get_list_name(pname, gui.index1)
  648. if name and name ~= "" then
  649. if marker.list_size(pname, "default") < marker.max_waypoints then
  650. local data = marker.get_list(pname, name)
  651. if gui.index3 >= 1 and gui.index3 <= #data then
  652. local pos = marker.remove_waypoint(pname, gui.index3, name)
  653. if pos then
  654. marker.add_waypoint(pname, pos, "default")
  655. local deflist = marker.get_list(pname, "default")
  656. gui.index2 = #deflist
  657. gui.index3 = -1
  658. marker.update_hud_markers(pname, name)
  659. minetest.chat_send_player(pname, "# Server: Moved marker to free-list.")
  660. else
  661. minetest.chat_send_player(pname, "# Server: Could not remove marker from list.")
  662. end
  663. else
  664. minetest.chat_send_player(pname, "# Server: You need to have selected a marker to be moved.")
  665. end
  666. else
  667. minetest.chat_send_player(pname, "# Server: Cannot remove marker from list, free-list storage is full.")
  668. end
  669. else
  670. minetest.chat_send_player(pname, "# Server: You must select a marker list, first.")
  671. end
  672. elseif fields.rs then
  673. local name = marker.get_list_name(pname, gui.index1)
  674. if name and name ~= "" then
  675. if marker.list_size(pname, name) < marker.max_waypoints then
  676. local data = marker.get_list(pname, "default")
  677. if gui.index2 >= 1 and gui.index2 <= #data then
  678. local pos = marker.remove_waypoint(pname, gui.index2, "default")
  679. if pos then
  680. marker.add_waypoint(pname, pos, name)
  681. local thelist = marker.get_list(pname, name)
  682. gui.index3 = #thelist
  683. gui.index2 = -1
  684. marker.update_hud_markers(pname, name, gui.index3)
  685. minetest.chat_send_player(pname, "# Server: Moved unattached marker to list.")
  686. else
  687. minetest.chat_send_player(pname, "# Server: Could not remove marker from free-list.")
  688. end
  689. else
  690. minetest.chat_send_player(pname, "# Server: You need to have selected a marker to be moved.")
  691. end
  692. else
  693. minetest.chat_send_player(pname, "# Server: Cannot add marker to list, list storage is full.")
  694. end
  695. else
  696. minetest.chat_send_player(pname, "# Server: You must select a marker list, first.")
  697. end
  698. elseif fields.mark then
  699. if marker.list_size(pname, "default") < marker.max_waypoints then
  700. local pos = player:get_pos()
  701. pos.y = pos.y + 1
  702. marker.add_waypoint(pname, pos, "default")
  703. local deflist = marker.get_list(pname, "default")
  704. gui.index2 = #deflist
  705. minetest.chat_send_player(pname, "# Server: Placed marker at " .. rc.pos_to_namestr(vector_round(pos)) .. ".")
  706. else
  707. minetest.chat_send_player(pname, "# Server: Cannot place a new marker, storage is full.")
  708. end
  709. elseif fields.delete then
  710. local index = gui.index2
  711. local deflist = marker.get_list(pname, "default")
  712. if index >= 1 and index <= #deflist then
  713. local s = rc.pos_to_namestr(deflist[index])
  714. marker.remove_waypoint(pname, index, "default")
  715. gui.index2 = -1
  716. minetest.chat_send_player(pname, "# Server: Removed marker: " .. s .. ".")
  717. else
  718. minetest.chat_send_player(pname, "# Server: You must select a marker from the marker list, to erase it.")
  719. end
  720. elseif fields.lists then
  721. local event = minetest.explode_textlist_event(fields.lists)
  722. if event.type == "CHG" then
  723. local index = event.index
  724. gui.index1 = index
  725. gui.index3 = -1
  726. gui.listname = marker.get_list_name(pname, index)
  727. marker.update_hud_markers(pname, gui.listname)
  728. end
  729. elseif fields.markers then
  730. local event = minetest.explode_textlist_event(fields.markers)
  731. if event.type == "CHG" then
  732. local index = event.index
  733. gui.index2 = index
  734. end
  735. elseif fields.positions then
  736. local event = minetest.explode_textlist_event(fields.positions)
  737. if event.type == "CHG" then
  738. local index = event.index
  739. gui.index3 = index
  740. marker.highlight_marker(pname, index)
  741. end
  742. elseif fields.listname then
  743. -- nothing here atm
  744. elseif fields.player then
  745. -- nothing here atm
  746. end
  747. marker.show_formspec(pname)
  748. return true
  749. end
  750. if not marker.registered then
  751. marker.storage = minetest.get_mod_storage()
  752. minetest.register_on_player_receive_fields(function(...)
  753. return marker.on_receive_fields(...)
  754. end)
  755. minetest.register_globalstep(function(...)
  756. return marker.on_globalstep(...)
  757. end)
  758. minetest.register_on_leaveplayer(function(...)
  759. return marker.on_leaveplayer(...)
  760. end)
  761. local c = "marker:core"
  762. local f = marker.modpath .. "/init.lua"
  763. reload.register_file(c, f, false)
  764. marker.registered = true
  765. end