init.lua 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. smartshop={user={},tmp={},add_storage={},max_wifi_distance=30,
  2. mesecon=minetest.get_modpath("mesecons")~=nil,
  3. dir={{x=0,y=0,z=-1},{x=-1,y=0,z=0},{x=0,y=0,z=1},{x=1,y=0,z=0}},
  4. dpos={
  5. {{x=0.2,y=0.2,z=0},{x=-0.2,y=0.2,z=0},{x=0.2,y=-0.2,z=0},{x=-0.2,y=-0.2,z=0}},
  6. {{x=0,y=0.2,z=0.2},{x=0,y=0.2,z=-0.2},{x=0,y=-0.2,z=0.2},{x=0,y=-0.2,z=-0.2}},
  7. {{x=-0.2,y=0.2,z=0},{x=0.2,y=0.2,z=0},{x=-0.2,y=-0.2,z=0},{x=0.2,y=-0.2,z=0}},
  8. {{x=0,y=0.2,z=-0.2},{x=0,y=0.2,z=0.2},{x=0,y=-0.2,z=-0.2},{x=0,y=-0.2,z=0.2}}}
  9. }
  10. minetest.register_craft({
  11. output = "smartshop:shop",
  12. recipe = {
  13. {"default:chest_locked", "default:chest_locked", "default:chest_locked"},
  14. {"default:sign_wall_wood", "default:chest_locked", "default:sign_wall_wood"},
  15. {"default:sign_wall_wood", "default:torch", "default:sign_wall_wood"},
  16. }
  17. })
  18. minetest.register_craft({
  19. output = "smartshop:wifistorage",
  20. recipe = {
  21. {"default:mese_crystal_fragment", "default:chest_locked", "default:mese_crystal_fragment"},
  22. {"default:mese_crystal_fragment", "default:chest_locked", "default:mese_crystal_fragment"},
  23. {"default:steel_ingot", "default:copper_ingot", "default:steel_ingot"},
  24. }
  25. })
  26. smartshop.strpos=function(str,spl)
  27. if str==nil then return "" end
  28. if spl then
  29. local c=","
  30. if string.find(str," ") then c=" " end
  31. local s=str.split(str,c)
  32. if s[3]==nil then
  33. return nil
  34. else
  35. local p={x=tonumber(s[1]),y=tonumber(s[2]),z=tonumber(s[3])}
  36. if not (p and p.x and p.y and p.z) then return nil end
  37. return p
  38. end
  39. else if str and str.x and str.y and str.z then
  40. return str.x .."," .. str.y .."," .. str.z
  41. else
  42. return nil
  43. end
  44. end
  45. end
  46. smartshop.send_mesecon=function(pos)
  47. if smartshop.mesecon then
  48. mesecon.receptor_on(pos)
  49. minetest.get_node_timer(pos):start(1)
  50. end
  51. end
  52. smartshop.use_offer=function(pos,player,n)
  53. local pressed={}
  54. pressed["buy" .. n]=true
  55. smartshop.user[player:get_player_name()]=pos
  56. smartshop.receive_fields(player,pressed)
  57. smartshop.user[player:get_player_name()]=nil
  58. smartshop.update(pos)
  59. end
  60. smartshop.get_offer=function(pos)
  61. if not pos or not minetest.get_node(pos) then return end
  62. if minetest.get_node(pos).name~="smartshop:shop" then return end
  63. local meta=minetest.get_meta(pos)
  64. local inv=meta:get_inventory()
  65. local offer={}
  66. for i=1,4,1 do
  67. offer[i]={
  68. give=inv:get_stack("give" .. i,1):get_name(),
  69. give_count=inv:get_stack("give" .. i,1):get_count(),
  70. pay=inv:get_stack("pay" .. i,1):get_name(),
  71. pay_count=inv:get_stack("pay" .. i,1):get_count(),
  72. }
  73. end
  74. return offer
  75. end
  76. smartshop.receive_fields=function(player,pressed)
  77. local pname=player:get_player_name()
  78. local pos=smartshop.user[pname]
  79. if not pos then
  80. return
  81. elseif pressed.tsend then
  82. smartshop.add_storage[pname]={send=true,pos=pos}
  83. minetest.after(30, function(pname)
  84. if smartshop.add_storage[pname] then
  85. minetest.chat_send_player(pname, "Time expired (30s)")
  86. smartshop.add_storage[pname]=nil
  87. end
  88. end, pname)
  89. minetest.chat_send_player(pname, "Open a storage owned by you")
  90. return
  91. elseif pressed.trefill then
  92. smartshop.add_storage[pname]={refill=true,pos=pos}
  93. minetest.after(30, function(pname)
  94. if smartshop.add_storage[pname] then
  95. minetest.chat_send_player(pname, "Time expired (30s)")
  96. smartshop.add_storage[pname]=nil
  97. end
  98. end, pname)
  99. minetest.chat_send_player(pname, "Open a storage owned by you")
  100. return
  101. elseif pressed.customer then
  102. return smartshop.showform(pos,player,true)
  103. elseif pressed.sellall then
  104. local meta=minetest.get_meta(pos)
  105. local pname=player:get_player_name()
  106. if meta:get_int("sellall")==0 then
  107. meta:set_int("sellall",1)
  108. minetest.chat_send_player(pname, "Sell your stock and give line")
  109. else
  110. meta:set_int("sellall",0)
  111. minetest.chat_send_player(pname, "Sell your stock only")
  112. end
  113. elseif pressed.toogleee then
  114. local meta=minetest.get_meta(pos)
  115. local pname=player:get_player_name()
  116. if meta:get_int("type")==0 then
  117. meta:set_int("type",1)
  118. minetest.chat_send_player(pname, "Your stock is limited")
  119. else
  120. meta:set_int("type",0)
  121. minetest.chat_send_player(pname, "Your stock is unlimited")
  122. end
  123. elseif not pressed.quit then
  124. local n=1
  125. for i=1,4,1 do
  126. n=i
  127. if pressed["buy" .. i] then break end
  128. end
  129. local meta=minetest.get_meta(pos)
  130. local type=meta:get_int("type")
  131. local sellall=meta:get_int("sellall")
  132. local inv=meta:get_inventory()
  133. local pinv=player:get_inventory()
  134. local pname=player:get_player_name()
  135. local check_storage
  136. if pressed["buy" .. n] then
  137. local name=inv:get_stack("give" .. n,1):get_name()
  138. local stack=name .." ".. inv:get_stack("give" .. n,1):get_count()
  139. local pay=inv:get_stack("pay" .. n,1):get_name() .." ".. inv:get_stack("pay" .. n,1):get_count()
  140. local stack_to_use="main"
  141. if name~="" then
  142. --fast checks
  143. if not pinv:room_for_item("main", stack) then
  144. minetest.chat_send_player(pname, "Error: Your inventory is full, exchange aborted.")
  145. return
  146. elseif not pinv:contains_item("main", pay) then
  147. minetest.chat_send_player(pname, "Error: You dont have enough in your inventory to buy this, exchange aborted.")
  148. return
  149. elseif type==1 and inv:room_for_item("main", pay)==false then
  150. minetest.chat_send_player(pname, "Error: The owners stock is full, cant receive, exchange aborted.")
  151. else
  152. if inv:contains_item("main", stack) then
  153. elseif sellall==1 and inv:contains_item("give" .. n, stack) then
  154. stack_to_use="give" .. n
  155. else
  156. minetest.chat_send_player(pname, "Error: The owners stock is end.")
  157. check_storage=1
  158. end
  159. if not check_storage then
  160. for i=0,32,1 do
  161. if pinv:get_stack("main", i):get_name()==inv:get_stack("pay" .. n,1):get_name() and pinv:get_stack("main",i):get_wear()>0 then
  162. minetest.chat_send_player(pname, "Error: your item is used")
  163. return
  164. end
  165. end
  166. local rastack=inv:remove_item(stack_to_use, stack)
  167. pinv:remove_item("main", pay)
  168. pinv:add_item("main",rastack)
  169. if type==1 then inv:add_item("main",pay) end
  170. if type==0 then inv:add_item("main", rastack) end
  171. end
  172. end
  173. -- send to / refill from wifi storage
  174. if type==1 then
  175. local tsend=smartshop.strpos(meta:get_string("item_send"),1)
  176. local trefill=smartshop.strpos(meta:get_string("item_refill"),1)
  177. if tsend then
  178. local m=minetest.get_meta(tsend)
  179. local inv2=m:get_inventory()
  180. local mes=m:get_int("mesein")
  181. for i=1,10,1 do
  182. if inv2:room_for_item("main", pay) and inv:contains_item("main", pay) then
  183. inv2:add_item("main",pay)
  184. inv:remove_item("main", pay)
  185. if mes==1 or mes==3 then
  186. smartshop.send_mesecon(tsend)
  187. end
  188. else
  189. break
  190. end
  191. end
  192. end
  193. if trefill then
  194. local m=minetest.get_meta(trefill)
  195. local inv2=m:get_inventory()
  196. local mes=m:get_int("mesein")
  197. local space=0
  198. --check if its room for other items, else the shop will stuck
  199. for i=1,32,1 do
  200. if inv:get_stack("main",i):get_count()==0 then
  201. space=space+1
  202. end
  203. end
  204. for i=1,space,1 do
  205. if i<space and inv2:contains_item("main", stack) and inv:room_for_item("main", stack) then
  206. local rstack=inv2:remove_item("main", stack)
  207. inv:add_item("main",rstack)
  208. if mes==2 or mes==3 then
  209. smartshop.send_mesecon(trefill)
  210. end
  211. if check_storage then
  212. check_storage=nil
  213. minetest.chat_send_player(pname, "Try again, stock just refilled")
  214. end
  215. else
  216. break
  217. end
  218. end
  219. end
  220. end
  221. smartshop.send_mesecon(pos)
  222. end
  223. end
  224. else
  225. smartshop.update_info(pos)
  226. smartshop.update(pos,"update")
  227. smartshop.user[player:get_player_name()]=nil
  228. end
  229. end
  230. minetest.register_on_player_receive_fields(function(player, form, pressed)
  231. if form=="smartshop.showform" then
  232. smartshop.receive_fields(player,pressed)
  233. elseif form=="smartshop.showform2" then
  234. smartshop.receive_fields2(player,pressed)
  235. end
  236. end)
  237. smartshop.update_info=function(pos)
  238. local meta=minetest.get_meta(pos)
  239. local inv = meta:get_inventory()
  240. local owner=meta:get_string("owner")
  241. local gve=0
  242. if meta:get_int("sellall")==1 then gve=1 end
  243. if meta:get_int("type")==0 then
  244. meta:set_string("infotext","(Smartshop by " .. owner ..") Stock is unlimited")
  245. return false
  246. end
  247. local name=""
  248. local count=0
  249. local stuff={}
  250. for i=1,4,1 do
  251. stuff["count" ..i]=inv:get_stack("give" .. i,1):get_count()
  252. stuff["name" ..i]=inv:get_stack("give" .. i,1):get_name()
  253. stuff["stock" ..i]=gve*stuff["count" ..i]
  254. stuff["buy" ..i]=0
  255. for ii=1,32,1 do
  256. name=inv:get_stack("main",ii):get_name()
  257. count=inv:get_stack("main",ii):get_count()
  258. if name==stuff["name" ..i] then
  259. stuff["stock" ..i]=stuff["stock" ..i]+count
  260. end
  261. end
  262. local nstr=(stuff["stock" ..i]/stuff["count" ..i]) ..""
  263. nstr=nstr.split(nstr, ".")
  264. stuff["buy" ..i]=tonumber(nstr[1])
  265. if stuff["name" ..i]=="" or stuff["buy" ..i]==0 then
  266. stuff["buy" ..i]=""
  267. stuff["name" ..i]=""
  268. else
  269. if string.find(stuff["name" ..i],":")~=nil then
  270. stuff["name" ..i]=stuff["name" ..i].split(stuff["name" ..i],":")[2]
  271. end
  272. stuff["buy" ..i]="(" ..stuff["buy" ..i] ..") "
  273. stuff["name" ..i]=stuff["name" ..i] .."\n"
  274. end
  275. end
  276. meta:set_string("infotext",
  277. "(Smartshop by " .. owner ..") Purchases left:\n"
  278. .. stuff.buy1 .. stuff.name1
  279. .. stuff.buy2 .. stuff.name2
  280. .. stuff.buy3 .. stuff.name3
  281. .. stuff.buy4 .. stuff.name4
  282. )
  283. end
  284. smartshop.update=function(pos,stat)
  285. --clear
  286. local spos=minetest.pos_to_string(pos)
  287. for _, ob in ipairs(minetest.get_objects_inside_radius(pos, 2)) do
  288. if ob and ob:get_luaentity() and ob:get_luaentity().smartshop and ob:get_luaentity().pos==spos then
  289. ob:remove()
  290. end
  291. end
  292. if stat=="clear" then return end
  293. --update
  294. local meta=minetest.get_meta(pos)
  295. local inv = meta:get_inventory()
  296. local node=minetest.get_node(pos)
  297. local dp = smartshop.dir[node.param2+1]
  298. if not dp then return end
  299. pos.x = pos.x + dp.x*0.01
  300. pos.y = pos.y + dp.y*6.5/16
  301. pos.z = pos.z + dp.z*0.01
  302. for i=1,4,1 do
  303. local item=inv:get_stack("give" .. i,1):get_name()
  304. local pos2=smartshop.dpos[node.param2+1][i]
  305. if item~="" then
  306. smartshop.tmp.item=item
  307. smartshop.tmp.pos=spos
  308. local e = minetest.add_entity({x=pos.x+pos2.x,y=pos.y+pos2.y,z=pos.z+pos2.z},"smartshop:item")
  309. e:set_yaw(math.pi*2 - node.param2 * math.pi/2)
  310. end
  311. end
  312. end
  313. minetest.register_entity("smartshop:item",{
  314. hp_max = 1,
  315. visual="wielditem",
  316. visual_size={x=.20,y=.20},
  317. collisionbox = {0,0,0,0,0,0},
  318. physical=false,
  319. textures={"air"},
  320. smartshop=true,
  321. type="",
  322. on_activate = function(self, staticdata)
  323. if smartshop.tmp.item ~= nil then
  324. self.item=smartshop.tmp.item
  325. self.pos=smartshop.tmp.pos
  326. smartshop.tmp={}
  327. else
  328. if staticdata ~= nil and staticdata ~= "" then
  329. local data = staticdata:split(';')
  330. if data and data[1] and data[2] then
  331. self.item = data[1]
  332. self.pos = data[2]
  333. end
  334. end
  335. end
  336. if self.item ~= nil then
  337. self.object:set_properties({textures={self.item}})
  338. else
  339. self.object:remove()
  340. end
  341. end,
  342. get_staticdata = function(self)
  343. if self.item ~= nil and self.pos ~= nil then
  344. return self.item .. ';' .. self.pos
  345. end
  346. return ""
  347. end,
  348. })
  349. smartshop.showform=function(pos,player,re)
  350. local meta=minetest.get_meta(pos)
  351. local creative=meta:get_int("creative")
  352. local inv = meta:get_inventory()
  353. local gui=""
  354. local spos=pos.x .. "," .. pos.y .. "," .. pos.z
  355. local uname=player:get_player_name()
  356. local owner=meta:get_string("owner")==uname
  357. if minetest.check_player_privs(uname, {protection_bypass=true}) then owner=true end
  358. if re then owner=false end
  359. smartshop.user[uname]=pos
  360. if owner then
  361. if meta:get_int("type")==0 and not (minetest.check_player_privs(uname, {creative=true}) or minetest.check_player_privs(uname, {give=true})) then
  362. meta:set_int("creative",0)
  363. meta:set_int("type",1)
  364. creative=0
  365. end
  366. gui=""
  367. .."size[8,10]"
  368. .."button_exit[6,0;1.5,1;customer;Customer]"
  369. .."button[7.2,0;1,1;sellall;All]"
  370. .."label[0,0.2;Item:]"
  371. .."label[0,1.2;Price:]"
  372. .."list[nodemeta:" .. spos .. ";give1;1,0;1,1;]"
  373. .."list[nodemeta:" .. spos .. ";pay1;1,1;1,1;]"
  374. .."list[nodemeta:" .. spos .. ";give2;2,0;1,1;]"
  375. .."list[nodemeta:" .. spos .. ";pay2;2,1;1,1;]"
  376. .."list[nodemeta:" .. spos .. ";give3;3,0;1,1;]"
  377. .."list[nodemeta:" .. spos .. ";pay3;3,1;1,1;]"
  378. .."list[nodemeta:" .. spos .. ";give4;4,0;1,1;]"
  379. .."list[nodemeta:" .. spos .. ";pay4;4,1;1,1;]"
  380. .."button_exit[5,0;1,1;tsend;Send]"
  381. .."button_exit[5,1;1,1;trefill;Refill]"
  382. local tsend=smartshop.strpos(meta:get_string("item_send"),1)
  383. local trefill=smartshop.strpos(meta:get_string("item_refill"),1)
  384. if tsend then
  385. local m=minetest.get_meta(tsend)
  386. local title=m:get_string("title")
  387. if title=="" or m:get_string("owner")~=meta:get_string("owner") then
  388. meta:set_string("item_send","")
  389. title="error"
  390. end
  391. gui=gui .."tooltip[tsend;Send payments to " .. title .."]"
  392. else
  393. gui=gui .."tooltip[tsend;Send payments to storage]"
  394. end
  395. if trefill then
  396. local m=minetest.get_meta(trefill)
  397. local title=m:get_string("title")
  398. if title=="" or m:get_string("owner")~=meta:get_string("owner") then
  399. meta:set_string("item_refill","")
  400. title="error"
  401. end
  402. gui=gui .."tooltip[trefill;Refil from " .. title .."]"
  403. else
  404. gui=gui .."tooltip[trefill;Refil from storage]"
  405. end
  406. if creative==1 then
  407. gui=gui .."label[0.5,-0.4;Your stock is unlimeted becaouse you have creative or give]"
  408. .."button[6,1;2.2,1;tooglelime;Toogle limit]"
  409. end
  410. gui=gui
  411. .."list[nodemeta:" .. spos .. ";main;0,2;8,4;]"
  412. .."list[current_player;main;0,6.2;8,4;]"
  413. .."listring[nodemeta:" .. spos .. ";main]"
  414. .."listring[current_player;main]"
  415. else
  416. gui=""
  417. .."size[8,6]"
  418. .."list[current_player;main;0,2.2;8,4;]"
  419. .."label[0,0.2;Item:]"
  420. .."label[0,1.2;Price:]"
  421. .."list[nodemeta:" .. spos .. ";give1;2,0;1,1;]"
  422. .."item_image_button[2,1;1,1;".. inv:get_stack("pay1",1):get_name() ..";buy1;\n\n\b\b\b\b\b" .. inv:get_stack("pay1",1):get_count() .."]"
  423. .."list[nodemeta:" .. spos .. ";give2;3,0;1,1;]"
  424. .."item_image_button[3,1;1,1;".. inv:get_stack("pay2",1):get_name() ..";buy2;\n\n\b\b\b\b\b" .. inv:get_stack("pay2",1):get_count() .."]"
  425. .."list[nodemeta:" .. spos .. ";give3;4,0;1,1;]"
  426. .."item_image_button[4,1;1,1;".. inv:get_stack("pay3",1):get_name() ..";buy3;\n\n\b\b\b\b\b" .. inv:get_stack("pay3",1):get_count() .."]"
  427. .."list[nodemeta:" .. spos .. ";give4;5,0;1,1;]"
  428. .."item_image_button[5,1;1,1;".. inv:get_stack("pay4",1):get_name() ..";buy4;\n\n\b\b\b\b\b" .. inv:get_stack("pay4",1):get_count() .."]"
  429. end
  430. minetest.after((0.1), function(gui)
  431. return minetest.show_formspec(player:get_player_name(), "smartshop.showform",gui)
  432. end, gui)
  433. end
  434. minetest.register_node("smartshop:shop", {
  435. description = "Smartshop",
  436. tiles = {"default_chest_top.png^[colorize:#ffffff77^default_obsidian_glass.png"},
  437. groups = {choppy = 2, oddly_breakable_by_hand = 1,tubedevice = 1, tubedevice_receiver = 1,mesecon=2},
  438. drawtype="nodebox",
  439. node_box = {type="fixed",fixed={-0.5,-0.5,-0.0,0.5,0.5,0.5}},
  440. paramtype2="facedir",
  441. paramtype = "light",
  442. sunlight_propagates = true,
  443. light_source = 10,
  444. on_timer = function (pos, elapsed)
  445. if smartshop.mesecon then
  446. mesecon.receptor_off(pos)
  447. end
  448. return false
  449. end,
  450. tube = {insert_object = function(pos, node, stack, direction)
  451. local meta = minetest.get_meta(pos)
  452. local inv = meta:get_inventory()
  453. local added = inv:add_item("main", stack)
  454. return added
  455. end,
  456. can_insert = function(pos, node, stack, direction)
  457. local meta = minetest.get_meta(pos)
  458. local inv = meta:get_inventory()
  459. return inv:room_for_item("main", stack)
  460. end,
  461. input_inventory = "main",
  462. connect_sides = {left = 1, right = 1, front = 1, back = 1, top = 1, bottom = 1}},
  463. after_place_node = function(pos, placer)
  464. local meta=minetest.get_meta(pos)
  465. meta:set_string("owner",placer:get_player_name())
  466. meta:set_string("infotext", "Shop by: " .. placer:get_player_name())
  467. meta:set_int("type",1)
  468. meta:set_int("sellall",1)
  469. if minetest.check_player_privs(placer:get_player_name(), {creative=true}) or minetest.check_player_privs(placer:get_player_name(), {give=true}) then
  470. meta:set_int("creative",1)
  471. meta:set_int("type",0)
  472. meta:set_int("sellall",0)
  473. end
  474. end,
  475. on_construct = function(pos)
  476. local meta=minetest.get_meta(pos)
  477. meta:set_int("state", 0)
  478. meta:get_inventory():set_size("main", 32)
  479. meta:get_inventory():set_size("give1", 1)
  480. meta:get_inventory():set_size("pay1", 1)
  481. meta:get_inventory():set_size("give2", 1)
  482. meta:get_inventory():set_size("pay2", 1)
  483. meta:get_inventory():set_size("give3", 1)
  484. meta:get_inventory():set_size("pay3", 1)
  485. meta:get_inventory():set_size("give4", 1)
  486. meta:get_inventory():set_size("pay4", 1)
  487. end,
  488. on_rightclick = function(pos, node, player, itemstack, pointed_thing)
  489. smartshop.showform(pos,player)
  490. end,
  491. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  492. if stack:get_wear()==0 and (minetest.get_meta(pos):get_string("owner")==player:get_player_name() or minetest.check_player_privs(player:get_player_name(), {protection_bypass=true})) then
  493. return stack:get_count()
  494. end
  495. return 0
  496. end,
  497. allow_metadata_inventory_take = function(pos, listname, index, stack, player)
  498. if minetest.get_meta(pos):get_string("owner")==player:get_player_name() or minetest.check_player_privs(player:get_player_name(), {protection_bypass=true}) then
  499. return stack:get_count()
  500. end
  501. return 0
  502. end,
  503. allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
  504. if minetest.get_meta(pos):get_string("owner")==player:get_player_name() or minetest.check_player_privs(player:get_player_name(), {protection_bypass=true}) then
  505. return count
  506. end
  507. return 0
  508. end,
  509. can_dig = function(pos, player)
  510. local meta=minetest.get_meta(pos)
  511. local inv=meta:get_inventory()
  512. if ((meta:get_string("owner")==player:get_player_name() or minetest.check_player_privs(player:get_player_name(), {protection_bypass=true})) and inv:is_empty("main") and inv:is_empty("pay1") and inv:is_empty("pay2") and inv:is_empty("pay3") and inv:is_empty("pay4") and inv:is_empty("give1") and inv:is_empty("give2") and inv:is_empty("give3") and inv:is_empty("give4")) or meta:get_string("owner")=="" then
  513. smartshop.update(pos,"clear")
  514. return true
  515. end
  516. end,
  517. })
  518. smartshop.receive_fields2=function(player,pressed)
  519. local pname=player:get_player_name()
  520. local pos=smartshop.user[pname]
  521. if not pos then
  522. return
  523. end
  524. local meta=minetest.get_meta(pos)
  525. if pressed.mesesin then
  526. local m=meta:get_int("mesein")
  527. if m<=2 then
  528. m=m+1
  529. else
  530. m=0
  531. end
  532. meta:set_int("mesein",m)
  533. smartshop.showform2(pos,player)
  534. return
  535. elseif pressed.save then
  536. local t=pressed.title
  537. if t=="" then t="wifi" .. math.random(1,9999) end
  538. meta:set_string("title",t)
  539. end
  540. smartshop.user[pname]=nil
  541. end
  542. smartshop.showform2=function(pos,player)
  543. local meta=minetest.get_meta(pos)
  544. local uname=player:get_player_name()
  545. if meta:get_string("owner")~=uname and not minetest.check_player_privs(uname, {protection_bypass=true}) then return end
  546. local inv = meta:get_inventory()
  547. local spos=pos.x .. "," .. pos.y .. "," .. pos.z
  548. local title=meta:get_string("title")
  549. smartshop.user[uname]=pos
  550. local gui="size[12,9]"
  551. if title=="" then
  552. title="wifi" .. math.random(1,999)
  553. end
  554. if smartshop.mesecon then
  555. local m=meta:get_int("mesein")
  556. if m==0 then
  557. gui=gui .. "button[0,7;2,1;mesesin;Don't send]"
  558. elseif m==1 then
  559. gui=gui .. "button[0,7;2,1;mesesin;Incoming]"
  560. elseif m==2 then
  561. gui=gui .. "button[0,7;2,1;mesesin;Outcoming]"
  562. elseif m==3 then
  563. gui=gui .. "button[0,7;2,1;mesesin;Both]"
  564. end
  565. gui=gui.."tooltip[mesesin;Send mesecon signal when items from shops does:]"
  566. end
  567. gui=gui .. ""
  568. .."field[0.3,5.3;2,1;title;;" .. title .."]"
  569. gui=gui
  570. .."tooltip[title;Used with connected smartshops]"
  571. .."button_exit[0,6;2,1;save;Save]"
  572. .."list[nodemeta:" .. spos .. ";main;0,0;12,5;]"
  573. .."list[current_player;main;2,5;8,4;]"
  574. .."listring[nodemeta:" .. spos .. ";main]"
  575. .."listring[current_player;main]"
  576. minetest.after((0.1), function(gui)
  577. return minetest.show_formspec(uname, "smartshop.showform2",gui)
  578. end, gui)
  579. local a=smartshop.add_storage[uname]
  580. if a then
  581. if not a.pos then return end
  582. if vector.distance(a.pos, pos)>smartshop.max_wifi_distance then
  583. minetest.chat_send_player(uname, "Too far, max distance " .. smartshop.max_wifi_distance)
  584. end
  585. local meta=minetest.get_meta(a.pos)
  586. local p=smartshop.strpos(pos)
  587. if a.send and p then
  588. meta:set_string("item_send",p)
  589. elseif a.refill and p then
  590. meta:set_string("item_refill",p)
  591. end
  592. minetest.chat_send_player(uname, "smartshop connected")
  593. smartshop.add_storage[uname]=nil
  594. end
  595. end
  596. minetest.register_node("smartshop:wifistorage", {
  597. description = "Wifi storage",
  598. tiles = {"default_chest_top.png^[colorize:#ffffff77^default_obsidian_glass.png"},
  599. groups = {choppy = 2, oddly_breakable_by_hand = 1,tubedevice = 1, tubedevice_receiver = 1,mesecon=2},
  600. paramtype = "light",
  601. sunlight_propagates = true,
  602. light_source = 10,
  603. on_timer = function (pos, elapsed)
  604. if smartshop.mesecon then
  605. mesecon.receptor_off(pos)
  606. end
  607. return false
  608. end,
  609. tube = {insert_object = function(pos, node, stack, direction)
  610. local meta = minetest.get_meta(pos)
  611. local inv = meta:get_inventory()
  612. local added = inv:add_item("main", stack)
  613. return added
  614. end,
  615. can_insert = function(pos, node, stack, direction)
  616. local meta = minetest.get_meta(pos)
  617. local inv = meta:get_inventory()
  618. return inv:room_for_item("main", stack)
  619. end,
  620. input_inventory = "main",
  621. connect_sides = {left = 1, right = 1, front = 1, back = 1, top = 1, bottom = 1}},
  622. after_place_node = function(pos, placer)
  623. local meta=minetest.get_meta(pos)
  624. local name=placer:get_player_name()
  625. meta:set_string("owner",name)
  626. meta:set_string("infotext", "Wifi storage by: " .. name)
  627. end,
  628. on_construct = function(pos)
  629. local meta=minetest.get_meta(pos)
  630. meta:get_inventory():set_size("main", 60)
  631. meta:set_int("mesein",0)
  632. meta:set_string("title","wifi" .. math.random(1,999))
  633. end,
  634. on_rightclick = function(pos, node, player, itemstack, pointed_thing)
  635. smartshop.showform2(pos,player)
  636. end,
  637. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  638. if stack:get_wear()==0 and (minetest.get_meta(pos):get_string("owner")==player:get_player_name() or minetest.check_player_privs(player:get_player_name(), {protection_bypass=true})) then
  639. return stack:get_count()
  640. end
  641. return 0
  642. end,
  643. allow_metadata_inventory_take = function(pos, listname, index, stack, player)
  644. if minetest.get_meta(pos):get_string("owner")==player:get_player_name() or minetest.check_player_privs(player:get_player_name(), {protection_bypass=true}) then
  645. return stack:get_count()
  646. end
  647. return 0
  648. end,
  649. can_dig = function(pos, player)
  650. local meta=minetest.get_meta(pos)
  651. local inv=meta:get_inventory()
  652. local p=player:get_player_name()
  653. if (meta:get_string("owner")==p or minetest.check_player_privs(p, {protection_bypass=true})) and inv:is_empty("main") or meta:get_string("owner")=="" then
  654. return true
  655. end
  656. end,
  657. })