init.lua 5.7 KB

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