Add wearables API
This commit is contained in:
parent
9e63d7fe3a
commit
5e4d2924e4
14 changed files with 181 additions and 0 deletions
|
|
@ -3,6 +3,8 @@ rgt_cosmetics = {
|
|||
}
|
||||
local ns = rgt_cosmetics
|
||||
|
||||
include "wearables.lua"
|
||||
|
||||
--[[
|
||||
{
|
||||
name = "", -- Technical name
|
||||
|
|
|
|||
118
mods/rgt_cosmetics/wearables.lua
Normal file
118
mods/rgt_cosmetics/wearables.lua
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
local ns = rgt_cosmetics
|
||||
|
||||
ns.wearables = {}
|
||||
|
||||
--[[
|
||||
{
|
||||
name = "", -- Name of the wearable
|
||||
attachments = { -- List of individual attachments managed by this wearable (in case one wearable involves multiple bones)
|
||||
mesh = "", -- The wearable's mesh
|
||||
textures = {"", ...}, -- The wearable's textures
|
||||
bone = ", -- Name of the player bone to attach to
|
||||
pos = <vector>, -- Attachment offset
|
||||
rot = <vector>, -- Attachment rotation
|
||||
}
|
||||
}
|
||||
--]]
|
||||
function ns.register_wearable(def)
|
||||
ns.wearables[def.name] = def
|
||||
end
|
||||
|
||||
minetest.register_entity("rgt_cosmetics:wearable", {
|
||||
initial_properties = {
|
||||
visual = "mesh",
|
||||
pointable = false,
|
||||
static_save = false
|
||||
},
|
||||
on_activate = function(e)
|
||||
e.object:set_armor_groups{immortal = 1}
|
||||
end,
|
||||
represent = function(e, form)
|
||||
e.form = form
|
||||
e.object:set_properties {
|
||||
mesh = form.mesh,
|
||||
textures = form.textures
|
||||
}
|
||||
e.object:set_attach(e.owner.object, form.bone, form.pos, form.rot)
|
||||
if form.animation then
|
||||
e.object:set_animation(form.animation, form.animation.frame_speed or 1, nil, form.animation.loop)
|
||||
end
|
||||
end,
|
||||
on_deactivate = function(e, removed)
|
||||
-- Reactivate immediately if we were not explicitly marked for removal.
|
||||
-- This is to prevent wearables from being lost to unloading, and to
|
||||
-- minimize interference from mods that might try to remove objects
|
||||
-- they shouldn't try to remove. Note that we must check get_pos() here
|
||||
-- because, since on_leaveplayer is called _after_ mapblock unloading,
|
||||
-- the entity may otherwise attempt to reactivate itself when its
|
||||
-- owner has left the game (causing a crash).
|
||||
if not e._remove and e.owner.object:get_pos() then
|
||||
e.owner.wearing[e.form.name][e.index] = ns.apply_wearable_part(e.owner, e.form, e.index)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
function ns.apply_wearable_part(m, w, i)
|
||||
local obj = minetest.add_entity(m.pos, "rgt_cosmetics:wearable")
|
||||
local e = obj:get_luaentity()
|
||||
e.owner = m
|
||||
e.index = i
|
||||
e:represent(w)
|
||||
return obj
|
||||
end
|
||||
|
||||
function ns.apply_wearable(m, wearable)
|
||||
local w = type(wearable) == "string" and ns.wearables[wearable] or wearable
|
||||
-- Do nothing if we're already wearing this.
|
||||
if m.wearing[w.name] then return end
|
||||
local item = {}
|
||||
for i, x in ipairs(w.attachments) do
|
||||
x.name = w.name
|
||||
item[i] = ns.apply_wearable_part(m, x, i)
|
||||
end
|
||||
m.wearing[w.name] = item
|
||||
end
|
||||
|
||||
function ns.remove_wearable(m, wearable)
|
||||
if m.wearing[wearable] then
|
||||
for _, x in pairs(m.wearing[wearable]) do
|
||||
-- Explicitly mark the object for removal.
|
||||
x:get_luaentity()._remove = true
|
||||
x:remove()
|
||||
end
|
||||
m.wearing[wearable] = nil
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(p)
|
||||
local m = rgt.players[p:get_player_name()]
|
||||
for k in pairs(m.wearing) do
|
||||
ns.remove_wearable(m, k)
|
||||
end
|
||||
end)
|
||||
|
||||
ns.register_wearable {
|
||||
name = "top_hat",
|
||||
attachments = {
|
||||
{
|
||||
mesh = "rgt_top_hat.gltf",
|
||||
textures = {"rgt_top_hat.png"},
|
||||
bone = "Head",
|
||||
pos = vector.new(0, 3.5, 0),
|
||||
rot = vector.new(0, 0, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
minetest.register_chatcommand("wear", {
|
||||
func = function(name, args)
|
||||
ns.apply_wearable(rgt.players[name], args)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("unwear", {
|
||||
func = function(name, args)
|
||||
ns.remove_wearable(rgt.players[name], args)
|
||||
end
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue