init.lua 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. bandages = bandages or {}
  2. bandages.modpath = minetest.get_modpath("bandages")
  3. bandages.players = bandages.players or {}
  4. if minetest.get_modpath("reload") then
  5. local c = "bandages:core"
  6. local f = bandages.modpath .. "/init.lua"
  7. if not reload.file_registered(c) then
  8. reload.register_file(c, f, false)
  9. end
  10. end
  11. bandages.movement_limit_from_level = function(level)
  12. if level == 1 then
  13. return 20
  14. elseif level == 2 then
  15. return 5
  16. elseif level == 3 then
  17. return 2
  18. end
  19. return 0
  20. end
  21. bandages.hp_from_level = function(level)
  22. if level == 1 then
  23. return 2
  24. elseif level == 2 then
  25. return 3
  26. elseif level == 3 then
  27. return 6
  28. end
  29. return 0
  30. end
  31. bandages.delay_from_level = function(level)
  32. if level == 1 then
  33. return 1.5
  34. elseif level == 2 then
  35. return 2.0
  36. elseif level == 3 then
  37. return 2.5
  38. end
  39. return 0
  40. end
  41. bandages.target_not_player = function(pname)
  42. minetest.chat_send_player(pname, "# Server: Target is not a player.")
  43. --easyvend.sound_error(pname)
  44. end
  45. bandages.target_not_hurt = function(pname, tname)
  46. minetest.chat_send_player(pname, "# Server: Player <" .. rename.gpn(tname) .. "> is not wounded.")
  47. --easyvend.sound_error(pname)
  48. end
  49. bandages.player_not_hurt = function(pname)
  50. minetest.chat_send_player(pname, "# Server: You are not harmed.")
  51. --easyvend.sound_error(pname)
  52. end
  53. bandages.player_bandages_self = function(pname, hp, hp_max)
  54. minetest.chat_send_player(pname, "# Server: You use bandages on yourself. Your health is now " .. hp .. "/" .. hp_max .. " HP.")
  55. end
  56. bandages.target_is_dead = function(pname, tname)
  57. minetest.chat_send_player(pname, "# Server: Player <" .. rename.gpn(tname) .. "> is dead!")
  58. --easyvend.sound_error(pname)
  59. end
  60. bandages.player_is_dead = function(pname)
  61. minetest.chat_send_player(pname, "# Server: You are dead!")
  62. --easyvend.sound_error(pname)
  63. end
  64. bandages.player_bandages_target = function(pname, tname, hp, hp_max)
  65. minetest.chat_send_player(tname, "# Server: Player <" .. rename.gpn(pname) .. "> used a bandage on you.")
  66. minetest.chat_send_player(pname, "# Server: <" .. rename.gpn(tname) .. ">'s health improves to " .. hp .. "/" .. hp_max .. " HP.")
  67. end
  68. bandages.medkit_already_in_use = function(pname)
  69. minetest.chat_send_player(pname, "# Server: You are already using a medkit; wait to be done.")
  70. --easyvend.sound_error(pname)
  71. end
  72. bandages.player_moved_too_much = function(pname)
  73. minetest.chat_send_player(pname, "# Server: You must hold still while using a medkit!")
  74. --easyvend.sound_error(pname)
  75. end
  76. bandages.target_moved_too_much = function(pname, tname)
  77. minetest.chat_send_player(pname, "# Server: Player <" .. rename.gpn(tname) .. "> must hold still for you to use medkit!")
  78. minetest.chat_send_player(tname, "# Server: Player <" .. rename.gpn(pname) .. "> is trying to use a medkit on you; hold still!")
  79. --easyvend.sound_error(pname)
  80. end
  81. bandages.get_sound_range_from_level = function(level)
  82. if level == 1 then
  83. return 8
  84. elseif level == 2 then
  85. return 16
  86. elseif level == 3 then
  87. return 24
  88. end
  89. return 0
  90. end
  91. bandages.get_sound_gain_from_level = function(level)
  92. if level == 1 then
  93. return 0.5
  94. elseif level == 2 then
  95. return 0.7
  96. elseif level == 3 then
  97. return 1.0
  98. end
  99. return 0
  100. end
  101. bandages.play_sound_effects = function(pos, level)
  102. local range = bandages.get_sound_range_from_level(level)
  103. local gain = bandages.get_sound_gain_from_level(level)
  104. ambiance.sound_play("bandages_bandaging", pos, gain, range)
  105. -- Increase length of sound effect for higher levels.
  106. if level >= 2 then
  107. minetest.after(1.0, function()
  108. ambiance.sound_play("bandages_bandaging", pos, gain, range)
  109. end)
  110. end
  111. if level >= 3 then
  112. minetest.after(2.0, function()
  113. ambiance.sound_play("bandages_bandaging", pos, gain, range)
  114. end)
  115. end
  116. end
  117. bandages.get_max_damage_for_level = function(level, hp, hp_max)
  118. if level == 3 then
  119. return 1
  120. elseif level == 2 then
  121. return (hp_max / 3)
  122. elseif level == 1 then
  123. return (hp_max / 5) * 4
  124. end
  125. return 0
  126. end
  127. bandages.target_too_hurt = function(pname, tname, level)
  128. minetest.chat_send_player(pname, "# Server: Player <" .. rename.gpn(tname) .. "> is too severely hurt for a level " .. level .. " medkit.")
  129. --easyvend.sound_error(pname)
  130. end
  131. bandages.player_too_hurt = function(pname, level)
  132. minetest.chat_send_player(pname, "# Server: You are too severely hurt for a level " .. level .. " medkit.")
  133. --easyvend.sound_error(pname)
  134. end
  135. bandages.use_bandage = function(itemstack, user, pointed_thing, level)
  136. if not user or not user:is_player() then return end
  137. local pname = user:get_player_name()
  138. if pointed_thing.type == "object" then
  139. local target = pointed_thing.ref
  140. if not target or not target:is_player() then
  141. return bandages.target_not_player(pname)
  142. end
  143. local tname = target:get_player_name()
  144. local hp = target:get_hp()
  145. local hp_max = target:get_properties().hp_max
  146. if hp >= hp_max then
  147. return bandages.target_not_hurt(pname, tname)
  148. end
  149. if hp <= 0 then
  150. return bandages.target_is_dead(pname, tname)
  151. end
  152. if hp < bandages.get_max_damage_for_level(level, hp, hp_max) then
  153. return bandages.target_too_hurt(pname, tname, level)
  154. end
  155. if bandages.players[pname] or bandages.players[tname] then
  156. return bandages.medkit_already_in_use(pname)
  157. end
  158. bandages.play_sound_effects(target:get_pos(), level)
  159. bandages.players[tname] = {pos=target:get_pos()}
  160. bandages.players[pname] = {pos=user:get_pos()}
  161. minetest.after(bandages.delay_from_level(level), function()
  162. local pos = bandages.players[tname].pos
  163. bandages.players[tname] = nil
  164. bandages.players[pname] = nil
  165. local target = minetest.get_player_by_name(tname)
  166. if not target or not target:is_player() then return end
  167. if vector.distance(target:get_pos(), pos) > bandages.movement_limit_from_level(level) then
  168. return bandages.target_moved_too_much(pname, tname)
  169. end
  170. -- Don't heal target if already dead.
  171. -- This solves an exploit people have found.
  172. if target:get_hp() == 0 then return end
  173. target:set_hp(hp + bandages.hp_from_level(level))
  174. bandages.player_bandages_target(pname, tname, target:get_hp(), hp_max)
  175. end)
  176. itemstack:take_item()
  177. return itemstack
  178. else
  179. -- Otherwise, try to heal self.
  180. local hp = user:get_hp()
  181. local hp_max = user:get_properties().hp_max
  182. if hp >= hp_max then
  183. return bandages.player_not_hurt(pname)
  184. end
  185. if hp <= 0 then
  186. return bandages.player_is_dead(pname)
  187. end
  188. if hp < bandages.get_max_damage_for_level(level, hp, hp_max) then
  189. return bandages.player_too_hurt(pname, level)
  190. end
  191. if bandages.players[pname] then
  192. return bandages.medkit_already_in_use(pname)
  193. end
  194. bandages.play_sound_effects(user:get_pos(), level)
  195. bandages.players[pname] = {pos=user:get_pos()}
  196. minetest.after(bandages.delay_from_level(level), function()
  197. local pos = bandages.players[pname].pos
  198. bandages.players[pname] = nil
  199. local user = minetest.get_player_by_name(pname)
  200. if not user or not user:is_player() then return end
  201. if vector.distance(user:get_pos(), pos) > bandages.movement_limit_from_level(level) then
  202. return bandages.player_moved_too_much(pname)
  203. end
  204. -- Don't heal user if already dead.
  205. -- This solves an exploit people have found.
  206. if user:get_hp() == 0 then return end
  207. user:set_hp(hp + bandages.hp_from_level(level))
  208. bandages.player_bandages_self(pname, user:get_hp(), hp_max)
  209. end)
  210. itemstack:take_item()
  211. return itemstack
  212. end
  213. end
  214. -- Execute registrations once only.
  215. if not bandages.registered then
  216. minetest.register_craftitem("bandages:bandage_1", {
  217. description = "Simple Bandage\n\nHeals light scrapes and scratches.\nUse on yourself or another.",
  218. inventory_image = "bandage_1.png",
  219. on_use = function(itemstack, user, pointed_thing)
  220. return bandages.use_bandage(itemstack, user, pointed_thing, 1)
  221. end,
  222. })
  223. minetest.register_craftitem("bandages:bandage_2", {
  224. description = "Basic Medkit\n\nHeals wounds.\nUse on yourself or another.",
  225. inventory_image = "bandage_2.png",
  226. on_use = function(itemstack, user, pointed_thing)
  227. return bandages.use_bandage(itemstack, user, pointed_thing, 2)
  228. end,
  229. })
  230. minetest.register_craftitem("bandages:bandage_3", {
  231. description = "Trauma Medkit\n\nHeals player from severe wounds.\nUse on yourself or another.",
  232. inventory_image = "bandage_3.png",
  233. on_use = function(itemstack, user, pointed_thing)
  234. return bandages.use_bandage(itemstack, user, pointed_thing, 3)
  235. end,
  236. })
  237. minetest.register_craft({
  238. output = 'bandages:bandage_1 2',
  239. recipe = {
  240. {'default:paper', 'default:paper', 'default:paper'},
  241. }
  242. })
  243. minetest.register_craft({
  244. output = 'bandages:bandage_2 2',
  245. recipe = {
  246. {'default:paper', 'wool:white', 'default:paper'},
  247. }
  248. })
  249. minetest.register_craft({
  250. output = 'bandages:bandage_3 2',
  251. recipe = {
  252. {'default:paper', 'wool:green', 'default:paper'},
  253. }
  254. })
  255. bandages.registered = true
  256. end