local S, NS = minetest.get_translator("wizards_api") local modpath = minetest.get_modpath("wizards_api") local wizpath = modpath.."/wizards" wizards_api = {} wizards_api.wizards = {} function wizards_api.load_wizards(path) local files = core.get_dir_list(path, false) local dirs = core.get_dir_list(path, true) for i,filename in ipairs(files) do if filename:sub(-5,-1) == ".conf" then local conf = Settings(path.."/"..filename):to_table() conf.name = filename:sub(1,-6) conf.visual_size = conf.visual_size and vector.from_string(conf.visual_size) conf.eye_height = tonumber(conf.eye_height) conf.height = tonumber(conf.height) conf.width = tonumber(conf.width) for _,part in ipairs({ "", "_back", "_hand" }) do core.dynamic_add_media({ filename = "wizards_api_"..conf.name..part..".png", filepath = path.."/"..conf.name..part..".png", ephemeral = false, }) end wizards_api.wizards[conf.name] = conf end end for i,dir in ipairs(dirs) do wizards_api.load_wizards(path.."/"..dir) end end function wizards_api.clear_and_load_wizards(path) -- TODO: Handle players using a wizard about to be cleared. -- Maybe a boolean to have in-use wizards not cleared? for name,conf in pairs(wizards_api.wizards) do wizards_api.wizards[name] = nil end return wizards_api.load_wizards(path) end core.register_privilege("wizards_api_set", { description = "The ability to set your own wizard skin.", give_to_singleplayer = true, }) core.register_privilege("wizards_api_manage", { description = "The ability to set anyone's wizard skin.", give_to_singleplayer = true, }) core.register_privilege("wizards_api_config", { description = "Configuration powers for wizards_api.", give_to_singleplayer = true, }) core.register_chatcommand("wizard_setme", { params = "[]", description = "Set your wizard skin.", privs = { wizards_api_set=true }, func = function(name, param) local wizname = param:match("^([^ ]+)$") if not wizname then local names = {} for name,conf in pairs(wizards_api.wizards) do names[#names+1] = name end return false, "Available wizards: "..table.concat(names, ", ") end return wizards_api.set_wizard(name, wizname) end, }) core.register_chatcommand("wizard_set", { params = " ", description = "Set someone's wizard skin.", privs = { wizards_api_manage=true }, func = function(name, param) local playername, wizname = param:match("^([^ ]+) +([^ ]+)$") if not (playername and wizname) then return false end return wizards_api.set_wizard(playername, wizname) end, }) core.register_chatcommand("wizard_reload", { params = "[]", description = "Reload wizards_api files, optionally clearing all existing wizards.", privs = { wizards_api_config=true }, func = function(name, param) -- succ, msg -- false, nil -> help if core.is_yes(param) then return wizards_api.clear_and_load_wizards(wizpath) else return wizards_api.load_wizards(wizpath) end end, }) do -- TODO: Maybe ":" isn't registered by default and that means meta doesn't work? -- core.override_item(":", { -- wield_image = "wizard_twoo_hand.png", -- }) local hand_def = {} for k,v in pairs(core.registered_items[""]) do if k ~= "mod_origin" and k ~= "type" then hand_def[k] = v end end core.register_tool("wizards_api:hand", hand_def) end function wizards_api.reload_wizard(playername) local player = core.get_player_by_name(playername) local meta = player:get_meta() local wizname = meta:get("wizards_api_wizard") or "wizard_green" return wizards_api.set_wizard(playername, wizname) end function wizards_api.set_wizard(playername, wizname) local player = core.get_player_by_name(playername) if not player then return nil, "unable to find player" end local conf = wizards_api.wizards[wizname] if not conf then return nil, "unable to find wizard skin" end local meta = player:get_meta() meta:set_string("wizards_api_wizard", wizname) -- get/set_eye_offset local props = player:get_properties() props.visual = "upright_sprite" -- "sprite" props.textures = { "wizards_api_"..wizname..".png", "wizards_api_"..wizname.."_back.png", } props.eye_height = conf.eye_height or 1.625 props.visual_size = conf.visual_size or vector.new(1,2,1) local rad = conf.width/2 props.collisionbox = { -rad, 0, -rad, rad, conf.height, rad } props.selectionbox = nil -- props.spritediv = { x=1, y=1 } -- props.initial_sprite_basepos = { x=0, y=0 } -- props.makes_footstep_sound = false -- props.glow = 0 -- props.shaded = true props.collide_with_objects = true player:set_properties(props) local inv = player:get_inventory() inv:set_size("hand", 1) -- local hand = inv:get_stack("hand", 1) local hand = ItemStack("wizards_api:hand") --hand:set_count(1) --core.debug(hand:set_name("")) local handmeta = hand:get_meta() handmeta:set_string("wield_image", "wizards_api_"..wizname.."_hand.png") -- handmeta:set_string("wield_overlay", ...) -- handmeta:set_string("wield_scale", vector.to_string(vector.new(1,1,1))) inv:set_stack("hand", 1, hand) end core.register_on_mods_loaded(function() wizards_api.load_wizards(wizpath) end) core.register_on_joinplayer(function(player) wizards_api.reload_wizard(player:get_player_name()) end)