flight.lua 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. local flight_secs = minetest.settings:get("ethereal.flightpotion_duration") or (5 * 60)
  2. local timer_check = 5 -- seconds per check
  3. local S = ethereal.intllib
  4. local is_50 = minetest.has_feature("object_use_texture_alpha")
  5. -- disable flight
  6. local function set_flight(user, set)
  7. if not user then return end
  8. local name = user:get_player_name()
  9. local privs = minetest.get_player_privs(name)
  10. privs.fly = set
  11. minetest.set_player_privs(name, privs)
  12. -- when 'fly' removed set timer to temp value for checks
  13. if not set then
  14. if is_50 then
  15. local meta = user:get_meta() ; if not meta then return end
  16. meta:set_string("ethereal:fly_timer", "-99")
  17. else
  18. user:set_attribute("ethereal:fly_timer", "-99")
  19. end
  20. end
  21. end
  22. -- after function
  23. local function ethereal_set_flight(user)
  24. if not user then return end
  25. local timer, meta
  26. if is_50 then
  27. meta = user:get_meta() ; if not meta then return end
  28. timer = tonumber(meta:get_string("ethereal:fly_timer") or "") or 0
  29. else
  30. timer = tonumber(user:get_attribute("ethereal:fly_timer") or "") or 0
  31. end
  32. if not timer then return end -- nil check
  33. -- if timer ran out then remove 'fly' privelage
  34. if timer <= 0 and timer ~= -99 then
  35. set_flight(user, nil)
  36. return
  37. end
  38. local name = user:get_player_name()
  39. local privs = minetest.get_player_privs(name)
  40. -- have we already applied 'fly' privelage?
  41. if not privs.fly then
  42. set_flight(user, true)
  43. end
  44. -- handle timer
  45. timer = timer - timer_check
  46. -- show expiration message and play sound
  47. if timer < 10 then
  48. minetest.chat_send_player(name,
  49. minetest.get_color_escape_sequence("#ff5500")
  50. .. S("Flight timer about to expire!"))
  51. minetest.sound_play("default_dig_dig_immediate",
  52. {to_player = name, gain = 1.0}, true)
  53. end
  54. -- store new timer setting
  55. if is_50 then
  56. meta:set_string("ethereal:fly_timer", timer)
  57. else
  58. user:set_attribute("ethereal:fly_timer", timer)
  59. end
  60. minetest.after(timer_check, function()
  61. ethereal_set_flight(user)
  62. end)
  63. end
  64. -- on join / leave
  65. minetest.register_on_joinplayer(function(player)
  66. if not player then return end
  67. local timer, meta
  68. if is_50 then
  69. meta = player:get_meta() ; if not meta then return end
  70. timer = tonumber(meta:get_string("ethereal:fly_timer") or "") or 0
  71. else
  72. timer = tonumber(player:get_attribute("ethereal:fly_timer") or "") or 0
  73. end
  74. if timer and timer == -99 then
  75. return
  76. end
  77. local privs = minetest.get_player_privs(player:get_player_name())
  78. if privs.fly and timer then
  79. minetest.after(timer_check, function()
  80. ethereal_set_flight(player)
  81. end)
  82. end
  83. end)
  84. -- potion item
  85. minetest.register_node("ethereal:flight_potion", {
  86. description = S("Flight Potion"),
  87. drawtype = "plantlike",
  88. tiles = {"ethereal_flight_potion.png"},
  89. inventory_image = "ethereal_flight_potion.png",
  90. wield_image = "ethereal_flight_potion.png",
  91. paramtype = "light",
  92. sunlight_propagates = true,
  93. walkable = false,
  94. selection_box = {
  95. type = "fixed",
  96. fixed = {-0.2, -0.37, -0.2, 0.2, 0.31, 0.2}
  97. },
  98. groups = {dig_immediate = 3},
  99. sounds = default.node_sound_glass_defaults(),
  100. on_use = function(itemstack, user, pointed_thing)
  101. -- get privs
  102. local name = user:get_player_name()
  103. local privs = minetest.get_player_privs(name)
  104. local timer, meta
  105. if is_50 then
  106. meta = user:get_meta() ; if not meta then return end
  107. timer = meta:get_string("ethereal:fly_timer") or ""
  108. else
  109. timer = user:get_attribute("ethereal:fly_timer") or ""
  110. end
  111. if privs.fly then
  112. local msg = timer
  113. if timer == "" or timer == "-99" then
  114. msg = S("unlimited")
  115. end
  116. minetest.chat_send_player(name,
  117. minetest.get_color_escape_sequence("#ffff00")
  118. .. S("Flight already granted, @1 seconds left!", msg))
  119. return
  120. end
  121. if is_50 then
  122. meta:set_string("ethereal:fly_timer", flight_secs)
  123. else
  124. user:set_attribute("ethereal:fly_timer", flight_secs)
  125. end
  126. minetest.chat_send_player(name,
  127. minetest.get_color_escape_sequence("#1eff00")
  128. .. S("Flight granted, you have @1 seconds!", flight_secs))
  129. ethereal_set_flight(user)
  130. -- take item
  131. itemstack:take_item()
  132. -- return empty bottle
  133. local inv = user:get_inventory()
  134. if inv:room_for_item("main", {name = "vessels:glass_bottle"}) then
  135. user:get_inventory():add_item("main", "vessels:glass_bottle")
  136. else
  137. minetest.add_item(user:get_pos(), {name = "vessels:glass_bottle"})
  138. end
  139. return itemstack
  140. end
  141. })
  142. -- recipe
  143. minetest.register_craft({
  144. output = "ethereal:flight_potion",
  145. recipe = {
  146. {"ethereal:etherium_dust", "ethereal:etherium_dust", "ethereal:etherium_dust"},
  147. {"ethereal:etherium_dust", "ethereal:fire_dust", "ethereal:etherium_dust"},
  148. {"ethereal:etherium_dust", "vessels:glass_bottle", "ethereal:etherium_dust"}
  149. }
  150. })