initial commit, based on sethomes mod, 8033915df1
[minetest-xpmod:xp.git] / init.lua
1 -- Some variables you can change
2
3 -- How often (in seconds) homes file saves
4 local save_delta = 10
5 -- How often (in seconds) player can teleport
6 -- Set it to 0 to disable
7 local cooldown = 0
8 -- Max distance player can teleport, otherwise he will see error messsage
9 -- Set it to 0 to disable
10 local max_distance = 0
11 ----------------------------------
12
13 local homes_file = minetest.get_modpath('sethome')..'/homes'
14 --local homes_file = minetest.get_worldpath() .. "/homes"
15 local homepos = {}
16 local last_moved = {}
17
18 local function loadhomes()
19     local input = io.open(homes_file, "r")
20     if input then
21         while true do
22             local x = input:read("*n")
23             if x == nil then
24                 break
25             end
26             local y = input:read("*n")
27             local z = input:read("*n")
28             local name = input:read("*l")
29             homepos[name:sub(2)] = {x = x, y = y, z = z}
30         end
31         io.close(input)
32     else
33         homepos = {}
34     end
35 end
36
37 loadhomes()
38
39 local function get_time()
40     return os.time()
41 end
42
43 local function distance(a, b)
44     return math.sqrt(math.pow(a.x-b.x, 2) + math.pow(a.y-b.y, 2) + math.pow(a.z-b.z, 2))
45 end
46
47 local function round(num, idp)
48     local mult = 10^(idp or 0)
49     return math.floor(num * mult + 0.5) / mult
50 end
51
52 local changed = false
53
54 minetest.register_privilege("home", "Can use /home and /sethome commands")
55
56 minetest.register_chatcommand("home", {
57     privs = {home=true},
58     description = "Teleport you to your home point",
59     func = function(name, param)
60         local player = minetest.env:get_player_by_name(name)
61         if player == nil then
62             -- just a check to prevent server death
63             return false
64         end
65         if homepos[name] then
66             local time = get_time()
67             if cooldown ~= 0 and last_moved[name] ~= nil and time - last_moved[name] < cooldown then
68                 minetest.chat_send_player(name, "You can teleport only once in "..cooldown.." seconds. Wait another "..round(cooldown - (time - last_moved[name]), 3).." secs...")
69                 return true
70             end
71             local pos = player:getpos()
72             local dst = distance(pos, homepos[name])
73             if max_distance ~= 0 and distance(pos, homepos[name]) > max_distance then
74                 minetest.chat_send_player(name, "You are too far away from your home. You must be "..round(dst - max_distance, 3).." meters closer to teleport to your home.")
75                 return true
76             end
77             last_moved[name] = time
78             player:setpos(homepos[name])
79             minetest.chat_send_player(name, "Teleported to home!")
80         else
81             minetest.chat_send_player(name, "You don't have a home now! Set it using /sethome.")
82         end
83     end,
84 })
85
86 minetest.register_chatcommand("sethome", {
87     privs = {home=true},
88     description = "Set your home point",
89     func = function(name, param)
90         local player = minetest.env:get_player_by_name(name)
91         local pos = player:getpos()
92         homepos[name] = pos
93         minetest.chat_send_player(name, "Home set!")
94         changed = true
95     end,
96 })
97
98 local delta = 0
99 minetest.register_globalstep(function(dtime)
100     delta = delta + dtime
101     -- save it every <save_delta> seconds
102     if delta > save_delta then
103         delta = delta - save_delta
104         if changed then
105             local output = io.open(homes_file, "w")
106             for i, v in pairs(homepos) do
107                 output:write(v.x.." "..v.y.." "..v.z.." "..i.."\n")
108             end
109             io.close(output)
110             changed = false
111         end
112     end
113 end)