sickness.lua 5.4 KB

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