--[[ Eleficery --- Elemental trinkets for minetest game Copyright © 2026 bdunahu This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . --]] core.register_node("eleficery:ice_packed", { description = "Packed Ice", tiles = {"ice_packed.png"}, groups = { cracky = 2, cools_lava = 1, slippery = 2, }, sounds = default.node_sound_ice_defaults(), }) local serpent_body_def = { description = "Serpent Body", tiles = {"serpent_body.png"}, paramtype = "light", light_source = 5, use_texture_alpha = 'clip', sunlight_propagates = true, drawtype = "glasslike_framed_optional", groups = { cracky = 3, cools_lava = 1, slippery = 5, not_in_creative_inventory = 1, }, sounds = default.node_sound_ice_defaults(), drop = "", } local serpent_head_def = table.copy(serpent_body_def) serpent_head_def.description = "Serpent Head" serpent_head_def.after_place_node = function(pos, placer, itemstack, pointed_thing) local meta = core.get_meta(pos) local pname = placer:get_player_name() meta:set_string("placer", pname) meta:set_string("prev_pos", minetest.serialize(pos)) meta:set_string( "prev_dir", core.serialize(eleficery.snap_to_cardinal(placer:get_look_dir())) ) meta:set_float("decay", eleficery.SERPENT_LIFETIME) local timer = core.get_node_timer(pos) timer:start(eleficery.SERPENT_GROWTH_RATE) core.log("action", pname .. " placed click_test_node") end serpent_head_def.on_timer = function(pos, elapsed) local meta = core.get_meta(pos) local decay = meta:get_float("decay") -- handle decay meta:set_float("decay", decay - elapsed) if decay <= 0 then core.set_node(pos, {name = "default:water_source"}) return false end -- handle growth local stored = meta:get_string("prev_pos") local prev_pos = core.deserialize(stored) local stored = meta:get_string("prev_dir") local prev_dir = core.deserialize(stored) local pname = meta:get_string("placer") local placer = core.get_player_by_name(pname) if placer then local wielded = placer:get_wielded_item() local ctrl = placer:get_player_control() if ctrl.RMB then -- the player is still clicking local dir = eleficery.get_held_dir_to_player(placer) prev_dir = dir or prev_dir prev_pos = vector.add( prev_pos, prev_dir ) if eleficery.is_water(prev_pos) then core.set_node(prev_pos, {name = "eleficery:serpent_body"}) core.after(eleficery.SERPENT_LIFETIME, function() if core.get_node(prev_pos).name == "eleficery:serpent_body" then core.set_node(prev_pos, {name = "default:water_source"}) end end) meta:set_string("prev_pos", core.serialize(prev_pos)) meta:set_string("prev_dir", core.serialize(prev_dir)) wielded:add_wear(65535 / (eleficery.SERPENT_MAX_TICKS - 1)) placer:set_wielded_item(wielded) return true else core.chat_send_player(pname, "Oh no! Your serpent crashed!") wielded:add_wear(65535) -- snap! placer:set_wielded_item(wielded) end end end meta:set_string("placer", nil) if placer then player_monoids.speed:del_change(placer, "eleficery:serpent") end return true end core.register_node("eleficery:serpent_body", serpent_body_def) core.register_node("eleficery:serpent_head", serpent_head_def)