items.lua 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. --------------------------------------------------------------------------------
  2. -- Special item that lets you revive a dead player in-place, provided they have
  3. -- not pressed the "respawn" button. Remember gents, there's no such thing as
  4. -- "dead". There's only "mostly dead" and "mostly dead" means "slightly alive"!
  5. local function scepter_revive_player(tref, tname, pname, pos)
  6. if pos then
  7. rc.notify_realm_update(tref, pos)
  8. tref:set_pos(pos)
  9. end
  10. preload_tp.spawn_spinup_particles(tref:get_pos(), 1)
  11. ambiance.sound_play("nether_portal_usual", tref:get_pos(), 1.0, 30)
  12. local hp_max = pova.get_active_modifier(tref, "properties").hp_max
  13. tref:set_hp(hp_max, {reason="revive"})
  14. tref:get_meta():set_int("abyss_return_midfeld", 0)
  15. -- DON'T run the bed respawn code, we want to keep player in place.
  16. bones.nohack.on_respawnplayer(tref)
  17. sprint.on_respawnplayer(tref)
  18. minetest.close_formspec(tname, "") -- Close the respawn formspec.
  19. ambiance.sound_play("default_cool_lava", tref:get_pos(), 1.0, 32)
  20. minetest.chat_send_player(pname, "# Server: You revived <" .. rename.gpn(tname) .. ">.")
  21. minetest.chat_send_player(tname, "# Server: You were revived by <" .. rename.gpn(pname) .. ">.")
  22. end
  23. local function scepter_hit_bones(itemstack, user, pt)
  24. --minetest.log('scepter hit bones')
  25. -- Collect information.
  26. local pname = user:get_player_name()
  27. local pos = pt.under
  28. local node = minetest.get_node(pos)
  29. local meta = minetest.get_meta(pos)
  30. local owner = meta:get_string("owner")
  31. local tref = minetest.get_player_by_name(owner)
  32. local bones_death_time = tonumber(meta:get_string("death_time")) or 0
  33. ambiance.sound_play("nether_extract_blood", pos, 1.0, 30)
  34. -- Player must be logged in.
  35. if not tref or not tref:is_player() then
  36. --minetest.log('ghost not logged in')
  37. return
  38. end
  39. -- Player must be dead.
  40. if tref:get_hp() > 0 then
  41. --minetest.log('ghost not dead')
  42. return
  43. end
  44. local tname = tref:get_player_name()
  45. local player_meta = tref:get_meta()
  46. local player_death_time = tonumber(player_meta:get_string("last_death_time")) or 0
  47. local player_bones_time = tonumber(player_meta:get_string("last_bones_time")) or 0
  48. local player_bones_pos = minetest.string_to_pos(player_meta:get_string("last_bones_pos"))
  49. local player_respawn_time = tonumber(player_meta:get_string("last_respawn_time")) or 0
  50. -- Determine if player can be revived from these bones.
  51. -- Time must be valid.
  52. if bones_death_time == 0 or player_death_time == 0 or player_bones_time == 0 then
  53. --minetest.log('times not valid')
  54. return
  55. end
  56. -- Player's last bones position must be known.
  57. if not player_bones_pos then
  58. --minetest.log('bone pos not valid')
  59. return
  60. end
  61. -- Bones time must match player's last death time.
  62. if bones_death_time ~= player_death_time then
  63. --minetest.log('death times don\'t match')
  64. return
  65. end
  66. -- Bones position must match player's last bones position.
  67. if not vector.equals(pos, player_bones_pos) then
  68. --minetest.log('bone positions don\'t match')
  69. return
  70. end
  71. -- Player's last respawn must be prior to their last death time.
  72. if player_respawn_time >= player_death_time then
  73. --minetest.log('respawn time too soon')
  74. return
  75. end
  76. -- Player's last bones time must match their last death time.
  77. if player_bones_time ~= player_death_time then
  78. --minetest.log('bones time doesn\'t match death time')
  79. return
  80. end
  81. -- Player's last respawn must be older than these bones.
  82. if player_respawn_time >= bones_death_time then
  83. --minetest.log('player respawned already')
  84. return
  85. end
  86. -- Everything looks in order. Revive player.
  87. scepter_revive_player(tref, tname, pname, pos)
  88. end
  89. local function scepter_hit_player(itemstack, user, pt)
  90. local pname = user:get_player_name()
  91. local tref = pt.ref
  92. ambiance.sound_play("nether_extract_blood", tref:get_pos(), 1.0, 30)
  93. local hp = tref:get_hp()
  94. local tname = tref:get_player_name()
  95. if hp <= 0 and pname ~= tname then
  96. -- Target is another player and player is dead. Revive player.
  97. -- This will bypass the respawn code, and player should revive in place.
  98. scepter_revive_player(tref, tname, pname)
  99. end
  100. end
  101. function stoneworld.oerkki_scepter(itemstack, user, pt)
  102. if user and user:is_player() then
  103. if pt.type == "node" and minetest.get_node(pt.under).name == "bones:bones" then
  104. scepter_hit_bones(itemstack, user, pt)
  105. elseif pt.type == "object" and pt.ref and pt.ref:is_player() then
  106. scepter_hit_player(itemstack, user, pt, nil)
  107. end
  108. end
  109. end
  110. -- They say the elite oerkki used it when they wanted to interrogate a prisoner
  111. -- harshly. But it can be repurposed for teamwork assistance.
  112. minetest.register_tool("stoneworld:oerkki_scepter", {
  113. description = "Interrogation Prod",
  114. inventory_image = "stoneworld_oerkki_staff.png",
  115. -- Tools with dual-use functions MUST put the secondary use in this callback,
  116. -- otherwise normal punches do not work!
  117. on_place = stoneworld.oerkki_scepter,
  118. on_secondary_use = stoneworld.oerkki_scepter,
  119. -- Using it on a live player? >:)
  120. -- Damage info is stored by sysdmg.
  121. tool_capabilities = {
  122. full_punch_interval = 3.0,
  123. },
  124. })
  125. -- Not craftable. Item is loot ONLY.
  126. --------------------------------------------------------------------------------