]> git.lizzy.rs Git - dragonfireclient.git/blob - builtin/game/misc.lua
8d5c80216ce173975b6c87c525b515d4ee1abc14
[dragonfireclient.git] / builtin / game / misc.lua
1 -- Minetest: builtin/misc.lua
2
3 --
4 -- Misc. API functions
5 --
6
7 local jobs = {}
8 local time = 0.0
9 local last = core.get_us_time() / 1000000
10
11 core.register_globalstep(function(dtime)
12         local new = core.get_us_time() / 1000000
13         if new > last then
14                 time = time + (new - last)
15         else
16                 -- Overflow, we may lose a little bit of time here but
17                 -- only 1 tick max, potentially running timers slightly
18                 -- too early.
19                 time = time + new
20         end
21         last = new
22
23         if #jobs < 1 then
24                 return
25         end
26
27         -- Iterate backwards so that we miss any new timers added by
28         -- a timer callback, and so that we don't skip the next timer
29         -- in the list if we remove one.
30         for i = #jobs, 1, -1 do
31                 local job = jobs[i]
32                 if time >= job.expire then
33                         core.set_last_run_mod(job.mod_origin)
34                         job.func(unpack(job.arg))
35                         table.remove(jobs, i)
36                 end
37         end
38 end)
39
40 function core.after(after, func, ...)
41         assert(tonumber(time) and type(func) == "function",
42                         "Invalid core.after invocation")
43         jobs[#jobs + 1] = {
44                 func = func,
45                 expire = time + after,
46                 arg = {...},
47                 mod_origin = core.get_last_run_mod()
48         }
49 end
50
51 function core.check_player_privs(player_or_name, ...)
52         local name = player_or_name
53         -- Check if we have been provided with a Player object.
54         if type(name) ~= "string" then
55                 name = name:get_player_name()
56         end
57         
58         local requested_privs = {...}
59         local player_privs = core.get_player_privs(name)
60         local missing_privileges = {}
61         
62         if type(requested_privs[1]) == "table" then
63                 -- We were provided with a table like { privA = true, privB = true }.
64                 for priv, value in pairs(requested_privs[1]) do
65                         if value and not player_privs[priv] then
66                                 missing_privileges[#missing_privileges + 1] = priv
67                         end
68                 end
69         else
70                 -- Only a list, we can process it directly.
71                 for key, priv in pairs(requested_privs) do
72                         if not player_privs[priv] then
73                                 missing_privileges[#missing_privileges + 1] = priv
74                         end
75                 end
76         end
77         
78         if #missing_privileges > 0 then
79                 return false, missing_privileges
80         end
81         
82         return true, ""
83 end
84
85 local player_list = {}
86
87 core.register_on_joinplayer(function(player)
88         player_list[player:get_player_name()] = player
89 end)
90
91 core.register_on_leaveplayer(function(player)
92         player_list[player:get_player_name()] = nil
93 end)
94
95 function core.get_connected_players()
96         local temp_table = {}
97         for index, value in pairs(player_list) do
98                 if value:is_player_connected() then
99                         temp_table[#temp_table + 1] = value
100                 end
101         end
102         return temp_table
103 end
104
105 -- Returns two position vectors representing a box of `radius` in each
106 -- direction centered around the player corresponding to `player_name`
107 function core.get_player_radius_area(player_name, radius)
108         local player = core.get_player_by_name(player_name)
109         if player == nil then
110                 return nil
111         end
112
113         local p1 = player:getpos()
114         local p2 = p1
115
116         if radius then
117                 p1 = vector.subtract(p1, radius)
118                 p2 = vector.add(p2, radius)
119         end
120
121         return p1, p2
122 end
123
124 function core.hash_node_position(pos)
125         return (pos.z+32768)*65536*65536 + (pos.y+32768)*65536 + pos.x+32768
126 end
127
128 function core.get_position_from_hash(hash)
129         local pos = {}
130         pos.x = (hash%65536) - 32768
131         hash = math.floor(hash/65536)
132         pos.y = (hash%65536) - 32768
133         hash = math.floor(hash/65536)
134         pos.z = (hash%65536) - 32768
135         return pos
136 end
137
138 function core.get_item_group(name, group)
139         if not core.registered_items[name] or not
140                         core.registered_items[name].groups[group] then
141                 return 0
142         end
143         return core.registered_items[name].groups[group]
144 end
145
146 function core.get_node_group(name, group)
147         core.log("deprecated", "Deprecated usage of get_node_group, use get_item_group instead")
148         return core.get_item_group(name, group)
149 end
150
151 function core.setting_get_pos(name)
152         local value = core.setting_get(name)
153         if not value then
154                 return nil
155         end
156         return core.string_to_pos(value)
157 end
158
159 -- To be overriden by protection mods
160 function core.is_protected(pos, name)
161         return false
162 end
163
164 function core.record_protection_violation(pos, name)
165         for _, func in pairs(core.registered_on_protection_violation) do
166                 func(pos, name)
167         end
168 end
169
170 local raillike_ids = {}
171 local raillike_cur_id = 0
172 function core.raillike_group(name)
173         local id = raillike_ids[name]
174         if not id then
175                 raillike_cur_id = raillike_cur_id + 1
176                 raillike_ids[name] = raillike_cur_id
177                 id = raillike_cur_id
178         end
179         return id
180 end
181
182 -- HTTP callback interface
183 function core.http_add_fetch(httpenv)
184         httpenv.fetch = function(req, callback)
185                 local handle = httpenv.fetch_async(req)
186
187                 local function update_http_status()
188                         local res = httpenv.fetch_async_get(handle)
189                         if res.completed then
190                                 callback(res)
191                         else
192                                 core.after(0, update_http_status)
193                         end
194                 end
195                 core.after(0, update_http_status)
196         end
197
198         return httpenv
199 end
200
201 function core.get_color_escape_sequence(color)
202         --if string.len(color) == 3 then
203         --      local r = string.sub(color, 1, 1)
204         --      local g = string.sub(color, 2, 2)
205         --      local b = string.sub(color, 3, 3)
206         --      color = r ..  r .. g .. g .. b .. b
207         --end
208
209         --assert(#color == 6, "Color must be six characters in length.")
210         --return "\v" .. color
211         return "\v(color;" .. color .. ")"
212 end
213
214 function core.colorize(color, message)
215         return core.get_color_escape_sequence(color) .. message .. core.get_color_escape_sequence("ffffff")
216 end