Added Waypoints & Limits
Limits: Players can now be governed by how many total homes they can place Default values are: Basic = 2 Advanced = 4 Super = 8 Unlimited = inf Where Basic is default for singleplayer modes (ie given by default) Waypoints: Players can now choose what homes become visable via a waypoint. THIS FEATURE REQUIRES MINETEST VERSION 5.0 OR HIGHER Removing a home that has been "marked" as a waypoint also will remove the waypoint Setting a home to a new location will update the waypoint to the new location The api for waypoints has been reworked to support golang-like function responses (success, errmsg, value) Waypoints currently use (0, 200, 0) RGB values 0x0c800 in HEX This mod is ready to prepare for release onto contentdb. (v1.0)
This commit is contained in:
parent
aaf8a920ef
commit
5106eb4eb1
36
README.md
36
README.md
@ -1,16 +1,44 @@
|
||||
# home_point
|
||||
|
||||
A /sethome and /home mod for Minetest
|
||||
A multi homes teleport feature.
|
||||
|
||||
## CMDs
|
||||
## Commands
|
||||
|
||||
All commands require `home_point` priviledge
|
||||
All commands require `home_point` privilege (And `/sh` needs one of the further privileges, See Limiting homes section below)
|
||||
|
||||
* `/h (place_name)` Goes to a place called place_name unless not given then your player name is used.
|
||||
* `/sh (place_name)` Saves a place called place_name unless not given then your player name is used.
|
||||
* `/rh (place_name)` Removes a place called place_name unless not given then your player name is used.
|
||||
* `/lh` Lists all your homes, if you don't have any it will tell you how to make one.
|
||||
* `/wh (place_name)` Places a waypoint at the designated home till you log-out/quit, if place_name not given then your player name is used.
|
||||
|
||||
> `/wh` actually toggles a waypoint, and when `/sh` is used with the same home as a waypoint a new waypoint will be place at the new location. (Also when `/rh` is used on a home with a waypoint the waypoint will be removed)
|
||||
|
||||
## Notice
|
||||
|
||||
This mod uses mod storage... this means if the server crashes the mod will lose a few home points.
|
||||
This mod uses mod storage... this means if the server crashes the mod could lose a few home points.
|
||||
|
||||
## Limiting homes
|
||||
|
||||
There are 4 default privileges which are defined in settings.
|
||||
|
||||
All these do is limit the number of home_points players can set.
|
||||
|
||||
> (For servers) This means you need to add `home_point` and at least `home_point_basic` to your default_privs in minetest.conf,
|
||||
so new players can at least use home_point. (See [here](https://github.com/minetest/minetest/blob/master/builtin/settingtypes.txt#L1166) for info on default_privs in minetest.conf)
|
||||
|
||||
### home_point_basic
|
||||
|
||||
Defaults to max of 2 homes (Change with `home_point.home_point_basic` in settings)
|
||||
|
||||
### home_point_advanced
|
||||
|
||||
Defaults to max of 4 homes (Change with `home_point.home_point_advanced` in settings)
|
||||
|
||||
### home_point_super
|
||||
|
||||
Defaults to max of 8 homes (Change with `home_point.home_point_super` in settings)
|
||||
|
||||
### home_point_unlimited
|
||||
|
||||
Allows unlimited number of homes (Not defined in settings, as unlimited is assumed to be unlimited)
|
||||
|
172
init.lua
172
init.lua
@ -4,9 +4,10 @@ local modpath = minetest.get_modpath("home_point")
|
||||
home_point = {}
|
||||
|
||||
home_point.storage = minetest.get_mod_storage()
|
||||
home_point.temp = {} -- Used to track who has what waypoints set for what homes
|
||||
|
||||
-- Actually it's our api so if someone else wanted to monkey with points they can
|
||||
dofile(modpath.."/store_base.lua")
|
||||
dofile(modpath..DIR_DELIM.."store_base.lua")
|
||||
|
||||
-- Assistants
|
||||
function home_point.firstToUpper(str)
|
||||
@ -24,7 +25,29 @@ function home_point.split(inputstr, sep)
|
||||
return t
|
||||
end
|
||||
|
||||
minetest.register_privilege("home_point", "Gives access to home point")
|
||||
dofile(modpath..DIR_DELIM.."settings.lua")
|
||||
|
||||
minetest.register_privilege("home_point", {
|
||||
description = "Gives access to home point commands",
|
||||
give_to_singleplayer = true -- This should mean in singleplayer you start off with the defaults
|
||||
})
|
||||
|
||||
minetest.register_privilege("home_point_basic", {
|
||||
description = "Gives access upto "..tostring(home_point.home_point_basic).." homes",
|
||||
give_to_singleplayer = true -- This should mean in singleplayer you start off with the defaults
|
||||
})
|
||||
minetest.register_privilege("home_point_advanced", {
|
||||
description = "Gives access upto "..tostring(home_point.home_point_advanced).." homes",
|
||||
give_to_singleplayer = false
|
||||
})
|
||||
minetest.register_privilege("home_point_super", {
|
||||
description = "Gives access upto "..tostring(home_point.home_point_super).." homes",
|
||||
give_to_singleplayer = false
|
||||
})
|
||||
minetest.register_privilege("home_point_unlimited", {
|
||||
description= "Gives access to unlimited homes",
|
||||
give_to_singleplayer = false
|
||||
})
|
||||
|
||||
-- Set home
|
||||
minetest.register_chatcommand("sh", {
|
||||
@ -37,13 +60,63 @@ minetest.register_chatcommand("sh", {
|
||||
if name ~= "singleplayer" then
|
||||
if minetest.get_player_by_name(name) == nil then return false, "You must be online to use this command" end
|
||||
end
|
||||
-- Ensure we stop users from placing unlimited homes when they are not allowed to
|
||||
local homes = home_point.count(name)
|
||||
if not minetest.check_player_privs(name, {home_point_unlimited=true}) then
|
||||
if minetest.check_player_privs(name, {home_point_super=true}) then
|
||||
if homes+1 > home_point.home_point_super then
|
||||
return false, "You can only have "..tostring(home_point.home_point_super).." homes, currently you have "..tostring(homes).."."
|
||||
end
|
||||
elseif minetest.check_player_privs(name, {home_point_advanced=true}) then
|
||||
if homes+1 > home_point.home_point_basic then
|
||||
return false, "You can only have "..tostring(home_point.home_point_advanced).." homes, currently you have "..tostring(homes).."."
|
||||
end
|
||||
elseif minetest.check_player_privs(name, {home_point_basic=true}) then
|
||||
if homes+1 > home_point.home_point_basic then
|
||||
return false, "You can only have "..tostring(home_point.home_point_basic).." homes, currently you have "..tostring(homes).."."
|
||||
end
|
||||
else
|
||||
return false, "You appear to not have access to place any homes, You need home_point and one of these (home_point_basic, home_point_advanced, home_point_super, or home_point_unlimited)."
|
||||
end
|
||||
end
|
||||
-- Setup the place/home
|
||||
local place = string.match(param, "^([%a%d_-]+)") or ""
|
||||
if place ~= "" then
|
||||
minetest.log("action", "[home_point] "..name.." saves a point as '"..place.."'")
|
||||
return home_point.save(name, place), "Saved as "..place
|
||||
local rc = home_point.save(name, place)
|
||||
-- Update a waypoints position if we are showing that home
|
||||
local is_way = home_point.waypoint_is(name, place)
|
||||
if is_way.success == true and is_way.value ~= -1 then
|
||||
local pl = home_point.place_waypoint(name, place)
|
||||
if pl.success ~= true then
|
||||
minetest.log("action", "[home_point] Err="..pl.errmsg.." Val="..minetest.serialize(pl.value))
|
||||
end
|
||||
pl = home_point.place_waypoint(name, place)
|
||||
if pl.success ~= true then
|
||||
minetest.log("action", "[home_point] Err="..pl.errmsg.." Val="..minetest.serialize(pl.value))
|
||||
end
|
||||
else
|
||||
minetest.log("action", "[home_point] Err="..is_way.errmsg.." Val="..minetest.serialize(is_way.value))
|
||||
end
|
||||
return rc, "Saved as "..place
|
||||
else
|
||||
minetest.log("action", "[home_point] "..name.." saves a point as '"..name.."'")
|
||||
return home_point.save(name, name), "Saved as "..name
|
||||
local rc = home_point.save(name, name)
|
||||
-- Update a waypoints position if we are showing that home
|
||||
local is_way = home_point.waypoint_is(name, name)
|
||||
if is_way.success == true and is_way.value ~= -1 then
|
||||
local pl = home_point.place_waypoint(name, name)
|
||||
if pl.success ~= true then
|
||||
minetest.log("action", "[home_point] Err="..pl.errmsg.." Val="..minetest.serialize(pl.value))
|
||||
end
|
||||
pl = home_point.place_waypoint(name, name)
|
||||
if pl.success ~= true then
|
||||
minetest.log("action", "[home_point] Err="..pl.errmsg.." Val="..minetest.serialize(pl.value))
|
||||
end
|
||||
else
|
||||
minetest.log("action", "[home_point] Err="..is_way.errmsg.." Val="..minetest.serialize(is_way.value))
|
||||
end
|
||||
return rc, "Saved as "..name
|
||||
end
|
||||
return false, "Uable to determine place_name"
|
||||
end,
|
||||
@ -94,15 +167,41 @@ minetest.register_chatcommand("rh", {
|
||||
if minetest.get_player_by_name(name) == nil then return false, "You must be online to use this command" end
|
||||
end
|
||||
local place = string.match(param, "^([%a%d_-]+)") or ""
|
||||
local target = nil
|
||||
local resp = ""
|
||||
if place ~= "" then
|
||||
home_point.remove(name, place)
|
||||
minetest.log("action", "[home_point] "..name.." removes home of '"..place.."'")
|
||||
minetest.chat_send_player(name, ""..place.." removed")
|
||||
--minetest.chat_send_player(name, ""..place.." removed")
|
||||
resp = place.." removed"
|
||||
-- Remove waypoints from deleted homes
|
||||
local is_way = home_point.waypoint_is(name, place)
|
||||
if is_way.success and is_way.value ~= -1 then
|
||||
local place_way = home_point.place_waypoint(name, place)
|
||||
if place_way.success == true then
|
||||
minetest.log("action", "[home_point] "..name.." removed waypoint at '"..place.."'")
|
||||
else
|
||||
minetest.log("action", "[home_point] Err="..place_way.errmsg.." Val="..minetest.serialize(place_way.value))
|
||||
end
|
||||
end
|
||||
if home_point.remove(name, place) then
|
||||
minetest.chat_send_player(name, reps)
|
||||
end
|
||||
else
|
||||
home_point.remove(name, name)
|
||||
minetest.log("action", "[home_point] "..name.." removes home of '"..name.."'")
|
||||
minetest.chat_send_player(name, ""..name.." removed")
|
||||
--minetest.chat_send_player(name, ""..name.." removed")
|
||||
resp = name.." removed"
|
||||
-- Remove waypoints from deleted homes
|
||||
local is_way = home_point.waypoint_is(name, name)
|
||||
if is_way.success and is_way.value ~= -1 then
|
||||
local place_way = home_point.place_waypoint(name, name)
|
||||
if place_way.success == true then
|
||||
minetest.log("action", "[home_point] "..name.." removed waypoint at '"..name.."'")
|
||||
else
|
||||
minetest.log("action", "[home_point] Err="..place_way.errmsg.." Val="..minetest.serialize(place_way.value))
|
||||
end
|
||||
end
|
||||
if home_point.remove(name, name) then
|
||||
minetest.chat_send_player(name, reps)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
@ -119,12 +218,21 @@ minetest.register_chatcommand("lh", {
|
||||
if minetest.get_player_by_name(name) == nil then return false, "You must be online to use this command" end
|
||||
end
|
||||
local list = home_point.list(name)
|
||||
if list ~= nil then
|
||||
local r = "Homes: " .. tostring(#list+1) .. "\n"
|
||||
if list ~= nil and home_point.count(name) ~= 0 then
|
||||
--minetest.log("action", "[home_point] "..type(list).." "..minetest.serialize(list).." "..tostring(#list))
|
||||
local r = "Homes: " .. tostring(home_point.count(name)) .. "\n"
|
||||
for k in pairs(list) do
|
||||
local pos = list[k].split(list[k], " ")
|
||||
local is_way = home_point.waypoint_is(name, k)
|
||||
if is_way.success == false then
|
||||
minetest.log("action", "[home_point] Err="..is_way.errmsg.." Val="..minetest.serialize(is_way.value))
|
||||
end
|
||||
if is_way.success == true and is_way.value ~= -1 then
|
||||
r = r .. " " .. k .. " (" .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ") *\n"
|
||||
else
|
||||
r = r .. " " .. k .. " (" .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ")\n"
|
||||
end
|
||||
end
|
||||
return true, r
|
||||
else
|
||||
minetest.chat_send_player(name, "You don't have any homes yet, use /sh <home_name> to place a home.")
|
||||
@ -132,4 +240,46 @@ minetest.register_chatcommand("lh", {
|
||||
end,
|
||||
})
|
||||
|
||||
-- Toggle waypoint on home
|
||||
minetest.register_chatcommand("wh", {
|
||||
privs = {
|
||||
home_point = true
|
||||
},
|
||||
description = "Toggles a waypoint at a home point",
|
||||
func = function (name, param)
|
||||
-- Don't allow offline players
|
||||
if name ~= "singleplayer" then
|
||||
if minetest.get_player_by_name(name) == nil then return false, "You must be online to use this command" end
|
||||
end
|
||||
local place = string.match(param, "^([%a%d_-]+)") or ""
|
||||
if home_point.count(name) ~= 0 then
|
||||
if place ~= "" then
|
||||
if home_point.get(name, place) ~= "" then
|
||||
local rc = home_point.place_waypoint(name, place)
|
||||
if rc.success == true then
|
||||
minetest.log("action", "[home_point] "..name.." "..rc.errmsg.." at "..place.." '"..home_point.get(name, place).."'")
|
||||
minetest.chat_send_player(name, rc.errmsg.." at "..place)
|
||||
else
|
||||
minetest.log("action", "[home_point] Err="..rc.errmsg.." Val="..minetest.serialize(rc.value))
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(name, "No such home point "..place)
|
||||
end
|
||||
else
|
||||
if home_point.get(name, name) ~= "" then
|
||||
local rc = home_point.place_waypoint(name, name)
|
||||
if rc.success == true then
|
||||
minetest.log("action", "[home_point] "..name.." "..rc.errmsg.." at "..name.." '"..home_point.get(name, name).."'")
|
||||
minetest.chat_send_player(name, rc.errmsg.." at "..name)
|
||||
else
|
||||
minetest.log("action", "[home_point] Err="..rc.errmsg.." Val="..minetest.serialize(rc.value))
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(name, "You don't have any homes yet, use /sh <home_name> to place a home.")
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.log("action", "[home_point] Ready")
|
||||
|
25
settings.lua
Normal file
25
settings.lua
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
home_point.home_point_basic = minetest.settings:get("home_point.home_point_basic")
|
||||
if home_point.home_point_basic == nil then
|
||||
home_point.home_point_basic = 2
|
||||
minetest.settings:set("home_point.home_point_basic", 2)
|
||||
else
|
||||
home_point.home_point_basic = tonumber(home_point.home_point_basic)
|
||||
end
|
||||
|
||||
home_point.home_point_advanced = minetest.settings:get("home_point.home_point_advanced")
|
||||
if home_point.home_point_advanced == nil then
|
||||
home_point.home_point_advanced = 4
|
||||
minetest.settings:set("home_point.home_point_advanced", 4)
|
||||
else
|
||||
home_point.home_point_advanced = tonumber(home_point.home_point_advanced)
|
||||
end
|
||||
|
||||
home_point.home_point_super = minetest.settings:get("home_point.home_point_super")
|
||||
if home_point.home_point_super == nil then
|
||||
home_point.home_point_super = 8
|
||||
minetest.settings:set("home_point.home_point_super", 8)
|
||||
else
|
||||
home_point.home_point_super = tonumber(home_point.home_point_super)
|
||||
end
|
||||
|
9
settingtypes.txt
Normal file
9
settingtypes.txt
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
# Limits how many homes basic users can use
|
||||
home_point.home_point_basic (Home Point Basic) int 2
|
||||
|
||||
# Limits how many homes advanced users can use
|
||||
home_point.home_point_advanced (Home Point Advanced) int 4
|
||||
|
||||
# Limits how many homes super users can use
|
||||
home_point.home_point_super (Home Point Super) int 8
|
136
store_base.lua
136
store_base.lua
@ -6,8 +6,8 @@ function home_point.save(pname, place_name)
|
||||
-- If the player really is a player
|
||||
if p ~= nil then
|
||||
-- Get their position and convert it to string
|
||||
local pos = p:get_pos()
|
||||
pos = "".. math.floor(pos.x) .." ".. math.floor(pos.y+1) .." ".. math.floor(pos.z)
|
||||
local pos = vector.round(p:get_pos())
|
||||
pos = "".. pos.x .." ".. pos.y+1 .." ".. pos.z
|
||||
-- Obtain the player's homes update/insert then update the mods storage
|
||||
local tmp = minetest.deserialize(home_point.storage:get_string(pname)) or {}
|
||||
tmp[place_name] = pos
|
||||
@ -46,14 +46,19 @@ function home_point.remove(pname, place_name)
|
||||
if tmp ~= nil then
|
||||
-- Make a new table and add all except selected place
|
||||
local new = {}
|
||||
local found = false
|
||||
for k in pairs(tmp) do
|
||||
if k ~= place_name then
|
||||
new[k] = tmp[k]
|
||||
else
|
||||
found = true
|
||||
end
|
||||
end
|
||||
home_point.storage:set_string(pname, minetest.serialize(new))
|
||||
return found
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Returns list of home and position for a player
|
||||
@ -62,4 +67,131 @@ function home_point.list(pname)
|
||||
if p ~= nil then
|
||||
return minetest.deserialize(home_point.storage:get_string(pname))
|
||||
end
|
||||
return {}
|
||||
end
|
||||
|
||||
-- Returns the actual count/number of homes
|
||||
function home_point.count(pname)
|
||||
local home_count = 0
|
||||
local p = minetest.get_player_by_name(pname) or nil
|
||||
if p ~= nil then
|
||||
local list = home_point.list(pname)
|
||||
if list ~= nil then
|
||||
for k in pairs(list) do
|
||||
home_count = home_count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return home_count
|
||||
end
|
||||
|
||||
-- Waypoints are temporary, as in when the user quits/logs out I need to clear them from the temp list
|
||||
|
||||
-- Do we have a waypoint hud id for the given home point?
|
||||
function home_point.waypoint_is(pname, home)
|
||||
if home_point.get(pname, home) ~= "" then
|
||||
local waypoints = home_point.temp[pname] or {}
|
||||
--minetest.log("action", minetest.serialize(waypoints))
|
||||
for _, way in pairs(waypoints) do
|
||||
local way_name = way[1]
|
||||
local way_hid = way[2]
|
||||
--minetest.log("action", "[home_point.waypoint_is] way_name='"..way_name.."' way_hid="..tostring(way_hid))
|
||||
if way_name == home then
|
||||
return {success=true, errmsg="", value=way_hid}
|
||||
end
|
||||
end
|
||||
return {success=true, errmsg="Home point '"..home.."' doesn't have a waypoint set.", value=-1}
|
||||
else
|
||||
return {success=false, errmsg="No such home point '"..home.."'.", value=nil}
|
||||
end
|
||||
end
|
||||
|
||||
-- Adds the given hud id to the given home point
|
||||
function home_point.waypoint_add(pname, home, hud_id)
|
||||
if home_point.get(pname, home) ~= "" then
|
||||
local waypoints = home_point.temp[pname] or {}
|
||||
local tab = {}
|
||||
table.insert(tab, home)
|
||||
table.insert(tab, hud_id)
|
||||
table.insert(waypoints, tab)
|
||||
home_point.temp[pname] = waypoints
|
||||
return {success=true, errmsg="", value=tab}
|
||||
else
|
||||
return {success=false, errmsg="No such home point '"..home.."'", value=nil}
|
||||
end
|
||||
end
|
||||
|
||||
function home_point.waypoint_remove(pname, home)
|
||||
if home_point.get(pname, home) ~= "" then
|
||||
local waypoints = home_point.temp[pname] or {}
|
||||
local new_waypoints = {}
|
||||
for _, way in pairs(waypoints) do
|
||||
local way_name = way[1]
|
||||
local way_hid = way[2]
|
||||
--minetest.log("action", "[home_point.waypoint_remove] way_name='"..way_name.."' way_hid="..tostring(way_hid))
|
||||
if way_name ~= home then
|
||||
local tab = {}
|
||||
table.insert(tab, way_name)
|
||||
table.insert(tab, way_hid)
|
||||
table.insert(new_waypoints, tab)
|
||||
end
|
||||
end
|
||||
home_point.temp[pname] = new_waypoints
|
||||
return {success=true, errmsg="", value=nil}
|
||||
else
|
||||
return {success=false, errmsg="No such home point '"..home.."'", value=nil}
|
||||
end
|
||||
end
|
||||
|
||||
function home_point.place_waypoint(pname, home)
|
||||
if home_point.get(pname, home) ~= "" then
|
||||
-- Obtain the actual pos
|
||||
local raw_pos = home_point.split(home_point.get(pname, home), " ")
|
||||
local pos = {x=tonumber(raw_pos[1]), y=tonumber(raw_pos[2]), z=tonumber(raw_pos[3])}
|
||||
local player = minetest.get_player_by_name(pname)
|
||||
|
||||
local is_way = home_point.waypoint_is(pname, home)
|
||||
if is_way.success == true then
|
||||
if is_way.value ~= -1 then
|
||||
-- Remove
|
||||
local rm = home_point.waypoint_remove(pname, home)
|
||||
if rm.success ~= true then
|
||||
return {success=false, errmsg="home_point.waypoint_remove returned error", value=rm}
|
||||
else
|
||||
player:hud_remove(is_way.value)
|
||||
return {success=true, errmsg="Removed waypoint", value=nil}
|
||||
end
|
||||
else
|
||||
-- Add
|
||||
local add = home_point.waypoint_add(pname, home, player:hud_add({
|
||||
hud_elem_type = "waypoint",
|
||||
world_pos = vector.subtract(pos, {x=0, y=1, z=0}),
|
||||
name = home,
|
||||
number = 0x00c800
|
||||
}))
|
||||
if add.success ~= true then
|
||||
return {success=false, errmsg="home_point.waypoint_add returned error", value=add}
|
||||
else
|
||||
return {success=true, errmsg="Created waypoint", value=add.value}
|
||||
end
|
||||
end
|
||||
else
|
||||
return {success=false, errmsg="home_point.waypoint_is returned error", value=is_way}
|
||||
end
|
||||
else
|
||||
return {success=false, errmsg="No such home point '"..home.."'", value=nil}
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local pname = player:get_player_name()
|
||||
if home_point.temp[pname] ~= nil then
|
||||
local new = {}
|
||||
for name, tab in pairs(home_point.temp) do
|
||||
if name ~= pname then
|
||||
new[name] = tab
|
||||
end
|
||||
end
|
||||
home_point.temp = new
|
||||
end
|
||||
end)
|
||||
|
Loading…
x
Reference in New Issue
Block a user