wizards_api/init.lua

188 lines
5.3 KiB
Lua

local S, NS = minetest.get_translator("wizards_api")
local modpath = minetest.get_modpath("wizards_api")
local wizpath = modpath.."/wizards"
wizards_api = {}
wizards_api.wizards = {}
-- must only be used at run-time due to silly call-back requirement for add_media
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,
}, function() end)
end
wizards_api.wizards[conf.name] = conf
end
end
for i,dir in ipairs(dirs) do
wizards_api.load_wizards(path.."/"..dir)
end
for i,player in ipairs(core.get_connected_players()) do
wizards_api.reset_wizard(player:get_player_name())
end
end
function wizards_api.clear_and_load_wizards(path)
-- TODO: Handle players using a wizard about to be 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 = "[<wizard>]",
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 = "<player> <wizard>",
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 = "[<clear (y/n)>]",
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.reset_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.after(0, function()
wizards_api.load_wizards(wizpath)
end)
core.register_on_joinplayer(function(player)
wizards_api.reset_wizard(player:get_player_name())
end)