spacepaste

  1.  
  2. ARMOR_INIT_DELAY = 1
  3. ARMOR_INIT_TIMES = 1
  4. ARMOR_BONES_DELAY = 1
  5. ARMOR_UPDATE_TIME = 1
  6. ARMOR_DROP = minetest.get_modpath("bones") ~= nil
  7. ARMOR_DESTROY = false
  8. ARMOR_LEVEL_MULTIPLIER = 1
  9. ARMOR_HEAL_MULTIPLIER = 1
  10. local modpath = minetest.get_modpath(ARMOR_MOD_NAME)
  11. local worldpath = minetest.get_worldpath()
  12. local input = io.open(modpath.."/armor.conf", "r")
  13. if input then
  14. dofile(modpath.."/armor.conf")
  15. input:close()
  16. input = nil
  17. end
  18. input = io.open(worldpath.."/armor.conf", "r")
  19. if input then
  20. dofile(worldpath.."/armor.conf")
  21. input:close()
  22. input = nil
  23. end
  24. local time = 0
  25. armor = {
  26. player_hp = {},
  27. elements = {"head", "torso", "legs", "feet"},
  28. physics = {"jump","speed","gravity"},
  29. --[[formspec = "size[8,8.5]list[detached:player_name_armor;armor;0,1;2,3;]"
  30. .."image[2,0.75;2,4;armor_preview]"
  31. .."list[current_player;main;0,4.5;8,4;]"
  32. .."list[current_player;craft;4,1;3,3;]"
  33. .."list[current_player;craftpreview;7,2;1,1;]",]]
  34. textures = {},
  35. default_skin = "character",
  36. }
  37. --[[if inventory_plus then
  38. armor.formspec = "size[8,8.5]button[0,0;2,0.5;main;Back]"
  39. .."list[detached:player_name_armor;armor;0,1;2,3;]"
  40. .."image[2.5,0.75;2,4;armor_preview]"
  41. .."label[5,1;Level: armor_level]"
  42. .."label[5,1.5;Heal: armor_heal]"
  43. .."list[current_player;main;0,4.5;8,4;]"
  44. elseif unified_inventory then
  45. unified_inventory.register_button("armor", {
  46. type = "image",
  47. image = "inventory_plus_armor.png",
  48. })
  49. unified_inventory.register_page("armor", {
  50. get_formspec = function(player)
  51. local name = player:get_player_name()
  52. local formspec = "background[0.06,0.99;7.92,7.52;3d_armor_ui_form.png]"
  53. .."label[0,0;Armor]"
  54. .."list[detached:"..name.."_armor;armor;0,1;2,3;]"
  55. .."image[2.5,0.75;2,4;"..armor.textures[name].preview.."]"
  56. .."label[5,1;Level: "..armor.def[name].level.."]"
  57. .."label[5,1.5;Heal: "..armor.def[name].heal.."]"
  58. return {formspec=formspec}
  59. end,
  60. })
  61. end]]
  62. armor.def = {
  63. state = 0,
  64. count = 0,
  65. }
  66. armor.update_player_visuals = function(self, player)
  67. if not player then
  68. return
  69. end
  70. local name = player:get_player_name()
  71. if self.textures[name] then
  72. default.player_set_textures(player, {
  73. self.textures[name].skin,
  74. self.textures[name].armor,
  75. self.textures[name].wielditem,
  76. })
  77. end
  78. end
  79. armor.set_player_armor = function(self, player)
  80. if not player then
  81. return
  82. end
  83. local name = player:get_player_name()
  84. local player_inv = player:get_inventory()
  85. if not name then
  86. minetest.log("error", "Failed to read player name")
  87. return
  88. elseif not player_inv then
  89. minetest.log("error", "Failed to read player inventory")
  90. return
  91. end
  92. --local armor_texture = "3d_armor_trans.png"
  93. local armor_level = 0
  94. local armor_heal = 0
  95. local state = 0
  96. local items = 0
  97. local elements = {}
  98. local textures = {}
  99. local physics_o = {speed=1,gravity=1,jump=1}
  100. local material = {type=nil, count=1}
  101. --local preview = armor:get_player_skin(name).."_preview.png"
  102. for _,v in ipairs(self.elements) do
  103. elements[v] = false
  104. end
  105. for i=1, 6 do
  106. local stack = player_inv:get_stack("armor", i)
  107. local item = stack:get_name()
  108. if stack:get_count() == 1 then
  109. local def = stack:get_definition()
  110. for k, v in pairs(elements) do
  111. if v == false then
  112. local level = def.groups["armor_"..k]
  113. if level then
  114. local texture = item:gsub("%:", "_")
  115. table.insert(textures, texture..".png")
  116. --preview = preview.."^"..texture.."_preview.png"
  117. armor_level = armor_level + level
  118. state = state + stack:get_wear()
  119. items = items + 1
  120. local heal = def.groups["armor_heal"] or 0
  121. armor_heal = armor_heal + heal
  122. for kk,vv in ipairs(self.physics) do
  123. local o_value = def.groups["physics_"..vv]
  124. if o_value then
  125. physics_o[vv] = physics_o[vv] + o_value
  126. end
  127. end
  128. local mat = string.match(item, "%:.+_(.+)$")
  129. if material.type then
  130. if material.type == mat then
  131. material.count = material.count + 1
  132. end
  133. else
  134. material.type = mat
  135. end
  136. elements[k] = true
  137. end
  138. end
  139. end
  140. end
  141. end
  142. --[[if minetest.get_modpath("shields") then
  143. armor_level = armor_level * 0.9
  144. end]]
  145. if material.type and material.count == #self.elements then
  146. armor_level = armor_level * 1.1
  147. end
  148. armor_level = armor_level * ARMOR_LEVEL_MULTIPLIER
  149. armor_heal = armor_heal * ARMOR_HEAL_MULTIPLIER
  150. if #textures > 0 then
  151. armor_texture = table.concat(textures, "^")
  152. end
  153. local armor_groups = {fleshy=100}
  154. if armor_level > 0 then
  155. armor_groups.level = math.floor(armor_level / 20)
  156. armor_groups.fleshy = 100 - armor_level
  157. end
  158. player:set_armor_groups(armor_groups)
  159. player:set_physics_override(physics_o)
  160. self.textures[name].armor = armor_texture
  161. --self.textures[name].preview = preview
  162. self.def[name].state = state
  163. self.def[name].count = items
  164. self.def[name].level = armor_level
  165. self.def[name].heal = armor_heal
  166. self.def[name].jump = physics_o.jump
  167. self.def[name].speed = physics_o.speed
  168. self.def[name].gravity = physics_o.gravity
  169. self:update_player_visuals(player)
  170. end
  171. armor.update_armor = function(self, player)
  172. if not player then
  173. return
  174. end
  175. local name = player:get_player_name()
  176. local hp = player:get_hp() or 0
  177. if hp == 0 or hp == self.player_hp[name] then
  178. return
  179. end
  180. if self.player_hp[name] > hp then
  181. local player_inv = player:get_inventory()
  182. local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
  183. if not player_inv then
  184. minetest.log("error", "Failed to read player inventory")
  185. return
  186. elseif not armor_inv then
  187. minetest.log("error", "Failed to read detached inventory")
  188. return
  189. end
  190. local heal_max = 0
  191. local state = 0
  192. local items = 0
  193. for i=1, 6 do
  194. local stack = player_inv:get_stack("armor", i)
  195. if stack:get_count() > 0 then
  196. local use = stack:get_definition().groups["armor_use"] or 0
  197. local heal = stack:get_definition().groups["armor_heal"] or 0
  198. local item = stack:get_name()
  199. stack:add_wear(use)
  200. armor_inv:set_stack("armor", i, stack)
  201. player_inv:set_stack("armor", i, stack)
  202. state = state + stack:get_wear()
  203. items = items + 1
  204. if stack:get_count() == 0 then
  205. local desc = minetest.registered_items[item].description
  206. if desc then
  207. minetest.chat_send_player(name, "Your "..desc.." got destroyed!")
  208. end
  209. self:set_player_armor(player)
  210. armor:update_inventory(player)
  211. end
  212. heal_max = heal_max + heal
  213. end
  214. end
  215. self.def[name].state = state
  216. self.def[name].count = items
  217. heal_max = heal_max * ARMOR_HEAL_MULTIPLIER
  218. if heal_max > math.random(100) then
  219. player:set_hp(self.player_hp[name])
  220. return
  221. end
  222. end
  223. self.player_hp[name] = hp
  224. end
  225. armor.get_player_skin = function(self, name)
  226. local skin = nil
  227. if skins then
  228. skin = skins.skins[name]
  229. elseif u_skins then
  230. skin = u_skins.u_skins[name]
  231. end
  232. return skin or armor.default_skin
  233. end
  234. armor.get_armor_formspec = function(self, name)
  235. local formspec = armor.formspec:gsub("player_name", name)
  236. --formspec = formspec:gsub("armor_preview", armor.textures[name].preview)
  237. formspec = formspec:gsub("armor_level", armor.def[name].level)
  238. return formspec:gsub("armor_heal", armor.def[name].heal)
  239. end
  240. --[[armor.update_inventory = function(self, player)
  241. local name = player:get_player_name()
  242. if unified_inventory then
  243. if unified_inventory.current_page[name] == "armor" then
  244. unified_inventory.set_inventory_formspec(player, "armor")
  245. end
  246. else
  247. local formspec = armor:get_armor_formspec(name)
  248. if inventory_plus then
  249. local page = player:get_inventory_formspec()
  250. if page:find("detached:"..name.."_armor") then
  251. inventory_plus.set_inventory_formspec(player, formspec)
  252. end
  253. else
  254. player:set_inventory_formspec(formspec)
  255. end
  256. end
  257. end]]
  258. -- Register Player Model
  259. default.player_register_model("3d_armor_character.x", {
  260. animation_speed = 30,
  261. textures = {
  262. armor.default_skin..".png",
  263. "3d_armor_trans.png",
  264. "3d_armor_trans.png",
  265. },
  266. animations = {
  267. stand = {x=0, y=79},
  268. lay = {x=162, y=166},
  269. walk = {x=168, y=187},
  270. mine = {x=189, y=198},
  271. walk_mine = {x=200, y=219},
  272. sit = {x=81, y=160},
  273. },
  274. })
  275. -- Register Callbacks
  276. minetest.register_on_player_receive_fields(function(player, formname, fields)
  277. local name = player:get_player_name()
  278. if inventory_plus and fields.armor then
  279. local formspec = armor:get_armor_formspec(name)
  280. inventory_plus.set_inventory_formspec(player, formspec)
  281. return
  282. end
  283. for field, _ in pairs(fields) do
  284. if string.find(field, "skins_set_") then
  285. minetest.after(0, function(player)
  286. local skin = armor:get_player_skin(name)
  287. armor.textures[name].skin = skin..".png"
  288. armor:set_player_armor(player)
  289. end, player)
  290. end
  291. end
  292. end)
  293. minetest.register_on_joinplayer(function(player)
  294. default.player_set_model(player, "3d_armor_character.x")
  295. local name = player:get_player_name()
  296. local player_inv = player:get_inventory()
  297. local armor_inv = minetest.create_detached_inventory(name.."_armor",{
  298. on_put = function(inv, listname, index, stack, player)
  299. player:get_inventory():set_stack(listname, index, stack)
  300. armor:set_player_armor(player)
  301. --armor:update_inventory(player)
  302. end,
  303. on_take = function(inv, listname, index, stack, player)
  304. player:get_inventory():set_stack(listname, index, nil)
  305. armor:set_player_armor(player)
  306. --armor:update_inventory(player)
  307. end,
  308. on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
  309. local plaver_inv = player:get_inventory()
  310. local stack = inv:get_stack(to_list, to_index)
  311. player_inv:set_stack(to_list, to_index, stack)
  312. player_inv:set_stack(from_list, from_index, nil)
  313. armor:set_player_armor(player)
  314. --armor:update_inventory(player)
  315. end,
  316. allow_put = function(inv, listname, index, stack, player)
  317. return 1
  318. end,
  319. allow_take = function(inv, listname, index, stack, player)
  320. return stack:get_count()
  321. end,
  322. allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
  323. return count
  324. end,
  325. })
  326. --[[if inventory_plus then
  327. inventory_plus.register_button(player,"armor", "Armor")
  328. end]]
  329. armor_inv:set_size("armor", 4)
  330. player_inv:set_size("armor", 4)
  331. for i=1, 4 do
  332. local stack = player_inv:get_stack("armor", i)
  333. armor_inv:set_stack("armor", i, stack)
  334. end
  335. -- Legacy support, import player's armor from old inventory format
  336. for _,v in pairs(armor.elements) do
  337. local list = "armor_"..v
  338. armor_inv:add_item("armor", player_inv:get_stack(list, 1))
  339. player_inv:set_stack(list, 1, nil)
  340. end
  341. armor.player_hp[name] = 0
  342. armor.def[name] = {
  343. state = 0,
  344. count = 0,
  345. level = 0,
  346. heal = 0,
  347. jump = 1,
  348. speed = 1,
  349. gravity = 1,
  350. }
  351. armor.textures[name] = {
  352. skin = armor.default_skin..".png",
  353. armor = "3d_armor_trans.png",
  354. wielditem = "3d_armor_trans.png",
  355. preview = armor.default_skin.."_preview.png",
  356. }
  357. if minetest.get_modpath("skins") then
  358. local skin = skins.skins[name]
  359. if skin and skins.get_type(skin) == skins.type.MODEL then
  360. armor.textures[name].skin = skin..".png"
  361. end
  362. elseif minetest.get_modpath("simple_skins") then
  363. local skin = skins.skins[name]
  364. if skin then
  365. armor.textures[name].skin = skin..".png"
  366. end
  367. --[[elseif minetest.get_modpath("u_skins") then
  368. local skin = u_skins.u_skins[name]
  369. if skin and u_skins.get_type(skin) == u_skins.type.MODEL then
  370. armor.textures[name].skin = skin..".png"
  371. end]]
  372. end
  373. if minetest.get_modpath("player_textures") then
  374. local filename = minetest.get_modpath("player_textures").."/textures/player_"..name
  375. local f = io.open(filename..".png")
  376. if f then
  377. f:close()
  378. armor.textures[name].skin = "player_"..name..".png"
  379. end
  380. end
  381. for i=1, ARMOR_INIT_TIMES do
  382. minetest.after(ARMOR_INIT_DELAY * i, function(player)
  383. armor:set_player_armor(player)
  384. if inventory_plus == nil and unified_inventory == nil then
  385. --armor:update_inventory(player)
  386. end
  387. end, player)
  388. end
  389. end)
  390. if ARMOR_DROP == true or ARMOR_DESTROY == true then
  391. minetest.register_on_dieplayer(function(player)
  392. local name = player:get_player_name()
  393. local pos = player:getpos()
  394. if name and pos then
  395. local drop = {}
  396. local player_inv = player:get_inventory()
  397. local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
  398. for i=1, player_inv:get_size("armor") do
  399. local stack = armor_inv:get_stack("armor", i)
  400. if stack:get_count() > 0 then
  401. table.insert(drop, stack)
  402. armor_inv:set_stack("armor", i, nil)
  403. player_inv:set_stack("armor", i, nil)
  404. end
  405. end
  406. armor:set_player_armor(player)
  407. --[[if unified_inventory then
  408. unified_inventory.set_inventory_formspec(player, "craft")
  409. elseif inventory_plus then
  410. local formspec = inventory_plus.get_formspec(player,"main")
  411. inventory_plus.set_inventory_formspec(player, formspec)
  412. else
  413. armor:update_inventory(player)
  414. end]]
  415. if ARMOR_DESTROY == false then
  416. if minetest.get_modpath("bones") then
  417. minetest.after(ARMOR_BONES_DELAY, function()
  418. pos = vector.round(pos)
  419. local node = minetest.get_node(pos)
  420. if node.name == "bones:bones" then
  421. local meta = minetest.get_meta(pos)
  422. local owner = meta:get_string("owner")
  423. local inv = meta:get_inventory()
  424. if name == owner then
  425. for _,stack in ipairs(drop) do
  426. if inv:room_for_item("main", stack) then
  427. inv:add_item("main", stack)
  428. end
  429. end
  430. end
  431. end
  432. end)
  433. else
  434. for _,stack in ipairs(drop) do
  435. local obj = minetest.add_item(pos, stack)
  436. if obj then
  437. local x = math.random(1, 5)
  438. if math.random(1,2) == 1 then
  439. x = -x
  440. end
  441. local z = math.random(1, 5)
  442. if math.random(1,2) == 1 then
  443. z = -z
  444. end
  445. obj:setvelocity({x=1/x, y=obj:getvelocity().y, z=1/z})
  446. end
  447. end
  448. end
  449. end
  450. end
  451. end)
  452. end
  453. minetest.register_globalstep(function(dtime)
  454. time = time + dtime
  455. if time > ARMOR_UPDATE_TIME then
  456. for _,player in ipairs(minetest.get_connected_players()) do
  457. armor:update_armor(player)
  458. end
  459. time = 0
  460. end
  461. end)
  462.