init.lua 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. gamer = {}
  2. gamer.player_attached = {}
  3. gamer.registered_player_models = {}
  4. local file = io.open(minetest.get_worldpath() .. '/skins', 'r')
  5. if file then
  6. gamer.player_textures = minetest.deserialize(file:read('*a'))
  7. file:close()
  8. else
  9. gamer.player_textures = {}
  10. end
  11. function gamer.save_skins()
  12. local file = io.open(minetest.get_worldpath() .. '/skins', 'w')
  13. file:write(minetest.serialize(gamer.player_textures))
  14. file:close()
  15. end
  16. minetest.register_item(':', {
  17. type = 'none',
  18. wield_image = 'wieldhand.png',
  19. wield_scale = {x=1,y=1,z=2.5},
  20. range = 10,
  21. })
  22. -- Local for speed.
  23. local models = gamer.registered_player_models
  24. function gamer.player_register_model(name, def)
  25. models[name] = def
  26. end
  27. -- Default player appearance
  28. gamer.player_register_model('gamer_model.b3d', {
  29. animation_speed = 30,
  30. textures = {'gamer_skin_default.png', 'blank.png', 'blank.png', 'blank.png'},
  31. animations = {
  32. -- Standard animations.
  33. stand = { x= 0, y= 79, },
  34. lay = { x=162, y=166, },
  35. walk = { x=168, y=187, },
  36. mine = { x=189, y=198, },
  37. walk_mine = { x=200, y=219, },
  38. sit = { x= 81, y=160, },
  39. },
  40. collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
  41. stepheight = 0.6,
  42. eye_height = 1.47,
  43. collide_with_objects = true,
  44. show_on_minimap = false,
  45. })
  46. -- Player stats and animations
  47. local player_model = {}
  48. local player_anim = {}
  49. local player_sneak = {}
  50. function gamer.player_get_animation(player)
  51. local name = player:get_player_name()
  52. return {
  53. model = player_model[name],
  54. textures = gamer.player_textures[name],
  55. animation = player_anim[name],
  56. }
  57. end
  58. function gamer.player_set_model(player, model_name)
  59. local name = player:get_player_name()
  60. local model = models[model_name]
  61. if model then
  62. if player_model[name] == model_name then
  63. return
  64. end
  65. player:set_properties({
  66. mesh = model_name,
  67. textures = {gamer.player_textures[name]} or {'gamer_skin_default.png'},
  68. visual = 'mesh',
  69. visual_size = {x=10, y=10},
  70. })
  71. gamer.player_set_animation(player, 'stand')
  72. else
  73. player:set_properties({
  74. textures = {'gamer_skin_default.png'},
  75. visual = 'upright_sprite',
  76. })
  77. end
  78. player_model[name] = model_name
  79. end
  80. --[[function gamer.player_set_textures(player, texture)
  81. local name = player:get_player_name()
  82. player:set_properties({textures = texture})
  83. end
  84. ]]
  85. function gamer.player_set_animation(player, anim_name, speed)
  86. local name = player:get_player_name()
  87. if player_anim[name] == anim_name then
  88. return
  89. end
  90. local model = player_model[name] and models[player_model[name]]
  91. if not (model and model.animations[anim_name]) then
  92. return
  93. end
  94. local anim = model.animations[anim_name]
  95. player_anim[name] = anim_name
  96. player:set_animation(anim, speed or model.animation_speed)
  97. end
  98. function gamer.player_update_clothes(player, layer_1, layer_2, layer_3)
  99. local name = player:get_player_name()
  100. local skin = gamer.player_textures[name]
  101. if skin then
  102. player:set_properties({
  103. textures = {skin, layer_1, layer_2, layer_3},
  104. visual = 'mesh',
  105. visual_size = {x=10, y=10},
  106. mesh = 'gamer_model.b3d',
  107. })
  108. if layer_1 == 'blank.png' and layer_2 == 'blank.png' and layer_3 == 'blank.png' then
  109. minetest.chat_send_player(name, 'Seriously, put some clothes on!')
  110. player:set_properties({
  111. textures = {'gamer_punisher.png'},
  112. visual = 'upright_sprite',
  113. visual_size = {x=10, y=10},
  114. })
  115. end
  116. else
  117. minetest.chat_send_player(name, 'Set a skin with the /skin command.')
  118. player:set_properties({
  119. visual = 'mesh',
  120. mesh = 'gamer_model.b3d',
  121. textures = {'gamer_skin_default.png'},
  122. visual_size = {x=10, y=10},
  123. })
  124. gamer.player_set_animation(player, 'stand')
  125. end
  126. end
  127. function gamer.save_clothes(player, inv)
  128. local player_attributes = player:get_meta()
  129. local clothes = {}
  130. for i = 1,18 do
  131. local stack = inv:get_stack('slots', i)
  132. if not stack:is_empty() then
  133. clothes[i] = stack:to_string()
  134. end
  135. end
  136. player_attributes:set_string('clothing_inv', minetest.serialize(clothes))
  137. end
  138. function gamer.retrieve_clothes(player)
  139. local name = player:get_player_name()
  140. local player_attributes = player:get_meta()
  141. local clothing_inv = player_attributes:get_string('clothing_inv')
  142. local clothing = minetest.deserialize(clothing_inv) or {}
  143. local inv = minetest.get_inventory({type = 'detached', name = name..'_clothing'})
  144. for i = 1,18 do
  145. inv:set_stack('slots', i, clothing[i] or "")
  146. end
  147. end
  148. function gamer.get_clothes(player)
  149. local name = player:get_player_name()
  150. local inv = minetest.get_inventory({type = 'detached', name = name..'_clothing'})
  151. local tex1 = {}
  152. local tex2 = {}
  153. local tex3 = {}
  154. for i = 1,6 do
  155. local item = inv:get_stack('slots', i)
  156. local def = item:get_definition() or {}
  157. if def.tex then
  158. tex1[#tex1+1] = def.tex
  159. end
  160. end
  161. for i = 7,12 do
  162. local item = inv:get_stack('slots', i)
  163. local def = item:get_definition() or {}
  164. if def.tex then
  165. tex2[#tex2+1] = def.tex
  166. end
  167. end
  168. for i = 13,18 do
  169. local item = inv:get_stack('slots', i)
  170. local def = item:get_definition() or {}
  171. if def.tex then
  172. tex3[#tex3+1] = def.tex
  173. end
  174. end
  175. local string1 = table.concat(tex1, '^')
  176. local string2 = table.concat(tex2, '^')
  177. local string3 = table.concat(tex3, '^')
  178. if string1 == '' then
  179. string1 = 'blank.png'
  180. end
  181. if string2 == '' then
  182. string2 = 'blank.png'
  183. end
  184. if string3 == '' then
  185. string3 = 'blank.png'
  186. end
  187. gamer.player_update_clothes(player, string1, string2, string3)
  188. gamer.save_clothes(player, inv)
  189. end
  190. -- Localize for better performance.
  191. local player_set_animation = gamer.player_set_animation
  192. local player_attached = gamer.player_attached
  193. -- Check each player and apply animations
  194. minetest.register_globalstep(function(dtime)
  195. for _, player in pairs(minetest.get_connected_players()) do
  196. local name = player:get_player_name()
  197. local model_name = player_model[name]
  198. local model = model_name and models[model_name]
  199. if model and not player_attached[name] then
  200. local controls = player:get_player_control()
  201. local walking = false
  202. local animation_speed_mod = model.animation_speed or 30
  203. -- Determine if the player is walking
  204. if controls.up or controls.down or controls.left or controls.right then
  205. walking = true
  206. end
  207. -- Determine if the player is sneaking, and reduce animation speed if so
  208. if controls.sneak then
  209. animation_speed_mod = animation_speed_mod / 2
  210. end
  211. -- Apply animations based on what the player is doing
  212. if walking then
  213. if player_sneak[name] ~= controls.sneak then
  214. player_anim[name] = nil
  215. player_sneak[name] = controls.sneak
  216. end
  217. if controls.LMB then
  218. player_set_animation(player, 'walk_mine', animation_speed_mod)
  219. else
  220. player_set_animation(player, 'walk', animation_speed_mod)
  221. end
  222. elseif controls.LMB then
  223. player_set_animation(player, 'mine')
  224. else
  225. player_set_animation(player, 'stand', animation_speed_mod)
  226. end
  227. end
  228. end
  229. end)
  230. minetest.register_on_leaveplayer(function(player)
  231. local name = player:get_player_name()
  232. player_model[name] = nil
  233. player_anim[name] = nil
  234. gamer.save_skins()
  235. end)
  236. local function player_heal()
  237. for _, player in pairs(minetest.get_connected_players()) do
  238. local hp = player:get_hp()
  239. local breath = player:get_breath()
  240. local max_hp = player:get_properties().hp_max
  241. if hp > 0 and hp < max_hp and breath > 0 then
  242. player:set_hp(hp + 1)
  243. end
  244. end
  245. minetest.after(3.0, player_heal)
  246. end
  247. minetest.after(5.0, player_heal)
  248. dofile(minetest.get_modpath('gamer')..'/player_callbacks.lua')
  249. dofile(minetest.get_modpath('gamer')..'/change_skin.lua')