summaryrefslogtreecommitdiff
path: root/mods/vzxv_pummel/init.lua
blob: c2ad767bf3b3c3002818b3dedc4b04986a56ba74 (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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
vzxv_pummel_recipes = {}
vzxv_pummels = {}

function sidename(pos)
    if pos.y == 1 then return 1 end
    if pos.y == -1 then return 2 end
    if pos.x == 1 then return 3 end
    if pos.x == -1 then return 4 end
    if pos.z == 1 then return 5 end
    return 6
end

local function sidecheck(sides,side)
    if not sides then return true end
    if type(sides) == "table" then
        for i,v in ipairs(sides) do
            if v == side then return v end
        end
        return false
    end
    return sides==side and side or false
end

local function toolcheck(tools,tool)
    local function singletoolcheck(st)
        if st:sub(1,5) == "group" then
            local num = tonumber(st:sub(6,6))
            local itgroup = minetest.get_item_group(tool,st:sub(8))
            return num <= itgroup
        else
            return tool == st
        end
    end
    if not tools then return true end
    if type(tools) == "table" then
        for i,v in ipairs(tools) do
            if singletoolcheck(v.item) then return v end
        end
        return false
    end
    return singletoolcheck(tool)
end

function vzxv.can_pummel(pos,node,tool,side)
    if vzxv_pummel_recipes[node.name] then
        for _,r in ipairs(vzxv_pummel_recipes[node.name]) do
            if not sidecheck(r.side,sidename(side)) then return false end
            if not toolcheck(r.tool,tool) then return false end
            if r.othernodes then
                for _,node in ipairs(r.othernodes) do
                    local outputpos = deepclone(pos)
                    outputpos.x = outputpos.x + (node.x or 0)
                    outputpos.y = outputpos.y + (node.y or 0)
                    outputpos.z = outputpos.z + (node.z or 0)
                    if node.item then
                        error("sorry no item inputs yet")
                    else
                        local node_at = minetest.get_node(outputpos).name
                        if not toolcheck(node.node,node_at) then
                            return false
                        end
                    end
                end
            end
            return r
        end
    end
    return false
end

function vzxv.pummel(pos,node,tool,side)
    local recipe = vzxv.can_pummel(pos,node,tool,side)
    if not recipe then return false end
    if recipe.func then recipe.func(pos,node,tool,side) end
    local nodes_involved = {recipe.node or recipe.item}
    for _,node in ipairs(recipe.othernodes or {}) do
        table.insert(nodes_involved,node)
    end

    for _,node in ipairs(nodes_involved) do
        local outputpos = deepclone(pos)
        outputpos.x = outputpos.x + (node.x or 0)
        outputpos.y = outputpos.y + (node.y or 0)
        outputpos.z = outputpos.z + (node.z or 0)
        if node.item then
            error("no item inputs yet sorry")
        else
            if node.consume then
                minetest.set_node(outputpos,{name="air"})
            end
        end
    end
    

    if recipe.outputs then
        for _,output in ipairs(recipe.outputs) do
            local outputpos = deepclone(pos)
            outputpos.x = outputpos.x + (output.x or 0)
            outputpos.y = outputpos.y + (output.y or 0)
            outputpos.z = outputpos.z + (output.z or 0)
            if output.item then
                vzxv.drop(outputpos,ItemStack({
                    name=output.item,
                    count=output.count or 1,
                }))
            else
                minetest.set_node(outputpos,{name=output.node})
            end
        end
    end
end

function vzxv.add_pummel_recipe(settings)
    local nodetype = settings.node.node or settings.node.item
    vzxv_pummel_recipes[nodetype] = vzxv_pummel_recipes[nodetype] or {}
    table.insert(vzxv_pummel_recipes[nodetype],settings)
end

minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing)
    local side = {
        x = pointed_thing.above.x - pos.x,
        y = pointed_thing.above.y - pos.y,
        z = pointed_thing.above.z - pos.z,
    }
    local meta = puncher:get_meta()
    local time = os.time()
    local itemname = puncher:get_wielded_item():get_name()
    local posstring = pos.x.." "..pos.y.." "..pos.z
    local nodename = node.name
    local sidename_ = sidename(side)
    local pummelname = itemname..posstring..nodename..sidename_
    if vzxv.can_pummel(pos,node,itemname,side) then
        if time - meta:get_int("vzxv_lastpummeltime") > 2 or meta:get_string("vzxv_lastpummel") ~= pummelname then
            meta:set_string("vzxv_lastpummel",pummelname)
            meta:set_int("vzxv_pummels",0)
        end
        meta:set_int("vzxv_lastpummeltime",time)
        if meta:get_string("vzxv_lastpummel") == pummelname then
            local pummels = meta:get_int("vzxv_pummels")
            meta:set_int("vzxv_pummels",pummels+1)
            for i=1, 5 do
                minetest.add_particle({
                    pos = {
                        x=pos.x + side.x/2 + (1-side.x)*math.random(-5,5)/10,
                        y=pos.y + side.y/2 + (1-side.y)*math.random(-5,5)/10,
                        z=pos.z + side.z/2 + (1-side.z)*math.random(-5,5)/10,
                    },
                    velocity = side,
                    expirationtime = 0.5 + math.random(0,5)/10,
                    texture = minetest.registered_nodes[nodename].tiles[1]
                })
            end
            if pummels==7 then
                meta:set_int("vzxv_pummels",0)
                vzxv.pummel(pos,node,itemname,side)
            end
        else
            meta:set_string("vzxv:lastpummel",pummelname)
        end
    end
end)
vzxv.include("recipes.lua")