97a04d8a5e
This allows for automated cat petting once again, but not trivially like before. Provision for the tool, AND activation timing, is needed now.
180 lines
4.8 KiB
Lua
180 lines
4.8 KiB
Lua
-- LUALOCALS < ---------------------------------------------------------
|
|
local math, minetest, nodecore, pairs, vector
|
|
= math, minetest, nodecore, pairs, vector
|
|
local math_abs, math_floor, math_random
|
|
= math.abs, math.floor, math.random
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
local modname = minetest.get_current_modname()
|
|
local myapi = _G[modname]
|
|
|
|
local furmetakey = "catprill"
|
|
|
|
nodecore.register_soaking_abm({
|
|
label = "cat furball",
|
|
fieldname = "furball",
|
|
nodenames = {"group:" .. modname .. "_cat"},
|
|
interval = 5,
|
|
arealoaded = 3,
|
|
soakrate = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
if (meta:get_float(furmetakey) or 0) ~= 0 then return false end
|
|
|
|
local found = #nodecore.find_nodes_around(pos,
|
|
"group:" .. modname .. "_face", 3)
|
|
return 2 ^ -math_abs(2 - found)
|
|
end,
|
|
soakcheck = function(data, pos)
|
|
if data.total < 1000 then return end
|
|
nodecore.log("action", "cat prill ready at " .. minetest.pos_to_string(pos))
|
|
minetest.get_meta(pos):set_float(furmetakey, 1)
|
|
return false
|
|
end
|
|
})
|
|
|
|
local purrtimes = {
|
|
1.676,
|
|
1.617,
|
|
1.642,
|
|
1.655
|
|
}
|
|
|
|
local hashpos = minetest.hash_node_position
|
|
local purring = {}
|
|
|
|
local purrgain = 0.15
|
|
|
|
local function playernear(pos)
|
|
for _, player in pairs(minetest.get_connected_players()) do
|
|
local ppos = player:get_pos()
|
|
ppos.y = ppos.y + player:get_properties().eye_height
|
|
local diff = vector.subtract(pos, ppos)
|
|
local dsqr = vector.dot(diff, diff)
|
|
if dsqr < 25 then return true end
|
|
end
|
|
end
|
|
|
|
local normaldraw = {}
|
|
minetest.after(0, function()
|
|
for k, v in pairs(minetest.registered_nodes) do
|
|
if v.drawtype == "normal" then
|
|
normaldraw[k] = true
|
|
end
|
|
end
|
|
end)
|
|
local function hearticles(pos, offs, time, qty)
|
|
if normaldraw[minetest.get_node(pos).name] then return end
|
|
minetest.add_particlespawner({
|
|
amount = math_floor(2 * qty),
|
|
time = time,
|
|
minpos = vector.add(pos, offs),
|
|
maxpos = vector.subtract(pos, offs),
|
|
texture = "nc_cats_heart.png",
|
|
minexptime = 1,
|
|
maxexptime = 2,
|
|
minsize = 1,
|
|
maxsize = 2,
|
|
glow = 4
|
|
})
|
|
end
|
|
local function hearticles_all(pos, time, qty)
|
|
local pdist = 0.55
|
|
for _, d in pairs({
|
|
{p = {x = pdist, y = 0, z = 0}, o = {x = 0, y = pdist, z = pdist}},
|
|
{p = {x = 0, y = pdist, z = 0}, o = {x = pdist, y = 0, z = pdist}},
|
|
{p = {x = 0, y = 0, z = pdist}, o = {x = pdist, y = pdist, z = 0}},
|
|
}) do
|
|
hearticles(vector.add(pos, d.p), d.o, time, qty)
|
|
hearticles(vector.subtract(pos, d.p), d.o, time, qty)
|
|
end
|
|
end
|
|
|
|
local function purr(pos, data)
|
|
purring[hashpos(pos)] = nodecore.gametime
|
|
|
|
local fade = data and data.presstoolpos
|
|
or math_random(1, 10) == 1 or not playernear(pos)
|
|
local id = math_random(1, #purrtimes)
|
|
local sh = nodecore.sound_play("nc_cats_purr_" .. id, {
|
|
pos = pos,
|
|
gain = purrgain,
|
|
not_ephemeral = fade
|
|
})
|
|
hearticles_all(pos, purrtimes[id], purrtimes[id])
|
|
if fade then
|
|
minetest.sound_fade(sh, -purrgain / purrtimes[id], 0)
|
|
return minetest.after(purrtimes[id], function()
|
|
purring[hashpos(pos)] = nil
|
|
end)
|
|
else
|
|
nodecore.dnt_set(pos, modname .. ":purr", purrtimes[id])
|
|
end
|
|
end
|
|
|
|
nodecore.register_dnt({
|
|
name = modname .. ":purr",
|
|
nodenames = {"group:" .. modname .. "_cat"},
|
|
action = purr
|
|
})
|
|
|
|
local function furballcheck(pos, node, ejectpos)
|
|
ejectpos = ejectpos or pos
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
local ready = meta:get_float(furmetakey) or 0
|
|
if ready > 0 then
|
|
nodecore.log("action", "cat ejects prill at " .. minetest.pos_to_string(pos))
|
|
nodecore.item_eject(ejectpos, modname .. ":prill", 5)
|
|
nodecore.witness(pos, "cat eject prill")
|
|
meta:set_float(furmetakey, 0)
|
|
end
|
|
|
|
node = node or minetest.get_node(pos)
|
|
if minetest.get_item_group(node.name, modname .. "_longcat") < 1 then return end
|
|
local fd = nodecore.facedirs[node.param2]
|
|
local back = vector.add(pos, fd.k)
|
|
local bnode = minetest.get_node(back)
|
|
if myapi.longcatmatch(node, bnode) then
|
|
return furballcheck(back, bnode, ejectpos)
|
|
end
|
|
end
|
|
local function purrstart(pos, data)
|
|
furballcheck(pos)
|
|
hearticles_all(pos, 0.05, 1)
|
|
return purr(pos, data)
|
|
end
|
|
|
|
function myapi.notpurring(pos)
|
|
local purrtime = purring[hashpos(pos)]
|
|
if purrtime and purrtime < nodecore.gametime - 2 then
|
|
purrtime = nil
|
|
purring[hashpos(pos)] = nil
|
|
end
|
|
return not purrtime and {}
|
|
end
|
|
|
|
local petdef = {
|
|
label = "pet cat",
|
|
action = "pummel",
|
|
indexkeys = {"group:" .. modname .. "_face"},
|
|
check = function(pos)
|
|
return myapi.notpurring(pos) and playernear(pos)
|
|
end,
|
|
nodes = {
|
|
{match = {
|
|
groups = {[modname .. "_cat"] = true},
|
|
stacked = false
|
|
}}
|
|
},
|
|
after = purrstart
|
|
}
|
|
nodecore.register_craft(nodecore.underride({
|
|
toolgroups = minetest.registered_items[""].tool_capabilities.groupcaps.cuddly
|
|
and {cuddly = 1} or {thumpy = 1},
|
|
}, petdef))
|
|
nodecore.register_craft(nodecore.underride({
|
|
wield = {groups = {rakey = true}},
|
|
consumewield = 1,
|
|
duration = 2
|
|
}, petdef))
|