summaryrefslogtreecommitdiff
path: root/nodes.lua
blob: 5c70565557bed893726d028ed4fd9ef3fe0306f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
--[[
Eleficery  --- Elemental trinkets for minetest game
Copyright © 2026 bdunahu <bdunahu@operationnull.com>

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 <https://www.gnu.org/licenses/>.
--]]

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)