init.lua 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. -- Simple Skins mod for minetest (5th June 2016)
  2. -- Adds a simple skin selector to the inventory, using inventory_plus
  3. -- or by using the /skin command to bring up selection list.
  4. -- Released by TenPlus1 and based on Zeg9's code under WTFPL
  5. skins = {}
  6. skins.skins = {}
  7. skins.modpath = minetest.get_modpath("simple_skins")
  8. skins.armor = minetest.get_modpath("3d_armor")
  9. skins.inv = minetest.get_modpath("inventory_plus")
  10. -- load skin list
  11. skins.list = {}
  12. skins.add = function(skin)
  13. table.insert(skins.list, skin)
  14. end
  15. local id = 1
  16. local f
  17. while true do
  18. f = io.open(skins.modpath .. "/textures/character_" .. id .. ".png")
  19. if not f then break end
  20. f:close()
  21. skins.add("character_" .. id)
  22. id = id + 1
  23. end
  24. id = id - 1
  25. -- load Metadata
  26. skins.meta = {}
  27. local f, data
  28. for _, i in pairs(skins.list) do
  29. skins.meta[i] = {}
  30. f = io.open(skins.modpath .. "/meta/" .. i .. ".txt")
  31. data = nil
  32. if f then
  33. data = minetest.deserialize("return {" .. f:read('*all') .. "}")
  34. f:close()
  35. end
  36. data = data or {}
  37. skins.meta[i].name = data.name or ""
  38. skins.meta[i].author = data.author or ""
  39. skins.meta[i].sex = data.sex or ""
  40. if type(data.enable) == "boolean" then
  41. if data.enable == true then
  42. skins.meta[i].enable = true
  43. else
  44. skins.meta[i].enable = false
  45. end
  46. else
  47. skins.meta[i].enable = true
  48. end
  49. end
  50. -- player load/save routines
  51. skins.file = minetest.get_worldpath() .. "/simple_skins.mt"
  52. skins.load = function()
  53. local input = io.open(skins.file, "r")
  54. local data = nil
  55. if input then
  56. data = input:read('*all')
  57. end
  58. if data and data ~= "" then
  59. local lines = string.split(data, "\n")
  60. for _, line in pairs(lines) do
  61. data = string.split(line, ' ', 2)
  62. skins.skins[data[1]] = data[2]
  63. end
  64. io.close(input)
  65. end
  66. end
  67. -- load player skins now
  68. skins.load()
  69. skins.save = function()
  70. local output = io.open(skins.file,'w')
  71. for name, skin in pairs(skins.skins) do
  72. if name and skin then
  73. output:write(name .. " " .. skin .. "\n")
  74. end
  75. end
  76. io.close(output)
  77. end
  78. -- skin selection page
  79. skins.formspec = {}
  80. skins.formspec.main = function(name)
  81. local selected = 1 -- select default
  82. local formspec = "size[8,8.5]"
  83. .. "bgcolor[#08080860;false]"
  84. .. "label[.5,2;Choose Your Avatar:]"
  85. .. "textlist[0.5,2.5;7,6;skins_set;"
  86. for i = 1, #skins.list do
  87. --if skins.meta[skins.list[i]].enable then
  88. formspec = formspec .. skins.meta[ skins.list[i] ].name .. ","
  89. if skins.skins[name] == skins.list[i] then
  90. selected = i
  91. end
  92. --end
  93. end
  94. formspec = formspec .. ";" .. selected .. ";true]"
  95. local meta = skins.meta[ skins.skins[name] ]
  96. if meta then
  97. if meta.name then
  98. formspec = formspec .. "label[3,.25;Name: " .. meta.name .. "]"
  99. end
  100. if meta.author then
  101. formspec = formspec .. "label[3,.65;Author: " .. meta.author .. "]"
  102. end
  103. end
  104. -- Show avatar number (MustTest).
  105. formspec = formspec .. "label[3,1.05;Avatar #: " .. selected .. "]"
  106. -- Back button moved here (MustTest).
  107. formspec = formspec .. "button[0.5,0.5;2,.5;main;Back]"
  108. return formspec
  109. end
  110. -- update player skin
  111. skins.update_player_skin = function(player)
  112. if not player then
  113. return
  114. end
  115. local name = player:get_player_name()
  116. if skins.armor then
  117. armor.textures[name].skin = skins.skins[name] .. ".png"
  118. armor:set_player_armor(player)
  119. else
  120. player:set_properties({
  121. textures = {skins.skins[name] .. ".png"},
  122. })
  123. end
  124. skins.save()
  125. end
  126. -- load player skin on join
  127. minetest.register_on_joinplayer(function(player)
  128. local name = player:get_player_name()
  129. if not skins.skins[name] then
  130. skins.skins[name] = "character_1"
  131. end
  132. skins.update_player_skin(player)
  133. end)
  134. -- formspec control
  135. minetest.register_on_player_receive_fields(function(player, formname, fields)
  136. local name = player:get_player_name()
  137. if fields.skins then
  138. inventory_plus.set_inventory_formspec(player, skins.formspec.main(name))
  139. end
  140. local event = minetest.explode_textlist_event(fields["skins_set"])
  141. if event.type == "CHG" then
  142. local index = event.index
  143. if index > id then index = id end
  144. skins.skins[name] = skins.list[index]
  145. minetest.log("action", name .. " selects skin " .. index)
  146. if skins.inv then
  147. inventory_plus.set_inventory_formspec(player, skins.formspec.main(name))
  148. end
  149. skins.update_player_skin(player)
  150. end
  151. end)
  152. -- Utility functions.
  153. function skins.get_player_sex(pname)
  154. if type(pname) ~= "string" then
  155. pname = pname:get_player_name()
  156. end
  157. local c = skins.skins[pname]
  158. if type(c) ~= "string" then
  159. return ""
  160. end
  161. local meta = skins.meta[c]
  162. if type(meta.sex) ~= "string" then
  163. return ""
  164. end
  165. if meta.sex == "female" then
  166. return "female"
  167. end
  168. if meta.sex == "male" then
  169. return "male"
  170. end
  171. return ""
  172. end
  173. function skins.get_gender_strings(pname)
  174. local sex = skins.get_player_sex(pname)
  175. local data = {}
  176. if sex == "male" then
  177. data.him = "him"
  178. data.he = "he"
  179. data.his = "his"
  180. data.his_possessive = "his"
  181. data.himself = "himself"
  182. elseif sex == "female" then
  183. data.him = "her"
  184. data.he = "she"
  185. data.his = "her"
  186. data.his_possessive = "hers"
  187. data.himself = "herself"
  188. else
  189. data.him = "it"
  190. data.he = "it"
  191. data.his = "its"
  192. data.his_possessive = "its"
  193. data.himself = "itself"
  194. end
  195. return data
  196. end
  197. function skins.get_random_standard_gender(fem_chance)
  198. local data = {}
  199. if math.random(1, 100) <= fem_chance then
  200. data.him = "her"
  201. data.he = "she"
  202. data.his = "her"
  203. data.his_possessive = "hers"
  204. data.himself = "herself"
  205. else
  206. data.him = "him"
  207. data.he = "he"
  208. data.his = "his"
  209. data.his_possessive = "his"
  210. data.himself = "himself"
  211. end
  212. return data
  213. end
  214. -- Register button once.
  215. if skins.inv then
  216. inventory_plus.register_button("skins", "Avatar")
  217. end