skin_meta_api.lua 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. skins.meta = {}
  2. local skin_class = {}
  3. skin_class.__index = skin_class
  4. skins.skin_class = skin_class
  5. -----------------------
  6. -- Class methods
  7. -----------------------
  8. -- constructor
  9. function skins.new(key, object)
  10. assert(key, 'Unique skins key required, like "character_1"')
  11. local self = object or {}
  12. setmetatable(self, skin_class)
  13. self.__index = skin_class
  14. self._key = key
  15. self._sort_id = 0
  16. skins.meta[key] = self
  17. return self
  18. end
  19. -- getter
  20. function skins.get(key)
  21. return skins.meta[key]
  22. end
  23. -- Skin methods
  24. -- In this implementation it is just access to attrubutes wrapped
  25. -- but this way allow to redefine the functionality for more complex skins provider
  26. function skin_class:get_key()
  27. return self._key
  28. end
  29. function skin_class:set_meta(key, value)
  30. self[key] = value
  31. end
  32. function skin_class:get_meta(key)
  33. return self[key]
  34. end
  35. function skin_class:get_meta_string(key)
  36. return tostring(self:get_meta(key) or "")
  37. end
  38. function skin_class:set_texture(value)
  39. self._texture = value
  40. end
  41. function skin_class:get_texture()
  42. return self._texture
  43. end
  44. function skin_class:set_preview(value)
  45. self._preview = value
  46. end
  47. function skin_class:get_preview()
  48. if self._preview then
  49. return self._preview
  50. end
  51. local player_skin = "("..self:get_texture()..")"
  52. local skin = ""
  53. -- Consistent on both sizes:
  54. --Chest
  55. skin = skin .. "([combine:16x32:-16,-12=" .. player_skin .. "^[mask:skindb_mask_chest.png)^"
  56. --Head
  57. skin = skin .. "([combine:16x32:-4,-8=" .. player_skin .. "^[mask:skindb_mask_head.png)^"
  58. --Hat
  59. skin = skin .. "([combine:16x32:-36,-8=" .. player_skin .. "^[mask:skindb_mask_head.png)^"
  60. --Right Arm
  61. skin = skin .. "([combine:16x32:-44,-12=" .. player_skin .. "^[mask:skindb_mask_rarm.png)^"
  62. --Right Leg
  63. skin = skin .. "([combine:16x32:0,0=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^"
  64. -- 64x skins have non-mirrored arms and legs
  65. local left_arm
  66. local left_leg
  67. if self:get_meta("format") == "1.8" then
  68. left_arm = "([combine:16x32:-24,-44=" .. player_skin .. "^[mask:(skindb_mask_rarm.png^[transformFX))^"
  69. left_leg = "([combine:16x32:-12,-32=" .. player_skin .. "^[mask:(skindb_mask_rleg.png^[transformFX))^"
  70. else
  71. left_arm = "([combine:16x32:-44,-12=" .. player_skin .. "^[mask:skindb_mask_rarm.png^[transformFX)^"
  72. left_leg = "([combine:16x32:0,0=" .. player_skin .. "^[mask:skindb_mask_rleg.png^[transformFX)^"
  73. end
  74. -- Left Arm
  75. skin = skin .. left_arm
  76. --Left Leg
  77. skin = skin .. left_leg
  78. -- Add overlays for 64x skins. these wont appear if skin is 32x because it will be cropped out
  79. --Chest Overlay
  80. skin = skin .. "([combine:16x32:-16,-28=" .. player_skin .. "^[mask:skindb_mask_chest.png)^"
  81. --Right Arm Overlay
  82. skin = skin .. "([combine:16x32:-44,-28=" .. player_skin .. "^[mask:skindb_mask_rarm.png)^"
  83. --Right Leg Overlay
  84. skin = skin .. "([combine:16x32:0,-16=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^"
  85. --Left Arm Overlay
  86. skin = skin .. "([combine:16x32:-40,-44=" .. player_skin .. "^[mask:(skindb_mask_rarm.png^[transformFX))^"
  87. --Left Leg Overlay
  88. skin = skin .. "([combine:16x32:4,-32=" .. player_skin .. "^[mask:(skindb_mask_rleg.png^[transformFX))"
  89. -- Full Preview
  90. skin = "(((" .. skin .. ")^[resize:64x128)^[mask:skindb_transform.png)"
  91. return skin
  92. end
  93. function skin_class:apply_skin_to_player(player)
  94. local function concat_texture(base, ext)
  95. if base == "blank.png" then
  96. return ext
  97. elseif ext == "blank.png" then
  98. return base
  99. else
  100. return base .. "^" .. ext
  101. end
  102. end
  103. local playername = player:get_player_name()
  104. local ver = self:get_meta("format") or "1.0"
  105. player_api.set_model(player, "skinsdb_3d_armor_character_5.b3d")
  106. local v10_texture = "blank.png"
  107. local v18_texture = "blank.png"
  108. local armor_texture = "blank.png"
  109. local wielditem_texture = "blank.png"
  110. if ver == "1.8" then
  111. v18_texture = self:get_texture()
  112. else
  113. v10_texture = self:get_texture()
  114. end
  115. -- Support for clothing
  116. if skins.clothing_loaded and clothing.player_textures[playername] then
  117. local cape = clothing.player_textures[playername].cape
  118. local layers = {}
  119. for k, v in pairs(clothing.player_textures[playername]) do
  120. if k ~= "skin" and k ~= "cape" then
  121. table.insert(layers, v)
  122. end
  123. end
  124. local overlay = table.concat(layers, "^")
  125. v10_texture = concat_texture(v10_texture, cape)
  126. v18_texture = concat_texture(v18_texture, overlay)
  127. end
  128. -- Support for armor
  129. if skins.armor_loaded then
  130. local armor_textures = armor.textures[playername]
  131. if armor_textures then
  132. armor_texture = concat_texture(armor_texture, armor_textures.armor)
  133. wielditem_texture = concat_texture(wielditem_texture, armor_textures.wielditem)
  134. end
  135. end
  136. player_api.set_textures(player, {
  137. v10_texture,
  138. v18_texture,
  139. armor_texture,
  140. wielditem_texture,
  141. })
  142. player:set_properties({
  143. visual_size = {
  144. x = self:get_meta("visual_size_x") or 1,
  145. y = self:get_meta("visual_size_y") or 1
  146. }
  147. })
  148. end
  149. function skin_class:set_skin(player)
  150. -- The set_skin is used on skins selection
  151. -- This means the method could be redefined to start an furmslec
  152. -- See character_creator for example
  153. end
  154. function skin_class:is_applicable_for_player(playername)
  155. local assigned_player = self:get_meta("playername")
  156. return minetest.check_player_privs(playername, {server=true}) or assigned_player == nil or assigned_player == true or
  157. (assigned_player:lower() == playername:lower())
  158. end