-
Notifications
You must be signed in to change notification settings - Fork 39
/
skin_meta_api.lua
240 lines (204 loc) · 6.58 KB
/
skin_meta_api.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
skins.meta = {}
local has_hand_monoid = minetest.get_modpath("hand_monoid")
local skin_class = {}
skin_class.__index = skin_class
skins.skin_class = skin_class
-----------------------
-- Class methods
-----------------------
-- constructor
function skins.new(key, object)
assert(key, 'Unique skins key required, like "character_1"')
local self = object or {}
setmetatable(self, skin_class)
self.__index = skin_class
self._key = key
self._sort_id = 0
skins.meta[key] = self
return self
end
-- getter
function skins.get(key)
return skins.meta[key]
end
-- Skin methods
-- In this implementation it is just access to attrubutes wrapped
-- but this way allow to redefine the functionality for more complex skins provider
function skin_class:get_key()
return self._key
end
function skin_class:set_meta(key, value)
self[key] = value
end
function skin_class:get_meta(key)
return self[key]
end
function skin_class:get_meta_string(key)
return tostring(self:get_meta(key) or "")
end
function skin_class:set_texture(value)
self._texture = value
end
function skin_class:get_texture()
return self._texture
end
function skin_class:set_hand(hand)
self._hand = hand
end
local ALPHA_CLIP = minetest.features.use_texture_alpha_string_modes and "clip" or true
function skin_class:set_hand_from_texture()
local hand = core.get_current_modname()..':'..self._texture:gsub('[%p%c%s]', '')
local hand_def = {}
for k,v in pairs(minetest.registered_items[""]) do
if k ~= "mod_origin" and k ~= "type" and k ~= "wield_image" then
hand_def[k] = v
end
end
hand_def.tiles = {self:get_texture()}
hand_def.visual_scale = 1
hand_def.wield_scale = {x=1,y=1,z=1}
hand_def.paramtype = "light"
hand_def.drawtype = "mesh"
if(self:get_meta("format") == "1.0") then
hand_def.mesh = "skinsdb_hand.b3d"
else
hand_def.mesh = "skinsdb_hand_18.b3d"
end
hand_def.use_texture_alpha = ALPHA_CLIP
minetest.register_node(hand, hand_def)
self:set_hand(hand)
end
function skin_class:get_hand()
return self._hand
end
function skin_class:set_preview(value)
self._preview = value
end
function skin_class:get_preview()
if self._preview then
return self._preview
end
local player_skin = "("..self:get_texture()..")"
local skin = ""
-- Consistent on both sizes:
--Chest
skin = skin .. "([combine:16x32:-16,-12=" .. player_skin .. "^[mask:skindb_mask_chest.png)^"
--Head
skin = skin .. "([combine:16x32:-4,-8=" .. player_skin .. "^[mask:skindb_mask_head.png)^"
--Hat
skin = skin .. "([combine:16x32:-36,-8=" .. player_skin .. "^[mask:skindb_mask_head.png)^"
--Right Arm
skin = skin .. "([combine:16x32:-44,-12=" .. player_skin .. "^[mask:skindb_mask_rarm.png)^"
--Right Leg
skin = skin .. "([combine:16x32:0,0=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^"
-- 64x skins have non-mirrored arms and legs
local left_arm
local left_leg
if self:get_meta("format") == "1.8" then
left_arm = "([combine:16x32:-24,-44=" .. player_skin .. "^[mask:(skindb_mask_rarm.png^[transformFX))^"
left_leg = "([combine:16x32:-12,-32=" .. player_skin .. "^[mask:(skindb_mask_rleg.png^[transformFX))^"
else
left_arm = "([combine:16x32:-44,-12=" .. player_skin .. "^[mask:skindb_mask_rarm.png^[transformFX)^"
left_leg = "([combine:16x32:0,0=" .. player_skin .. "^[mask:skindb_mask_rleg.png^[transformFX)^"
end
-- Left Arm
skin = skin .. left_arm
--Left Leg
skin = skin .. left_leg
-- Add overlays for 64x skins. these wont appear if skin is 32x because it will be cropped out
--Chest Overlay
skin = skin .. "([combine:16x32:-16,-28=" .. player_skin .. "^[mask:skindb_mask_chest.png)^"
--Right Arm Overlay
skin = skin .. "([combine:16x32:-44,-28=" .. player_skin .. "^[mask:skindb_mask_rarm.png)^"
--Right Leg Overlay
skin = skin .. "([combine:16x32:0,-16=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^"
--Left Arm Overlay
skin = skin .. "([combine:16x32:-40,-44=" .. player_skin .. "^[mask:(skindb_mask_rarm.png^[transformFX))^"
--Left Leg Overlay
skin = skin .. "([combine:16x32:4,-32=" .. player_skin .. "^[mask:(skindb_mask_rleg.png^[transformFX))"
-- Full Preview
skin = "(((" .. skin .. ")^[resize:64x128)^[mask:skindb_transform.png)"
return skin
end
function skin_class:apply_skin_to_player(player)
local function concat_texture(base, ext)
if base == "blank.png" then
return ext
elseif ext == "blank.png" then
return base
else
return base .. "^" .. ext
end
end
local playername = player:get_player_name()
local ver = self:get_meta("format") or "1.0"
player_api.set_model(player, "skinsdb_3d_armor_character_5.b3d")
local v10_texture = "blank.png"
local v18_texture = "blank.png"
local armor_texture = "blank.png"
local wielditem_texture = "blank.png"
if ver == "1.8" then
v18_texture = self:get_texture()
else
v10_texture = self:get_texture()
end
-- Support for clothing
if skins.clothing_loaded and clothing.player_textures[playername] then
local cape = clothing.player_textures[playername].cape
local layers = {}
for k, v in pairs(clothing.player_textures[playername]) do
if k ~= "skin" and k ~= "cape" then
table.insert(layers, v)
end
end
local overlay = table.concat(layers, "^")
v10_texture = concat_texture(v10_texture, cape)
v18_texture = concat_texture(v18_texture, overlay)
end
-- Support for armor
if skins.armor_loaded then
local armor_textures = armor.textures[playername]
if armor_textures then
armor_texture = concat_texture(armor_texture, armor_textures.armor)
wielditem_texture = concat_texture(wielditem_texture, armor_textures.wielditem)
end
end
player_api.set_textures(player, {
v10_texture,
v18_texture,
armor_texture,
wielditem_texture,
})
player:set_properties({
visual_size = {
x = self:get_meta("visual_size_x") or 1,
y = self:get_meta("visual_size_y") or 1
}
})
local hand = self:get_hand()
if has_hand_monoid then
if hand then
hand_monoid.monoid:add_change(player, {name = hand}, "skinsdb:hand")
else
hand_monoid.monoid:del_change(player, "skinsdb:hand")
end
else
if hand then
player:get_inventory():set_size("hand", 1)
player:get_inventory():set_stack("hand", 1, hand)
else
player:get_inventory():set_stack("hand", 1, "")
end
end
end
function skin_class:set_skin(player)
-- The set_skin is used on skins selection
-- This means the method could be redefined to start an furmslec
-- See character_creator for example
end
function skin_class:is_applicable_for_player(playername)
local assigned_player = self:get_meta("playername")
return assigned_player == nil or assigned_player == true or
playername and (minetest.check_player_privs(playername, {server=true}) or
assigned_player:lower() == playername:lower())
end