-
Notifications
You must be signed in to change notification settings - Fork 10
/
bookmark.lua
159 lines (134 loc) · 4.13 KB
/
bookmark.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
local book_item, book_written = ""
if minetest.get_modpath("default") then
book_item = "default:book"
book_written = "default:book_written"
end
if minetest.get_modpath("mcl_books") then
book_item = "mcl_books:book"
book_written = "mcl_books:written_book"
end
jumpdrive.write_to_book = function(pos, sender)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:contains_item("main", {name=book_item, count=1}) then
local stack = inv:remove_item("main", {name=book_item, count=1})
local new_stack = ItemStack(book_written)
local data = {}
data.owner = sender:get_player_name()
data.title = "Jumpdrive coordinates"
data.description = "Jumpdrive coordinates"
data.text = minetest.serialize(jumpdrive.get_meta_pos(pos))
data.page = 1
data.page_max = 1
new_stack:get_meta():from_table({ fields = data })
if inv:room_for_item("main", new_stack) then
-- put written book back
inv:add_item("main", new_stack)
else
-- put back old stack
inv:add_item("main", stack)
end
end
end
local function has_nil(pos)
if nil == pos
or nil == pos.x
or nil == pos.y
or nil == pos.z
then
return true
end
return false
end
local function sanitize_and_set_coordinates(meta, pos)
meta:set_int("x", jumpdrive.sanitize_coord(pos.x))
meta:set_int("y", jumpdrive.sanitize_coord(pos.y))
meta:set_int("z", jumpdrive.sanitize_coord(pos.z))
end
jumpdrive.read_from_book = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local player_name = meta:get_string("owner")
local inv_size = inv:get_size("main")
local stack
local stack_name
local stack_meta
local text
local target_pos
for i = inv_size, 1, -1 do
stack = inv:get_stack("main", i)
stack_name = stack:get_name()
if book_written == stack_name then
-- remove item from inventory
inv:set_stack("main", i, ItemStack())
stack_meta = stack:get_meta()
text = stack_meta:get_string("text")
local data = minetest.deserialize(text)
if has_nil(data) then
-- put book back where it was, it may contain other information
inv:set_stack("main", i, stack)
else
target_pos = {
x = tonumber(data.x),
y = tonumber(data.y),
z = tonumber(data.z)
}
if has_nil(target_pos) then
-- put book back where it was, it may contain other information
inv:set_stack("main", i, stack)
-- alert player
if nil ~= player_name then
minetest.chat_send_player(player_name, "Invalid coordinates")
end
return
end
sanitize_and_set_coordinates(meta, target_pos)
-- put book back to next free slot
inv:add_item("main", stack)
return
end
elseif "missions:wand_position" == stack_name then
-- remove item from inventory
inv:set_stack("main", i, ItemStack())
stack_meta = stack:get_meta()
text = stack_meta:get_string("pos")
target_pos = minetest.string_to_pos(text)
if has_nil(target_pos) then
-- put wand back where it was.
-- In singleplayer/creative you can get an invalid position wand
inv:set_stack("main", i, stack)
else
-- don't know how you could get unsanitary coords in a wand,
-- let's just be safe
sanitize_and_set_coordinates(meta, target_pos)
-- put wand back to next free slot
inv:add_item("main", stack)
return
end
elseif "ccompass:" == stack_name:sub(1, 9)
or "compass:" == stack_name:sub(1, 8) then
-- remove item from inventory
inv:set_stack("main", i, ItemStack())
stack_meta = stack:get_meta()
text = stack_meta:get_string("target_pos")
target_pos = minetest.string_to_pos(text)
if has_nil(target_pos) then
-- put compass back, it is probably not calibrated
-- we put it at same position as we did not actually use it
inv:set_stack("main", i, stack)
else
sanitize_and_set_coordinates(meta, target_pos)
-- put compass back to next free slot
inv:add_item("main", stack)
return
end
end -- switch item type
end -- loop inventory
-- if we got here, there was nothing.
-- should we or should we not message user?
--[[
if nil ~= player_name then
minetest.chat_send_player(player_name, "No valid bookmark item found.")
end
--]]
end