Codebase list minetest-mod-character-creator / 1bfb81b
New upstream version 1.2 Julien Puydt 1 year, 5 months ago
121 changed file(s) with 247 addition(s) and 114 deletion(s). Raw diff Collapse all Expand all
0 unused_args = false
1 allow_defined_top = true
2 max_line_length = 999
3 -- Allow shadowed variables (callbacks in callbacks)
4 redefined = false
5
6 globals = {
7 "character_creator",
8 "armor", "multiskin"
9 }
10
11 read_globals = {
12 string = {fields = {"split", "trim"}},
13 table = {fields = {"copy", "getn", "indexof"}},
14
15 "minetest", "vector",
16 "ItemStack",
17
18 "skins", "sfinv", "sfinv_buttons", "unified_inventory",
19 "inventory_plus"
20 }
+0
-6
depends.txt less more
0 3d_armor?
1 multiskin?
2 inventory_plus?
3 unified_inventory?
4 skinsdb?
5 sfinv_buttons?
+0
-1
description.txt less more
0 Allows the creation of customized character skins inside the game.
+151
-103
init.lua less more
0 if not minetest.get_translator then
1 error("[character_creator] Translator API not found. "
2 .. "Please update Minetest to a recent version.")
3 end
4
05 character_creator = {}
1 character_creator.skins = dofile(minetest.get_modpath("character_creator") .. "/skins.lua")
6 -- Fill character_creator.skins
7 dofile(minetest.get_modpath("character_creator") .. "/skins.lua")
8
9 -- Update with /path/to/i18n.py -p -s .
10 character_creator.S = minetest.get_translator("character_creator")
11 character_creator.FS = function(...)
12 return minetest.formspec_escape(character_creator.S(...))
13 end
14 --local S = character_creator.S
15 local FS = character_creator.S
216
317 local skinsdb
418 if minetest.get_modpath("skinsdb") and minetest.global_exists("skins") then
519 skinsdb = skins
20
21 -- Create dummy skins with hand
22 if skins.skin_class.set_hand_from_texture then
23 for skin_name, skin_texture in pairs(character_creator.skins.skin) do
24 local hand_skin = skinsdb.new("character_creator:"..skin_name)
25 hand_skin:set_texture(skin_texture)
26 hand_skin:set_hand_from_texture()
27 hand_skin:set_meta("in_inventory_list", false)
28 end
29 end
630 end
731
832 local skin_default = {
2044 shoes = "Leather Shoes"
2145 }
2246
23 local skins = character_creator.skins
2447 local skins_array = {}
2548
2649 minetest.after(0, function()
27 local function associative_to_array(associative)
50 local function table_keys_to_array(associative)
2851 local array = {}
2952 for key in pairs(associative) do
3053 table.insert(array, key)
3255 return array
3356 end
3457
35 skins_array = {
36 skin = associative_to_array(skins.skin),
37 face = associative_to_array(skins.face),
38 hair = associative_to_array(skins.hair),
39 hair_style = associative_to_array(skins.hair_style),
40 eyes = associative_to_array(skins.eyes),
41 tshirt = associative_to_array(skins.tshirt),
42 pants = associative_to_array(skins.pants),
43 shoes = associative_to_array(skins.shoes)
44 }
58 -- part: skin, face, hair, ....
59 for part, def in pairs(character_creator.skins) do
60 skins_array[part] = table_keys_to_array(def)
61 end
4562 end)
4663
4764 -- Saved skins_array indexes in this
4966
5067 local function show_formspec(player)
5168 local indexes = skin_indexes[player]
52
53 local formspec = "size[15,9.5]"
54 .. "no_prepend[]"
55 .. "bgcolor[#00000000]"
69 local order = {
70 "skin", "face", "hair", "hair_style", "eyes",
71 "tshirt", "pants", "shoes"
72 }
73
74 local fs = {
75 "formspec_version[2]",
76 "size[13,9]",
77 "no_prepend[]",
78 "bgcolor[#00000000]",
79 "style_type[button;noclip=true]",
5680 -- Gender
57 .. "button[10,;2.5,.5;male;Male]"
58 .. "button[12.5,;2.5,.5;female;Female]"
81 "button[10, 0;2.5,.75;male;" .. FS("Male") .. "]",
82 "button[12.5,0;2.5,.75;female;" .. FS("Female") .. "]",
5983 -- Height
60 .. "button[10,1.1;2.5,.5;taller;Taller]"
61 .. "button[10,2;2.5,.5;shorter;Shorter]"
84 "button[10 ,1;2.5,.75;taller;" .. FS("Taller") .. "]",
85 "button[10 ,2;2.5,.75;shorter;" .. FS("Shorter") .. "]",
6286 -- Width
63 .. "button[12.5,1.1;2.5,.5;wider;Wider]"
64 .. "button[12.5,2;2.5,.5;thinner;Thinner]"
65 -- Skin
66 .. "button[10,2.75;5,1;skin;" .. skins_array.skin[indexes.skin] .. "]"
67 .. "button[10,2.75;1,1;skin_back;<<]"
68 .. "button[14,2.75;1,1;skin_next;>>]"
69 -- Face
70 .. "button[10,3.5;5,1;face;" .. skins_array.face[indexes.face] .. "]"
71 .. "button[10,3.5;1,1;face_back;<<]"
72 .. "button[14,3.5;1,1;face_next;>>]"
73 -- Hair
74 .. "button[10,4.25;5,1;hair;" .. skins_array.hair[indexes.hair] .. "]"
75 .. "button[10,4.25;1,1;hair_back;<<]"
76 .. "button[14,4.25;1,1;hair_next;>>]"
77 -- Hair Style
78 .. "button[10,5;5,1;hair_style;" .. skins_array.hair_style[indexes.hair_style] .. "]"
79 .. "button[10,5;1,1;hair_style_back;<<]"
80 .. "button[14,5;1,1;hair_style_next;>>]"
81 -- Eyes
82 .. "button[10,5.75;5,1;eyes;" .. skins_array.eyes[indexes.eyes] .. "]"
83 .. "button[10,5.75;1,1;eyes_back;<<]"
84 .. "button[14,5.75;1,1;eyes_next;>>]"
85 -- T-Shirt
86 .. "button[10,6.5;5,1;tshirt;" .. skins_array.tshirt[indexes.tshirt] .. "]"
87 .. "button[10,6.5;1,1;tshirt_back;<<]"
88 .. "button[14,6.5;1,1;tshirt_next;>>]"
89 -- Pants
90 .. "button[10,7.25;5,1;pants;" .. skins_array.pants[indexes.pants] .. "]"
91 .. "button[10,7.25;1,1;pants_back;<<]"
92 .. "button[14,7.25;1,1;pants_next;>>]"
93 -- Shoes
94 .. "button[10,8;5,1;shoes;" .. skins_array.shoes[indexes.shoes] .. "]"
95 .. "button[10,8;1,1;shoes_back;<<]"
96 .. "button[14,8;1,1;shoes_next;>>]"
97 -- Done
98 .. "button_exit[10,9;2.5,.5;done;Done]"
99 .. "button_exit[12.5,9;2.5,.5;cancel;Cancel]"
100
101 minetest.show_formspec(player:get_player_name(), "character_creator", formspec)
87 "button[12.5,1;2.5,.75;wider;" .. FS("Wider") .. "]",
88 "button[12.5,2;2.5,.75;thinner;" .. FS("Thinner") .. "]",
89 }
90 local x = 11
91 local y = 3
92
93 for _, part in ipairs(order) do
94 fs[#fs + 1] =
95 ("button[%g,%g;1,.75;%s_back;<<]"):format(x - 1, y, part) ..
96 ("button[%g,%g;3,.75;%s;%s]" ):format(x + 0, y, part, skins_array[part][indexes[part]]) ..
97 ("button[%g,%g;1,.75;%s_next;>>]"):format(x + 3, y, part)
98 y = y + 0.75
99 end
100 table.insert(fs,
101 "button_exit[10,9.2;2.5,.75;done;" .. FS("Done") .. "]" ..
102 "button_exit[12.5,9.2;2.5,.75;cancel;" .. FS("Cancel") .. "]")
103
104 minetest.show_formspec(player:get_player_name(), "character_creator", table.concat(fs))
102105 end
103106
104107 local function load_skin(player)
141144
142145 local function save_skin(player)
143146 local player_meta = player:get_meta()
147 if player_meta == nil then
148 -- The player disconnected before this function was dispatched
149 return
150 end
144151
145152 local function save_data(data_name)
146153 local indexes = skin_indexes[player]
161168
162169 local function get_texture(player)
163170 local player_meta = player:get_meta()
164 local indexes = skin_indexes[player]
165 local texture = ""
171 if not player_meta then
172 -- The player disconnected before this function was dispatched
173 return ""
174 end
175
176 local defs = {}
177 for part, selected in pairs(skin_indexes[player]) do
178 local key = skins_array[part][selected]
179 defs[part] = {
180 key = key,
181 -- Table reference to the selected hair/skin/...
182 val = character_creator.skins[part][key]
183 }
184 end
185
166186 local gender = player_meta:get_string("character_creator:gender")
167
168 local skin_key = skins_array.skin[indexes.skin]
169 local skin = skins.skin[skin_key]
170 texture = texture .. "(" .. skin .. ")"
171
172 local face_key = skins_array.face[indexes.face]
173 local face = skins.face[face_key][gender][skin_key]
174 texture = texture .. "^(" .. face .. ")"
175
176 local eyes_key = skins_array.eyes[indexes.eyes]
177 local eyes = skins.eyes[eyes_key]
178 texture = texture .. "^(" .. eyes .. ")"
179
180 local hair_style = skins_array.hair_style[indexes.hair_style]
181 local hair_key = skins_array.hair[indexes.hair]
182 local hair = skins.hair[hair_key][gender][hair_style]
183 texture = texture .. "^(" .. hair .. ")"
184
185 local tshirt_key = skins_array.tshirt[indexes.tshirt]
186 local tshirt = skins.tshirt[tshirt_key]
187 texture = texture .. "^(" .. tshirt .. ")"
188
189 local pants_key = skins_array.pants[indexes.pants]
190 local pants = skins.pants[pants_key]
191 texture = texture .. "^(" .. pants .. ")"
192
193 local shoes_key = skins_array.shoes[indexes.shoes]
194 local shoes = skins.shoes[shoes_key]
195 texture = texture .. "^(" .. shoes .. ")"
196 return texture
187 local face = defs.face.val[gender][defs.skin.key]
188 local hair = defs.hair.val[gender][defs.hair_style.key]
189 return table.concat({
190 "(" .. defs.skin.val .. ")",
191 "(" .. face .. ")",
192 "(" .. defs.eyes.val .. ")",
193 "(" .. hair .. ")",
194 "(" .. defs.tshirt.val .. ")",
195 "(" .. defs.pants.val .. ")",
196 "(" .. defs.shoes.val .. ")",
197 }, "^")
197198 end
198199
199200 local function change_skin(player)
200201 local player_meta = player:get_meta()
202 if player_meta == nil then
203 -- The player disconnected before this function was dispatched
204 return
205 end
206
201207 local texture = get_texture(player)
202208
203209 local width = player_meta:get_float("character_creator:width")
210216 }
211217 })
212218
213 local name = player:get_player_name()
214
215219 if minetest.get_modpath("multiskin") then
216 multiskin.layers[name].skin = texture
217 armor:set_player_armor(player)
218 multiskin:set_player_textures(player, {textures = {texture}})
220 local name = player:get_player_name()
221 minetest.after(0, function(name)
222 local player = minetest.get_player_by_name(name)
223 if player then
224 multiskin.layers[name].skin = texture
225 armor:set_player_armor(player)
226 multiskin:set_player_textures(player, {textures = {texture}})
227 end
228 end, name)
229
219230 elseif minetest.get_modpath("3d_armor") then
220 armor.textures[name].skin = texture
221 armor:set_player_armor(player)
231 local name = player:get_player_name()
232 minetest.after(0, function(name)
233 local player = minetest.get_player_by_name(name)
234 if player then
235 armor.textures[name].skin = texture
236 armor:set_player_armor(player)
237 end
238 end, name)
239
222240 else
223241 player:set_properties({textures = {texture}})
224242 end
230248 --change skin redefinition for skinsdb
231249 function change_skin(player)
232250 local player_meta = player:get_meta()
251 if player_meta == nil then
252 -- The player disconnected before this function was dispatched
253 return
254 end
255
233256 local playername = player:get_player_name()
234257 local skinname = "character_creator:"..playername
235258 local skin_obj = skinsdb.get(skinname) or skinsdb.new(skinname)
236259 skin_obj:set_meta("format", "1.0")
237260 skin_obj:set_meta("visual_size_x", player_meta:get_float("character_creator:width"))
238261 skin_obj:set_meta("visual_size_y", player_meta:get_float("character_creator:height"))
239 skin_obj:apply_skin_to_player(player)
240 skinsdb.assign_player_skin(player, "character_creator:"..playername)
262 skinsdb.assign_player_skin(player, skinname)
263 skinsdb.update_player_skin(player)
241264 save_skin(player)
242265 end
243266 end
259282 function skin_obj:get_texture()
260283 return get_texture(minetest.get_player_by_name(self:get_meta("playername")))
261284 end
285 function skin_obj:get_hand()
286 local player = minetest.get_player_by_name(self:get_meta("playername"))
287 local skin_key = skins_array.skin[skin_indexes[player].skin]
288 local hand_skin = skinsdb.get("character_creator:"..skin_key)
289 if hand_skin then
290 return hand_skin:get_hand()
291 end
292 end
262293
263294 -- set data
264 skin_obj:set_preview("inventory_plus_character_creator.png")
265295 skin_obj:set_meta("name","Character Creator")
266296 --skin_obj:set_meta("author", "???")
267297 skin_obj:set_meta("license", "MIT / CC-BY-SA 3.0 Unported")
429459 title = "Character Creator",
430460 action = show_formspec,
431461 })
432 end
462
463 elseif not skinsdb and not minetest.get_modpath("sfinv_buttons")
464 and minetest.global_exists("sfinv") and sfinv.enabled then
465
466 local old_func = sfinv.pages["sfinv:crafting"].get
467 sfinv.override_page("sfinv:crafting", {
468 get = function(self, player, context)
469 local fs = old_func(self, player, context)
470 return fs .. "image_button[0,0;1,1;inventory_plus_character_creator.png;character_creator;]"
471 end
472 })
473
474 minetest.register_on_player_receive_fields(function(player, formname, fields)
475 if fields.character_creator then
476 show_formspec(player)
477 return true
478 end
479 end)
480 end
0 # textdomain: character_creator
1
2 ### init.lua ###
3 Cancel=Abbrechen
4 Done=Fertig
5 Female=Weiblich
6 Male=Männlich
7 Shorter=Kürzer
8 Taller=Länger
9 Thinner=Schmaler
10 Wider=Breiter
0 # textdomain: character_creator
1
2 ### init.lua ###
3 Cancel=
4 Done=
5 Female=
6 Male=
7 Shorter=
8 Taller=
9 Thinner=
10 Wider=
00 name = character_creator
11 description = Allows the creation of customized character skins inside the game.
22 license = MIT
3 optional_depends = 3d_armor, multiskin, inventory_plus, unified_inventory, skinsdb, sfinv_buttons
3 optional_depends = 3d_armor, multiskin, inventory_plus, unified_inventory, skinsdb, sfinv_buttons, sfinv
0 # Character Creator
1
02 This mod is attributed to the Voxelands project.
3 It allows you to customize your skin.
4
5 ![Screenshot](screenshot.png)
6
7 To change your skin, use either the chat commmand `/character_creator`
8 or a dedicated button in one of the supported inventory mods (see below).
9
10 ### Requirements
11
12 * Minetest 5.0.0 or newer
13
14 ### Supported mods
15
16 * multiskin
17 * 3d_armor
18 * sfinv (Minetest Game)
19 * unified_inventory
20 * sfinv_buttons
21 * inventory_plus
22
23
24 ### License
25
26 Code: MIT
27
28 Textures: CC BY-SA 3.0
29
30 See also: [license.txt](license.txt)
31
32 ### Credits
133
234 Voxelands creators:
3 sdzen
4 darkrose
35
36 * sdzen
37 * darkrose
Binary diff not shown
0 return {
0 -- TODO: Check if the indices are backwards-compatible after "translation"
1 --local S = character_creator.S
2
3 character_creator.skins = {
14 skin = {
25 ["Fair Skin"] = "cc_skin_fair.png",
36 ["Green Skin"] = "cc_skin_green.png",
248251 ["Yellow T-Shirt"] = "cc_tshirt_yellow.png",
249252 ["Black T-Shirt"] = "cc_tshirt_black.png",
250253 ["Blue T-Shirt"] = "cc_tshirt_blue.png",
254 ["Brown Vest"] = "cc_vest_brown.png",
255 ["Green Vest"] = "cc_vest_green.png",
256 ["Blue Vest"] = "cc_vest_blue.png",
257 ["Brown Shirt"] = "cc_shirt_canvas_brown.png",
258 ["Green Shirt"] = "cc_shirt_canvas_green.png",
259 ["Blue Shirt"] = "cc_shirt_canvas_blue.png",
251260 },
252261
253262 pants = {
259268 ["White Pants"] = "cc_pants_white.png",
260269 ["Yellow Pants"] = "cc_pants_yellow.png",
261270 ["Black Pants"] = "cc_pants_black.png",
271 ["Brown Canvas Pants"] = "cc_pants_canvas_brown.png",
272 ["Green Canvas Pants"] = "cc_pants_canvas_green.png",
273 ["Blue Canvas Pants"] = "cc_pants_canvas_blue.png",
262274 },
263275
264276 shoes = {
265277 ["Leather Shoes"] = "cc_shoes_leather.png",
266278 ["Canvas Shoes"] = "cc_shoes_canvas.png",
267279 ["Fur Shoes"] = "cc_shoes_fur.png",
280 ["Brown Shoes"] = "cc_shoes_brown.png",
281 ["Green Shoes"] = "cc_shoes_green.png",
282 ["Blue Shoes"] = "cc_shoes_blue.png",
283 ["Black Shoes"] = "cc_shoes_black.png",
268284 }
269285 }
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown