sickness.lua 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. if not minetest.global_exists("portal_sickness") then portal_sickness = {} end
  2. portal_sickness.players = portal_sickness.players or {}
  3. portal_sickness.version = portal_sickness.version or 1
  4. -- Localize for performance.
  5. local math_random = math.random
  6. -- Localize.
  7. local players = portal_sickness.players
  8. local alert_color = core.get_color_escape_sequence("#ff0000")
  9. local function portal_sicken(pname, count)
  10. if count < 1 then
  11. count = 1
  12. end
  13. -- Length of sickness increases based on how many times player has teleported
  14. -- since the last sickness.
  15. local step = count * 10
  16. local msg = "# Server: <" .. rename.gpn(pname) .. "> succumbed to PORTAL SICKNESS."
  17. hb4.delayed_harm({
  18. name = pname,
  19. step = step,
  20. min = 1*500,
  21. max = 3*500,
  22. msg = msg,
  23. poison = true,
  24. done = function()
  25. portal_sickness.init_if_needed(pname)
  26. -- Don't cure player.
  27. -- Check if player is actually still sick, and hasn't died (and been
  28. -- reset) in the meantime.
  29. if players[pname].sick >= 2 then
  30. players[pname].sick = 2 -- Go back to feeling sick.
  31. portal_sickness.check_sick(pname)
  32. end
  33. end,
  34. })
  35. minetest.chat_send_all("# Server: <" .. rename.gpn(pname) .. "> has contracted portal sickness!")
  36. end
  37. local function sicken_sound(pname)
  38. minetest.after(1, function()
  39. local player = minetest.get_player_by_name(pname)
  40. if not player or not player:is_player() then
  41. return
  42. end
  43. -- Can also be used because it sounds like someone being sick.
  44. coresounds.play_death_sound(player, pname)
  45. end)
  46. end
  47. function portal_sickness.reset(pname)
  48. portal_sickness.init_if_needed(pname)
  49. players[pname].sick = 0
  50. players[pname].count = 0
  51. players[pname].time = os.time()
  52. end
  53. function portal_sickness.init_if_needed(pname)
  54. if not players[pname] then
  55. players[pname] = {
  56. count = 0,
  57. sick = 0,
  58. time = os.time(),
  59. version = portal_sickness.version,
  60. }
  61. end
  62. -- If stored data has old version, then reset it.
  63. if players[pname] then
  64. if not players[pname].version or players[pname].version < portal_sickness.version then
  65. players[pname] = {
  66. count = 0,
  67. sick = 0,
  68. time = os.time(),
  69. version = portal_sickness.version,
  70. }
  71. end
  72. end
  73. end
  74. function portal_sickness.on_use_portal(pname)
  75. local player = minetest.get_player_by_name(pname)
  76. if not player or not player:is_player() then
  77. return
  78. end
  79. sprint.set_stamina(player, 0)
  80. portal_sickness.init_if_needed(pname)
  81. local rand_time_add = (players[pname].count - 6) * 10
  82. local t1 = players[pname].time
  83. local t2 = os.time()
  84. local mt = math_random(30, math_random(40, 140 + rand_time_add))
  85. local max_time = math_random(60*10, 60*20)
  86. -- If player waits long enough, they don't sicken, but neither does the
  87. -- sickness go away!
  88. if (t2 - t1) < max_time then
  89. if players[pname].sick == 2 then
  90. players[pname].sick = 3
  91. portal_sicken(pname, players[pname].count)
  92. return
  93. elseif players[pname].sick >= 3 then
  94. -- Teleporting while throwing up? Just die already!
  95. player:set_hp(0, {reason="portal"})
  96. minetest.chat_send_all("# Server: <" .. rename.gpn(pname) .. "> succumbed to PORTAL SICKNESS.")
  97. return
  98. end
  99. end
  100. if (t2 - t1) < mt then
  101. players[pname].count = players[pname].count + 1
  102. local max = 8 - players[pname].count
  103. if max < 1 then
  104. max = 1
  105. end
  106. if (math_random(1, max) == 1) or players[pname].sick == 1 then
  107. if players[pname].sick == 0 then
  108. minetest.chat_send_player(pname, alert_color .. "# Server: WARNING: You are feeling queasy!")
  109. players[pname].sick = 1
  110. elseif players[pname].sick == 1 then
  111. minetest.chat_send_player(pname, alert_color .. "# Server: WARNING: You have contracted PORTAL SICKNESS! You must sleep it off to be cured.")
  112. players[pname].sick = 2
  113. sicken_sound(pname)
  114. end
  115. end
  116. else
  117. portal_sickness.check_sick(pname)
  118. end
  119. -- Update time since last use of portal.
  120. players[pname].time = t2
  121. end
  122. function portal_sickness.on_use_bed(pname)
  123. portal_sickness.init_if_needed(pname)
  124. local was_ill = (players[pname].count > 0 or players[pname].sick > 0)
  125. players[pname].count = 0
  126. players[pname].sick = 0
  127. players[pname].time = os.time()
  128. if was_ill then
  129. minetest.after(2, function()
  130. minetest.chat_send_player(pname, "# Server: You feel refreshed. The queasiness from portal sickness has gone.")
  131. end)
  132. end
  133. end
  134. function portal_sickness.on_die_player(pname)
  135. portal_sickness.reset(pname)
  136. end
  137. function portal_sickness.check_sick(pname)
  138. minetest.after(2, function()
  139. local player = minetest.get_player_by_name(pname)
  140. if not player or not player:is_player() then
  141. return
  142. end
  143. portal_sickness.init_if_needed(pname)
  144. if players[pname].sick >= 2 then
  145. minetest.chat_send_player(pname, alert_color .. "# Server: WARNING: You still have PORTAL SICKNESS!")
  146. elseif players[pname].sick == 1 then
  147. minetest.chat_send_player(pname, alert_color .. "# Server: WARNING: You are still feeling queasy!")
  148. end
  149. end)
  150. end
  151. function portal_sickness.is_sick_or_queasy(pname)
  152. portal_sickness.init_if_needed(pname)
  153. if players[pname].sick >= 2 then
  154. return true
  155. elseif players[pname].sick == 1 then
  156. return true
  157. end
  158. end
  159. function portal_sickness.on_join_player(pname)
  160. portal_sickness.check_sick(pname)
  161. end
  162. function portal_sickness.on_leave_player(pname)
  163. portal_sickness.init_if_needed(pname)
  164. -- Only erase data if player is not sick or queasy.
  165. -- Once player gets sick, relogging doesn't remove the sickness!
  166. if players[pname].sick == 0 then
  167. players[pname] = nil
  168. end
  169. end
  170. if not portal_sickness.registered then
  171. minetest.register_on_joinplayer(function(player)
  172. portal_sickness.on_join_player(player:get_player_name())
  173. end)
  174. minetest.register_on_leaveplayer(function(player)
  175. portal_sickness.on_leave_player(player:get_player_name())
  176. end)
  177. portal_sickness.registered = true
  178. end