flame_staff.lua 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. function obsidian_gateway.on_flamestaff_use(item, user, pt)
  2. if pt.type ~= "node" then
  3. return
  4. end
  5. if not user:is_player() then
  6. return
  7. end
  8. local pname = user:get_player_name()
  9. ambiance.sound_play("fire_flint_and_steel", pt.above, 0.7, 10)
  10. -- Punched node must be one of these.
  11. do
  12. local nn = minetest.get_node(pt.under).name
  13. if nn ~= "default:obsidian" and
  14. nn ~= "griefer:grieferstone" and
  15. nn ~= "cavestuff:dark_obsidian" and
  16. nn ~= "cavestuff:glow_obsidian" then
  17. return
  18. end
  19. end
  20. local pos = pt.under
  21. local success, origin, airpoints, northsouth, ns_key, playerorigin =
  22. obsidian_gateway.find_gate(pos)
  23. if not success then
  24. return
  25. end
  26. -- Using the staff on an uninitialized gate does nothing.
  27. do
  28. local meta = minetest.get_meta(origin)
  29. local target = meta:get_string("obsidian_gateway_destination_" .. ns_key)
  30. local dest = minetest.string_to_pos(target)
  31. if not dest then
  32. return
  33. end
  34. end
  35. -- Add/update sound beacon.
  36. ambiance.spawn_sound_beacon("soundbeacon:gate", origin, 20, 1)
  37. ambiance.replay_nearby_sound_beacons(origin, 6)
  38. if sheriff.is_cheater(pname) then
  39. if sheriff.punish_probability(pname) then
  40. sheriff.punish_player(pname)
  41. return
  42. end
  43. end
  44. local do_effect = false
  45. do
  46. local meta = item:get_meta()
  47. if meta:get_string("gate1") == "" then
  48. meta:set_string("gate1", minetest.pos_to_string(playerorigin))
  49. meta:set_string("description", "Flame Staff (Partially Linked)")
  50. do_effect = true
  51. elseif meta:get_string("gate2") == "" then
  52. meta:set_string("gate2", minetest.pos_to_string(playerorigin))
  53. meta:set_string("description", "Flame Staff (Linked)")
  54. do_effect = true
  55. end
  56. end
  57. if do_effect then
  58. local p = pt.above
  59. minetest.sound_play("default_item_smoke", {
  60. pos = pos,
  61. max_hear_distance = 8,
  62. }, true)
  63. minetest.add_particlespawner({
  64. amount = 3,
  65. time = 0.1,
  66. minpos = {x = p.x - 0.1, y = p.y + 0.1, z = p.z - 0.1 },
  67. maxpos = {x = p.x + 0.1, y = p.y + 0.2, z = p.z + 0.1 },
  68. minvel = {x = 0, y = 2.5, z = 0},
  69. maxvel = {x = 0, y = 2.5, z = 0},
  70. minacc = {x = -0.15, y = -0.02, z = -0.15},
  71. maxacc = {x = 0.15, y = -0.01, z = 0.15},
  72. minexptime = 4,
  73. maxexptime = 6,
  74. minsize = 5,
  75. maxsize = 5,
  76. collisiondetection = true,
  77. texture = "default_item_smoke.png"
  78. })
  79. end
  80. -- Success, but do not continue to the teleport logic.
  81. if do_effect then
  82. return item
  83. end
  84. -- Player must be standing in the gate.
  85. do
  86. local posunder = utility.node_under_pos(user:get_pos())
  87. local namunder = minetest.get_node(posunder).name
  88. if namunder ~= "default:obsidian" and
  89. namunder ~= "griefer:grieferstone" and
  90. namunder ~= "cavestuff:dark_obsidian" and
  91. namunder ~= "cavestuff:glow_obsidian" then
  92. return
  93. end
  94. end
  95. do
  96. local meta = item:get_meta()
  97. local spos1 = meta:get_string("gate1")
  98. local spos2 = meta:get_string("gate2")
  99. if spos1 == "" or spos2 == "" then
  100. return
  101. end
  102. local tar1 = minetest.string_to_pos(spos1)
  103. local tar2 = minetest.string_to_pos(spos2)
  104. if not tar1 or not tar2 then
  105. return
  106. end
  107. -- If the linked targets are the same, nothing happens.
  108. if vector.equals(tar1, tar2) then
  109. return
  110. end
  111. -- If either target is in the Abyss, nothing happens.
  112. if rc.current_realm_at_pos(tar1) == "abyss" or
  113. rc.current_realm_at_pos(tar2) == "abyss" then
  114. return
  115. end
  116. -- If player activates gate #2 first, then pretend we didn't notice and just
  117. -- swap the datums.
  118. if vector.equals(playerorigin, tar2) then
  119. local tmp
  120. tmp = tar1
  121. tar1 = tar2
  122. tar2 = tmp
  123. meta:set_string("gate1", spos2)
  124. meta:set_string("gate2", spos1)
  125. tmp = spos1
  126. spos1 = spos2
  127. spos2 = tmp
  128. -- Meta changes do not take effect until we return the itemstack.
  129. end
  130. -- Player has activated gate #1.
  131. -- Send them to the Abyss!
  132. if vector.equals(playerorigin, tar1) then
  133. -- The fixed coordinates of a hidden cave tunnel which links to a dungeon.
  134. local hidden_spawn = {
  135. x = -9265,
  136. y = 4076,
  137. z = 5819,
  138. }
  139. preload_tp.execute({
  140. player_name = pname,
  141. target_position = hidden_spawn,
  142. emerge_radius = 8,
  143. particle_effects = true,
  144. -- Don't let players bring foreign objects into the Abyss.
  145. -- That could have consequences ....
  146. pre_teleport_callback = function()
  147. --bones.dump_bones(pname, true)
  148. --bones.last_known_death_locations[pname] = nil -- Fake death.
  149. --local pref = minetest.get_player_by_name(pname)
  150. --pref:set_hp(pref:get_properties().hp_max)
  151. coresounds.play_death_sound(user, pname)
  152. end,
  153. post_teleport_callback = function()
  154. portal_sickness.on_use_portal(pname)
  155. end,
  156. })
  157. -- If the staff was already used to teleport to the Abyss once, then a
  158. -- second use breaks it.
  159. if meta:get_int("times_used") >= 1 then
  160. item:take_item()
  161. else
  162. meta:set_int("times_used", 1)
  163. end
  164. -- The metadata will have been updated if we swapped datums.
  165. return item
  166. end
  167. -- Player has activated a gate in the Abyss. Send then back.
  168. -- Also destroy the flame staff.
  169. if rc.current_realm_at_pos(origin) == "abyss" then
  170. preload_tp.execute({
  171. player_name = pname,
  172. target_position = tar2,
  173. emerge_radius = 16,
  174. particle_effects = true,
  175. pre_teleport_callback = function()
  176. end,
  177. post_teleport_callback = function()
  178. portal_sickness.on_use_portal(pname)
  179. end,
  180. })
  181. ambiance.sound_play("default_tool_breaks", pos, 1.0, 10)
  182. item:take_item()
  183. return item
  184. end
  185. end
  186. end