71885b5d47
Cats should have a pretty significant impact on the probability distribution of the color of cats hatching nearby.
216 lines
6.0 KiB
Lua
216 lines
6.0 KiB
Lua
-- LUALOCALS < ---------------------------------------------------------
|
|
local ipairs, math, minetest, nodecore, type, vector
|
|
= ipairs, math, minetest, nodecore, type, vector
|
|
local math_random
|
|
= math.random
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
local modname = minetest.get_current_modname()
|
|
local myapi = _G[modname]
|
|
|
|
local function faceallow(pos, param2)
|
|
local face = nodecore.facedirs[param2]
|
|
local fp = vector.add(pos, face.f)
|
|
return nodecore.sunlight_propagates(fp)
|
|
end
|
|
local function checkfacedir(pos)
|
|
local node = minetest.get_node(pos)
|
|
if faceallow(pos, node.param2) then return end
|
|
local t = {}
|
|
for i = 0, 23 do
|
|
if faceallow(pos, i) then t[#t + 1] = i end
|
|
end
|
|
if #t < 1 then return end
|
|
node.param2 = t[math_random(1, #t)]
|
|
minetest.swap_node(pos, node)
|
|
return node
|
|
end
|
|
|
|
local function getcatid(node)
|
|
local catid = minetest.get_item_group(node.name, modname .. '_cat')
|
|
return catid > 0 and catid
|
|
end
|
|
local function longcatmatch(nodea, nodeb)
|
|
return getcatid(nodea) == getcatid(nodeb)
|
|
and vector.equals(
|
|
nodecore.facedirs[nodea.param2].f,
|
|
nodecore.facedirs[nodeb.param2].f)
|
|
end
|
|
myapi.longcatmatch = longcatmatch
|
|
local function findtail(pos, node, ishead)
|
|
local fd = nodecore.facedirs[node.param2]
|
|
local back = vector.add(pos, fd.k)
|
|
local bnode = minetest.get_node(back)
|
|
local istail = not longcatmatch(node, bnode)
|
|
|
|
local catname = not istail and findtail(back, bnode, false)
|
|
|
|
local part = ishead and istail and ":cat_"
|
|
or ishead and ":longcat_front_"
|
|
or istail and ":longcat_back_"
|
|
or ":longcat_mid_"
|
|
node.name = modname .. part .. getcatid(node)
|
|
if not istail then node.param2 = bnode.param2 end
|
|
|
|
local saved = minetest.get_meta(pos):to_table()
|
|
saved.fields.realname = saved.fields.realname or saved.fields.description
|
|
saved.fields.description = istail and saved.fields.realname or catname
|
|
nodecore.set_node_check(pos, node)
|
|
minetest.get_meta(pos):from_table(saved)
|
|
return saved.fields.description
|
|
end
|
|
local function findhead(pos, node)
|
|
local fd = nodecore.facedirs[node.param2]
|
|
local fore = vector.add(pos, fd.f)
|
|
local fnode = minetest.get_node(fore)
|
|
if longcatmatch(node, fnode) then
|
|
return findhead(fore, fnode)
|
|
end
|
|
findtail(pos, node, true)
|
|
end
|
|
local function checksnake(pos, node)
|
|
node = node or minetest.get_node(pos)
|
|
if not getcatid(node) then return end
|
|
return findhead(pos, node)
|
|
end
|
|
|
|
local function reg(id, base, spot)
|
|
myapi.maxcatid = ((not myapi.maxcatid) or (id > myapi.maxcatid)) and id or myapi.maxcatid
|
|
local txr = "nc_cats_base.png^[multiply:" .. base .. ":255"
|
|
if base ~= spot then
|
|
txr = txr .. "^(nc_cats_spots.png^[multiply:" .. spot .. ":255)"
|
|
end
|
|
local basedef = {
|
|
description = "Cat",
|
|
tiles = {
|
|
txr .. "^nc_cats_ears.png",
|
|
txr .. "^nc_cats_paws_front.png^nc_cats_paws_back.png",
|
|
txr,
|
|
txr,
|
|
txr .. "^nc_cats_tail.png",
|
|
txr .. "^nc_cats_face.png",
|
|
},
|
|
groups = {
|
|
snappy = 1,
|
|
falling_node = 1,
|
|
[modname .. "_cat"] = id
|
|
},
|
|
stack_max = 1,
|
|
paramtype2 = "facedir",
|
|
on_place = function(stack, placer, pointed, inf, orient, ...)
|
|
orient = orient or {}
|
|
orient.invert_wall = pointed.above.y == pointed.under.y
|
|
return minetest.rotate_and_place(stack, placer, pointed, inf, orient, ...)
|
|
end,
|
|
sounds = nodecore.sounds(modname .. "_mew"),
|
|
drop = modname .. ":cat_" .. id,
|
|
preserve_metadata = function(_, _, oldmeta, drops)
|
|
if oldmeta.realname then
|
|
oldmeta.description = oldmeta.realname
|
|
oldmeta.realname = nil
|
|
end
|
|
drops[1]:get_meta():from_table({fields = oldmeta})
|
|
end,
|
|
after_place_node = function(pos, _, itemstack)
|
|
local node = checkfacedir(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:from_table(itemstack:get_meta():to_table())
|
|
myapi.setname(meta)
|
|
checksnake(pos, node)
|
|
end,
|
|
after_destruct = function(pos)
|
|
for _, dir in ipairs(nodecore.dirs()) do
|
|
local p = vector.add(pos, dir)
|
|
checksnake(p)
|
|
end
|
|
end
|
|
}
|
|
minetest.register_node(modname .. ":cat_" .. id, nodecore.underride({
|
|
groups = {
|
|
[modname .. "_face"] = 1
|
|
}
|
|
}, basedef))
|
|
minetest.register_node(modname .. ":longcat_front_" .. id,
|
|
nodecore.underride({
|
|
description = "LongCat",
|
|
tiles = {
|
|
txr .. "^nc_cats_ears.png",
|
|
txr .. "^nc_cats_paws_front.png",
|
|
txr,
|
|
txr,
|
|
txr,
|
|
txr .. "^nc_cats_face.png",
|
|
},
|
|
groups = {
|
|
falling_node = 0,
|
|
[modname .. "_face"] = 1,
|
|
[modname .. "_longcat"] = 1
|
|
},
|
|
drop = modname .. ":cat_" .. id
|
|
}, basedef))
|
|
minetest.register_node(modname .. ":longcat_mid_" .. id,
|
|
nodecore.underride({
|
|
description = "LongCat",
|
|
tiles = {
|
|
txr,
|
|
txr .. "^nc_cats_paws_mid.png",
|
|
txr,
|
|
txr,
|
|
txr,
|
|
txr,
|
|
},
|
|
groups = {
|
|
falling_node = 0,
|
|
[modname .. "_longcat"] = 1
|
|
},
|
|
drop = modname .. ":cat_" .. id
|
|
}, basedef))
|
|
minetest.register_node(modname .. ":longcat_back_" .. id,
|
|
nodecore.underride({
|
|
description = "LongCat",
|
|
tiles = {
|
|
txr,
|
|
txr .. "^nc_cats_paws_back.png",
|
|
txr,
|
|
txr,
|
|
txr .. "^nc_cats_tail.png",
|
|
txr,
|
|
},
|
|
groups = {
|
|
falling_node = 0,
|
|
[modname .. "_longcat"] = 1
|
|
},
|
|
drop = modname .. ":cat_" .. id
|
|
}, basedef))
|
|
end
|
|
|
|
reg(1, "#c0c0c0", "#404040") -- light gray
|
|
reg(2, "#404040", "#202020") -- mid gray
|
|
reg(3, "#202020", "#101010") -- dark gray
|
|
reg(4, "#ff8000", "#804000") -- dark orange
|
|
reg(5, "#e0c040", "#ff8000") -- light orange
|
|
reg(6, "#804000", "#402000") -- dark brown
|
|
reg(7, "#c0a080", "#806020") -- light brown
|
|
|
|
function myapi.makecat(pos, param2)
|
|
local probs = {}
|
|
for i = 1, myapi.maxcatid do
|
|
probs[i] = 1
|
|
end
|
|
for _, np in ipairs(nodecore.find_nodes_around(pos,
|
|
{"group:" .. modname .. "_cat"}, 2)) do
|
|
local id = getcatid(minetest.get_node(np))
|
|
if id and probs[id] then
|
|
probs[id] = probs[id] * 1.2
|
|
end
|
|
end
|
|
local _, newid = nodecore.pickrand(probs,
|
|
function(v) return v end)
|
|
nodecore.set_loud(pos, {
|
|
name = modname .. ":cat_" .. newid,
|
|
param2 = type(param2) == "number" and param2
|
|
or math_random(0, 3)
|
|
})
|
|
myapi.setname(minetest.get_meta(pos))
|
|
end
|