-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathxpgate.lua
176 lines (140 loc) · 4.53 KB
/
xpgate.lua
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
local has_protector_mod = minetest.get_modpath("protector")
local update_formspec = function(meta)
local threshold = meta:get_int("xpthreshold")
local mode = meta:get_int("mode")
local mode_str = "Mode: <Min XP required>"
if mode == 1 then
mode_str = "Mode: <Max XP allowed>"
end
meta:set_string("infotext", "XP Gate, threshold: " .. threshold .. " " .. mode_str)
meta:set_string("formspec", "size[6,4;]" ..
"field[0,1;6,1;xpthreshold;XP Threshold;" .. threshold .. "]" ..
"button[0,2;6,1;toggle_mode;" .. mode_str .. "]" ..
"button_exit[0,3.2;6,1;save;Save]"
)
end
minetest.register_node("xp_redo:xpgate", {
description = "XP Gateway",
tiles = {"xp_gate.png"},
groups = {cracky=3,oddly_breakable_by_hand=3,epic=1},
is_ground_content = false,
drop = "xp_redo:xpgate",
sounds = default.node_sound_glass_defaults(),
on_rotate = minetest.get_modpath("screwdriver") and screwdriver.rotate_simple or nil,
paramtype2 = "facedir",
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "")
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_int("xpthreshold", 10)
meta:set_int("mode", 0)-- 0=min xp required, 1=max xp allowed
update_formspec(meta)
end,
on_receive_fields = function(pos, _, fields, sender)
local meta = minetest.get_meta(pos)
local name = sender:get_player_name()
if name == meta:get_string("owner") then
if fields.toggle_mode then
local mode = meta:get_int("mode")
if mode == 1 then
meta:set_int("mode", 0)
else
meta:set_int("mode", 1)
end
end
-- owner
if fields.xpthreshold then
local xpthreshold = tonumber(fields.xpthreshold)
if xpthreshold ~= nil then
meta:set_int("xpthreshold", xpthreshold)
end
end
update_formspec(meta)
end
end,
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
local name = player:get_player_name()
return name == meta:get_string("owner")
end,
epic = {
on_enter = function(_, meta, player, ctx)
local xp_threshold = meta:get_int("xpthreshold")
local mode = meta:get_int("mode")
local name = player:get_player_name()
local xp = xp_redo.get_xp(name)
if mode == 1 and xp <= xp_threshold then
-- max xp
ctx.next()
elseif mode == 0 and xp >= xp_threshold then
-- min xp
ctx.next()
end
end
}
})
local override_door = function(name, yoffset)
local doorDef = minetest.registered_nodes[name]
if doorDef ~= nil then
-- override door def
local doorRightClick = doorDef.on_rightclick
doorDef.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local ppos = clicker:get_pos()
local gate = minetest.find_node_near(pos, 2, {"xp_redo:xpgate"})
if gate ~= nil then
minetest.log("action", "[xp-gate] clicked by player " ..
clicker:get_player_name() .. " @ " ..
ppos.x .. "/" .. ppos.y .. "/" .. ppos.z)
-- xp limited door
local meta = minetest.get_meta(gate)
local mode = meta:get_int("mode")
local xpthreshold = meta:get_int("xpthreshold")
local playername = clicker:get_player_name()
local xp = xp_redo.get_xp(playername)
local err_msg
local allowed
if mode == 1 then
-- max xp allowed
allowed = xp <= xpthreshold
err_msg = "Too much xp, maximum allowed: " .. xpthreshold
else
-- min xp required
allowed = xp >= xpthreshold
err_msg = "Not enough xp, minimum required: " .. xpthreshold
end
if allowed then
local dir = vector.direction(ppos, pos)
local newPos = vector.add(pos, dir)
-- use y from door
newPos.y = pos.y + yoffset
minetest.log("action", "[xp-gate] moving player to " .. newPos.x .. "/" .. newPos.y .. "/" .. newPos.z)
clicker:moveto(newPos)
else
-- not allowed
minetest.log("action", "[xp-gate] player '" .. playername .. "' disallowed: " .. err_msg)
minetest.chat_send_player(playername, err_msg)
end
else
-- normal door, delegate
doorRightClick(pos, node, clicker, itemstack, pointed_thing)
end
end
end
end
if has_protector_mod then
override_door("protector:door_steel_b_1", -0.5)
override_door("protector:door_steel_b_2", -0.5)
override_door("protector:door_steel_t_1", -1.5)
override_door("protector:door_steel_t_2", -1.5)
end
override_door("doors:door_wood_b", -0.5)
minetest.register_craft({
output = 'xp_redo:xpgate',
recipe = {
{'doors:door_wood', '', 'doors:door_steel'},
{'group:wood', 'group:wood', 'group:wood'},
{'doors:door_steel', '', 'doors:door_wood'}
}
})