Skip to content

Instantly share code, notes, and snippets.

@GreenXenith GreenXenith/stocking.lua Secret
Last active Nov 16, 2017

Embed
What would you like to do?
christmas stockings
local stocking = {}
local stuffer = {}
stuffer.stuffers = {}
local storage = minetest.get_mod_storage()
function stuffer.register_stuff(name, count)
if count == nil then count = 1 end
local stuff = {
name = name,
count = count,
metadata = "",
}
table.insert(stuffer.stuffers, stuff)
end
function stuffer.select_stuffers(count)
local p_stuffers = {}
for i=1,#stuffer.stuffers do
table.insert(p_stuffers, stuffer.stuffers[i])
end
local itemstacks = {}
for i=1,#stuffer.stuffers do
itemstacks[i] = stuffer.stuff_to_itemstack(stuffer.stuffers[i])
end
return itemstacks
end
function stuffer.stuff_to_itemstack(stuff)
local itemstack = {}
itemstack.name = stuff.name
itemstack.count = stuffer.determine_count(stuff)
itemstack.metadata = stuff.metadata
return ItemStack(itemstack)
end
function stuffer.determine_count(stuff)
if(type(stuff.count)=="number") then
return stuff.count
end
end
stuffer.register_stuff("default:cobble",45) --test code
function stocking.get_stocking_formspec(pos)
local spos = pos.x .. "," .. pos.y .. "," ..pos.z
local formspec =
"size[9,9]"..
"background[-0.8,-0.4;10,10;stocking_bg.png]"..
"image_button_exit[7.75,1;1,1;exit_button.png;exit;]"..
"listcolors[#D4393C;#d45658]"..
"list[nodemeta:".. spos .. ";main;-0.2,2;8,2;]"..
"list[current_player;main;-0.2,5;8,4;]" ..
"listring[current_player;main]"
return formspec
end
stocking.can_dig_function = function(pos, player)
local meta = minetest.get_meta(pos);
local name = player and player:get_player_name()
local owner = meta:get_string("owner")
local inv = meta:get_inventory()
return name == owner and inv:is_empty("main")
end
local year = tonumber(os.date("%Y"))
local month = tonumber(os.date("%m"))
local day = tonumber(os.date("%d"))
local second = tonumber(os.date("%S"))
local minute = tonumber(os.date("%M"))
--[[local nextyear
local addyear = function()
if month > 11 then
if day > 25 then
nextyear = year + 1
else
nextyear = year
end
else
nextyear = year
end
end]]
minetest.register_node("christmas_decor:stocking", {
description = "Stocking",
drawtype = "mesh",
mesh = "stocking.obj",
tiles = {"velvet_fluff.png"},
use_texture_alpha = true,
inventory_image = "inv_stocking.png",
wield_image = "inv_stocking.png",
walkable = false,
selection_box = {
type = "fixed",
fixed = {-0.4, -0.5, 0.5, 0.4, 0.5, 0.2},
},
collision_box = {
type = "fixed",
fixed = {-0.4, -0.5, 0.5, 0.4, 0.5, 0.2},
},
paramtype = "light",
sunlight_propagates = true,
paramtype2 = "facedir",
groups = {snappy = 3},
sounds = default.node_sound_leaves_defaults(),
-- local next_fill_year
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if player then
minetest.chat_send_player(player:get_player_name(),
"Wait until Christmas Eve for Santa to fill your stocking!")
return 0
end
end,
on_place = function(itemstack, placer, pointed_thing)
if minetest.is_yes(placer:get_attribute("has_placed_stocking")) then
minetest.chat_send_player(placer:get_player_name(),
"Santa won't fill more than one stocking!")
return itemstack
else
return minetest.item_place(itemstack, placer, pointed_thing)
end
end,
on_construct = function(pos, itemstack, pointed_thing)
local second = tonumber(os.date("%S"))
local minute = tonumber(os.date("%M"))
local meta = minetest.get_meta(pos)
if second > 10 then
meta:set_int("next_min", minute + 1)
minetest.log("none", "second is " ..second.. " which is greater than 10, setting fill date to next minute (" .. minute + 1 ..") from current minute (" .. minute .. ")")
elseif second <= 10 then
meta:set_int("next_min", minute)
minetest.log("none", "second is " ..second.. " which is less than 10, setting fill date to current minute (" .. minute ..")")
end
end,
after_place_node = function(pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta(pos)
local owner = placer:get_player_name()
meta:set_string("owner", owner)
meta:set_string("infotext", owner.."'s Stocking")
local inv = meta:get_inventory()
inv:set_size("main", 8*2)
--[[if month > 11 then
if day > 24 then
next_fill_year = year + 1
else
next_fill_year = year
end
else
next_fill_year = year
end]]
if minetest.is_yes(meta:get_string("can_fill")) and placer:get_attribute("stocking_dug_filled", "true") then
-- placer:set_attribute("stocking_filled", "true")
minetest.log("none", "dug after filled, stocking_filled = true")
end
--[[ if minetest.is_yes(storage:get_string("reset_filled")) then
placer:set_attribute("stocking_filled", "false")
placer:set_attribute("stocking_dug_filled", "false")
meta:set_int("has_filled", 0)
minetest.log("none", "reset detected, stocking_filled dug_filled meta:has_filled = false")
end]]
placer:set_attribute("has_placed_stocking", "true")
if minetest.is_yes(placer:get_attribute("stocking_filled")) then
meta:set_int("has_filled", 1)
minetest.log("none", "stocking was already filled, set stocking to filled = true.")
elseif minetest.is_yes(placer:get_attribute("stocking_filled")) then
meta:set_int("has_filled", 0)
minetest.log("none", "stocking not already filled, allowing to fill.")
end
end,
on_rightclick = function(pos, node, clicker, itemstack)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local player = clicker:get_player_name()
local stuffers = stuffer.select_stuffers()
--[[if year == next_fill_year then
if month > 11 then
if day > 24 then
met:set_int("can_fill", 1)
else
meta:set_int("can_fill", 0)
end
else
meta:set_int("can_fill", 0)
end
elseif year == next_fill_year + 1 then
if month < 12 then
meta:set_int("can_fill", 1)
elseif month == 12 then
if day < 25 then
meta:set_int("can_fill", 1)
else
meta:set_int("can_fill", 0)
end
end
end]]
local second = tonumber(os.date("%S"))
local minute = tonumber(os.date("%M"))
if minute == meta:get_int("next_min") then
minetest.log("none", "[FILL_CHECK]: minute is " ..minute.. " which is equal to next_min (".. tostring(meta:get_int("next_min")) .. "), checking second...")
if second > 9 then
meta:set_int("can_fill", 1)
clicker:set_attribute("stocking_filled", "false")
minetest.log("none", "[FILL_CHECK]: second is " ..second.. " which is greater than than 9, allowing fill.")
else
meta:set_int("can_fill", 0)
minetest.log("none", "[FILL_CHECK]: second is " ..second.. " which is less than (or equal to) 9, disallowing fill.")
end
elseif minute == meta:get_int("next_min") + 1 then
minetest.log("none", "[FILL_CHECK]: minute is " ..minute.. " which is equal to next_min (".. tostring(meta:get_int("next_min")) .. " + 1), checking second...")
if second < 10 then
meta:set_int("can_fill", 1)
clicker:set_attribute("stocking_filled", "false")
minetest.log("none", "[FILL_CHECK]: second is " ..second.. " which is less than 10, allowing fill.")
else
meta:set_int("can_fill", 0)
minetest.log("none", "[FILL_CHECK]: second is " ..second.. " which is greater than (or equal to) 10, disallowing fill.")
end
end
--[[ if minetest.is_yes(storage:get_string("reset_filled")) then
clicker:set_attribute("stocking_filled", "false")
clicker:set_attribute("stocking_dug_filled", "false")
meta:set_int("has_filled", 0)
minetest.log("none", "reset detected, stocking_filled dug_filled meta:has_filled = false")
end]]
if minetest.is_yes(meta:get_string("can_fill")) then
if meta:get_int("has_filled") == 0 then
for i=1, #stuffers do
inv:set_stack("main", i, stuffers[i])
end
meta:set_int("has_filled", 1)
clicker:set_attribute("stocking_filled", "true")
minetest.log("none", "Hasnt been filled, is now filled, can no longer fill.")
end
end
local owner = meta:get_string("owner")
if owner == player then
minetest.show_formspec(
clicker:get_player_name(),
"default:chest_locked",
stocking.get_stocking_formspec(pos))
else
return itemstack
end
return itemstack
end,
can_dig = stocking.can_dig_function,
on_metadata_inventory_move = function(pos, from_list, from_index,
to_list, to_index, count, player)
minetest.log("action", player:get_player_name() ..
" moves stuff in stocking at " .. minetest.pos_to_string(pos))
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" moves stuff to stocking at " .. minetest.pos_to_string(pos))
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" takes stuff from stocking at " .. minetest.pos_to_string(pos))
end,
on_dig = function(pos, node, digger)
local meta = minetest.get_meta(pos)
if stocking.can_dig_function(pos, digger) then
digger:set_attribute("has_placed_stocking", "false")
--[[ if minetest.is_yes(storage:get_string("reset_filled")) then
digger:set_attribute("stocking_filled", "false")
digger:set_attribute("stocking_dug_filled", "false")
minetest.log("none", "reset detected, stocking_filled dug_filled meta:has_filled = false")
end]]
if minetest.is_yes(meta:get_string("can_fill")) and digger:get_attribute("stocking_filled", "true") then
digger:set_attribute("stocking_dug_filled", "true")
minetest.log("none", "Dug after filled, dug_filled = true.")
end
minetest.remove_node(pos)
end
end
})
function stocking.enable_can_fill()
storage:set_string("can_fill", "true")
minetest.log("none", "fill enabled")
end
function stocking.disable_has_filled_reset()
storage:set_string("reset_filled", "false")
minetest.log("none", "disable reset stocking fill")
end
minetest.register_chatcommand("enable_fill", {
description = "Allow stockings to be filled.",
privs = {protection_bypass = true},
func = function(name, param)
stocking.disable_has_filled_reset()
stocking.enable_can_fill()
minetest.chat_send_player(name, "Stockings are now fillable.")
end
})
function stocking.disable_can_fill()
storage:set_string("can_fill", "false")
minetest.log("none", "fill disabled")
end
minetest.register_chatcommand("disable_fill", {
description = "Prevent stockings from being filled.",
privs = {protection_bypass = true},
func = function(name, param)
stocking.disable_can_fill()
minetest.chat_send_player(name, "Stockings are no longer fillable.")
end
})
function stocking.reset_has_filled()
storage:set_string("reset_filled", "true")
minetest.log("none", "reset stocking fill")
end
minetest.register_chatcommand("newyear", {
description = "Reset stockings for new year (not necessarily for the new year).",
privs = {protection_bypass = true},
func = function(name, param)
stocking.disable_can_fill()
stocking.reset_has_filled()
minetest.chat_send_player(name, "Stockings are ready for next Christmas. can_fill = false, has_filled = false")
end
})
-- Below commands are for testing purposes
minetest.register_chatcommand("systime", {
func = function(name)
local time = os.date("%I:%M:%S")
minetest.chat_send_player(name, "Time is " .. time)
end
})
minetest.register_chatcommand("second", {
func = function(name)
local second = os.date("%S")
if tonumber(second) > 30 then
minetest.chat_send_player(name, "Current second is " .. second .. " which is greater than 30.")
elseif tonumber(second) < 30 then
minetest.chat_send_player(name, "Current second is " .. second .. " which is less than 30.")
else
minetest.chat_send_player(name, "Current second is " .. second .. " which is exactly 30.")
end
end
})
function stocking.cs(player)
if type(player) == "string" then
player = minetest.get_player_by_name(player)
player:set_attribute("has_placed_stocking", "false")
player:set_attribute("stocking_filled", "false")
else
minetest.chat_send_player(name, "type(player) != string")
end
end
minetest.register_chatcommand("cs", {
privs = {shout = true},
func = function(name, param)
stocking.cs(name)
minetest.chat_send_player(name, "Stocking stats reset.")
end
})
local stat_placed
function stocking.check_stats_has_placed(player)
if type(player) == "string" then
player = minetest.get_player_by_name(player)
stat_placed = tostring(player:get_attribute("has_placed_stocking"))
end
end
local stat_filled
function stocking.check_stats_have_filled(player)
if type(player) == "string" then
player = minetest.get_player_by_name(player)
stat_filled = tostring(player:get_attribute("stocking_filled"))
end
end
minetest.register_chatcommand("stats", {
privs = {shout = true},
func = function(name, param)
minetest.chat_send_player(name, "Your current stocking stats are:")
stocking.check_stats_has_placed(name)
minetest.chat_send_player(name, "stat_placed = " .. stat_placed)
stocking.check_stats_have_filled(name)
minetest.chat_send_player(name, "stat_filled = " .. stat_filled)
end
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.