init.lua 8.1 KB

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