items.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. local stick_knockback = sumo.stick_knockback --multiplier for how hard the stick hits
  2. local stick_vault_reach = sumo.stick_vault_reach -- how close to the pointed node must the player be to vault
  3. local stick_vault_timeout = sumo.stick_vault_timeout --(float)--in seconds
  4. local allow_swap_distance = sumo.allow_swap_distance -- if an opponent is within this distance, then if the player uses the pushstick with the shift key pressed, the players switch positions.
  5. local stick_pointing_distance = sumo.stick_pointing_distance
  6. local stick_push_timeout = sumo.stick_push_timeout --(float)--in seconds
  7. sumo.timeouts={}
  8. sumo.jumpouts = {}
  9. sumo.push_hud = {}
  10. sumo.jump_hud = {}
  11. minetest.register_craftitem("sumo:pushstick", {
  12. description = "Push Stick",
  13. inventory_image = "default_stick.png",
  14. stack_max = 1,
  15. wield_scale = {x = 2, y = 2, z = 2},
  16. on_drop = function() end,
  17. range = stick_pointing_distance,
  18. on_use = function(itemstack, user, pointed_thing)
  19. --local imeta = itemstack:get_meta()
  20. local p_name = user:get_player_name()
  21. local last_push_time = sumo.timeouts[p_name] or 0.0
  22. local current_time = minetest.get_us_time()/1000000.0
  23. local time_from_last_push = current_time-last_push_time
  24. local force = 1 --hey, lets give the jitter-clickers "something" but not much: force of 2 is tiny, which makes jitterclicking completely ineffectual
  25. if time_from_last_push > stick_push_timeout then
  26. local time_factor = 0
  27. if time_from_last_push >= 0.3 and time_from_last_push < 0.4 then
  28. time_factor = 4
  29. elseif time_from_last_push >= 0.4 and time_from_last_push < 0.5 then
  30. time_factor = 9
  31. elseif time_from_last_push >= 0.5 and time_from_last_push < 0.7 then
  32. time_factor = 14
  33. elseif time_from_last_push > 0.7 then
  34. time_factor = 20
  35. elseif time_from_last_push > 2.0 then
  36. time_factor = 25
  37. end
  38. force = stick_knockback + time_factor
  39. end
  40. local sound = 'swish'..math.random(1,4)
  41. minetest.sound_play(sound, {
  42. pos = user:get_pos(),
  43. max_hear_distance = 5,
  44. gain = 10.0,
  45. })
  46. if pointed_thing == nil then return end
  47. if pointed_thing.type == 'node' then return end
  48. if not pointed_thing.type == 'object' then return end
  49. if pointed_thing.type == 'object' then
  50. --this only works on players
  51. if minetest.is_player(pointed_thing.ref) == true then
  52. local dir = user:get_look_dir()
  53. local keys = user:get_player_control()
  54. local swap = false
  55. local hitted_pos = pointed_thing.ref:get_pos()
  56. local hitter_pos = user:get_pos()
  57. if keys.sneak and vector.distance(hitted_pos,hitter_pos) < allow_swap_distance then --swap if pressing shift
  58. swap = true
  59. user:move_to(hitted_pos, true)
  60. local pointed_name = pointed_thing.ref:get_player_name()
  61. if not sumo.invincible[pointed_name] then
  62. pointed_thing.ref:move_to(hitter_pos, true)
  63. pointed_thing.ref:add_player_velocity(vector.multiply({x = -dir.x, y = dir.y, z= -dir.z}, (force + 1)* 0.6 )) --switch positions, and throw the target with 0.6X normal force
  64. sumo.timeouts[p_name] = current_time
  65. local sound = 'swish'..math.random(1,4)
  66. minetest.sound_play(sound, {
  67. to_player = pointed_thing.ref:get_player_name(),
  68. pos = user:get_pos(),
  69. gain = 10.0,
  70. })
  71. end
  72. else --not pressing shift, add velocity "force"
  73. local pointed_name = pointed_thing.ref:get_player_name()
  74. if not sumo.invincible[pointed_name] then
  75. pointed_thing.ref:add_player_velocity(vector.multiply(dir, force))
  76. sumo.timeouts[p_name] = current_time
  77. local sound = 'thwack2' --TODO: get the other 2 thwack souds into the game (where did they go anyways?!)
  78. minetest.sound_play(sound, {
  79. pos = user:get_pos(),
  80. max_hear_distance = 10,
  81. gain = 10.0,
  82. })
  83. minetest.sound_play(sound, {
  84. to_player = pointed_thing.ref:get_player_name(),
  85. pos = user:get_pos(),
  86. gain = 10.0,
  87. })
  88. local sound = 'hurt'..math.random(1,2)
  89. minetest.sound_play(sound, {
  90. to_player = pointed_thing.ref:get_player_name(),
  91. pos = user:get_pos(),
  92. gain = 10.0,
  93. })
  94. end
  95. end
  96. end
  97. end
  98. end,
  99. on_place = function(itemstack, placer, pointed_thing)
  100. local p_name = placer:get_player_name()
  101. local last_jump_time = sumo.jumpouts[p_name] or 0.0
  102. local current_time = minetest.get_us_time()/1000000.0 --microsec converted to sec
  103. local time_from_last_jump = current_time-last_jump_time
  104. if pointed_thing.type == 'node' then
  105. if vector.distance(pointed_thing.under, placer:get_pos()) < stick_vault_reach then
  106. if last_jump_time == 0.0 or time_from_last_jump >= stick_vault_timeout then
  107. local lookvect = placer:get_look_dir()
  108. local pushvect = vector.normalize( {x=lookvect.x, z=lookvect.z, y= math.sqrt(1-(lookvect.y*lookvect.y))})
  109. --gives a unit vector that is 90 deg offset in the vert direction
  110. local force = 10 * vector.length(vector.normalize( {x=lookvect.x, z=lookvect.z, y= 0}))
  111. sumo.jumpouts[p_name] = current_time
  112. placer:add_player_velocity(vector.multiply(pushvect, force))
  113. --update the staff time for next check
  114. local sound = 'jump'..math.random(1,2)
  115. minetest.sound_play(sound, {
  116. pos = placer:get_pos(),
  117. max_hear_distance = 10,
  118. gain = 10.0,
  119. })
  120. end
  121. end
  122. end
  123. end,
  124. })
  125. --HUD indicator for sumo pushstick strength (color based)
  126. minetest.register_globalstep(function(dtime)
  127. for _,player in ipairs(minetest.get_connected_players()) do
  128. local pl_name = player:get_player_name()
  129. local inv = player:get_inventory()
  130. local stack = ItemStack("sumo:pushstick")
  131. if inv:contains_item('main', stack) then
  132. --Push HUD
  133. local last_push_time = sumo.timeouts[pl_name] or 0.0
  134. local current_time = minetest.get_us_time()/1000000.0
  135. local time_from_last_push = current_time-last_push_time
  136. local push_color = "#ff000088" --bright red
  137. if time_from_last_push >= 0.3 and time_from_last_push < 0.4 then
  138. push_color = "#ff150088" --orange red
  139. elseif time_from_last_push >= 0.4 and time_from_last_push < 0.5 then
  140. push_color = "#ff330088" --orange
  141. elseif time_from_last_push >= 0.5 and time_from_last_push < 0.7 then
  142. push_color = "#f2ff0088" --yellow
  143. elseif time_from_last_push >= 0.7 then
  144. push_color = "#8cff0088" --yellow green
  145. elseif time_from_last_push >= 2.0 then
  146. push_color = "#66ff0088" --green
  147. end
  148. --Thank you, ElCeejo, for giving this HUD code that *actually* works :P
  149. if not sumo.push_hud[pl_name] then
  150. sumo.push_hud[pl_name] =player:hud_add({
  151. hud_elem_type = "image",
  152. position = {x = 0, y = 1},
  153. name = "sumo_hud_push",
  154. text = "sumo_hud_push.png^[colorize:"..push_color,
  155. scale = {x = 3, y = 3},
  156. alignment = {x = 1, y = -1},
  157. offset = {x = 5, y = -5}
  158. })
  159. else
  160. player:hud_change(sumo.push_hud[pl_name], "text", "sumo_hud_push.png^[colorize:"..push_color)
  161. end
  162. --Jump HUD
  163. local last_jump_time = sumo.jumpouts[pl_name] or 0.0
  164. local current_time = minetest.get_us_time()/1000000.0 --microsec converted to sec
  165. local time_from_last_jump = current_time-last_jump_time
  166. local jump_color = "#ff000088" --red
  167. if last_jump_time == 0.0 or time_from_last_jump >= stick_vault_timeout then --jump *would* work now
  168. jump_color = "#66ff0088" --green
  169. end
  170. if not sumo.jump_hud[pl_name] then
  171. sumo.jump_hud[pl_name] =player:hud_add({
  172. hud_elem_type = "image",
  173. position = {x = 0, y = 1},
  174. name = "sumo_hud_jump",
  175. text = "sumo_hud_jump.png^[colorize:"..jump_color,
  176. scale = {x = 3, y = 3},
  177. alignment = {x = 1, y = -1},
  178. offset = {x = 75, y = -5}
  179. })
  180. else
  181. player:hud_change(sumo.jump_hud[pl_name], "text", "sumo_hud_jump.png^[colorize:"..jump_color)
  182. end
  183. else
  184. if sumo.push_hud[pl_name] then
  185. player:hud_remove(sumo.push_hud[pl_name])
  186. sumo.push_hud[pl_name] = nil
  187. end
  188. if sumo.jump_hud[pl_name] then
  189. player:hud_remove(sumo.jump_hud[pl_name])
  190. sumo.jump_hud[pl_name] = nil
  191. end
  192. end
  193. end
  194. end)