master
Beha 2017-01-01 22:42:25 -05:00
parent 8f43ea120e
commit fe0911639c
7 changed files with 182 additions and 12 deletions

View File

@ -6,7 +6,7 @@ function kingdoms.spm(s)
kingdoms.show_protection_messages = s
end
function kingdoms.is_protected(r, pos, name)
function kingdoms.can_dig(r, pos, name)
if not name or not pos then return false end
local kingdom = kingdoms.player.kingdom(name)
local positions = minetest.find_nodes_in_area(
@ -16,7 +16,7 @@ function kingdoms.is_protected(r, pos, name)
for _, pos in ipairs(positions) do
local meta = minetest.get_meta(pos)
local kid = meta:get_string("kingdom.id")
if not kingdom or kid ~= kingdom.id then
if (not kingdom or kid ~= kingdom.id) and kingdoms.db.kingdoms[kid] then
if kingdoms.show_protection_messages then
minetest.chat_send_player(name, ("This area is part of a kingdom ('%s') of which you are not a member."):format(kingdoms.db.kingdoms[kid].longname))
end
@ -26,9 +26,26 @@ function kingdoms.is_protected(r, pos, name)
return true
end
function kingdoms.bypos(pos)
local r = kingdoms.config.corestone_radius
local positions = minetest.find_nodes_in_area(
{x = pos.x - r, y = pos.y - r, z = pos.z - r},
{x = pos.x + r, y = pos.y + r, z = pos.z + r},
{"kingdoms:corestone"})
for _, pos in ipairs(positions) do
local meta = minetest.get_meta(pos)
return kingdoms.db.kingdoms[meta:get_string("kingdom.id")]
end
return nil
end
function kingdoms.is_protected(pos, digger)
return not kingdoms.can_dig(kingdoms.config.corestone_radius, pos, digger)
end
local old_is_protected = minetest.is_protected
function minetest.is_protected(pos, digger, digging)
if not kingdoms.is_protected(kingdoms.config.corestone_radius, pos, digger) then
if kingdoms.is_protected(pos, digger) then
if protection_lagporter and digging then
protection_lagporter.check(pos, digger)
end
@ -73,7 +90,7 @@ minetest.register_node("kingdoms:corestone", {
return itemstack
end
if pos.y < kingdoms.config.corestone_miny then
if pointed_thing.under.y < kingdoms.config.corestone_miny then
minetest.chat_send_player(placer:get_player_name(), ("You cannot place a corestone below %d."):format(kingdoms.config.corestone_miny))
return itemstack
end
@ -81,13 +98,15 @@ minetest.register_node("kingdoms:corestone", {
local radius = kingdoms.config.corestone_radius * 4
kingdoms.spm(false)
local canplace = not protector.is_protected(radius, pointed_thing.under, placer:get_player_name()) or not protector.is_protected(radius, pointed_thing.above, placer:get_player_name())
local canplace = not kingdoms.can_dig(radius, pointed_thing.under, placer:get_player_name()) or not kingdoms.can_dig(radius, pointed_thing.above, placer:get_player_name())
kingdoms.spm(true)
if canplace then
minetest.chat_send_player(placer:get_player_name(), "You cannot place a corestone this close to another.")
return itemstack
end
kingdoms.log("action", ("Corestone of '%s' placed at %s."):format(kingdom.longname, minetest.pos_to_string(pointed_thing.above)))
return minetest.item_place(itemstack, placer, pointed_thing)
end,

View File

@ -1,6 +1,10 @@
-- Save the database every <save_delay> seconds.
kingdoms.config.save_delay = 10
-- Minimum and maximum level (inclusive).
kingdoms.config.minlevel = 1
kingdoms.config.maxlevel = 100
-- A corestone extends in a radius of <corestone_radius>.
kingdoms.config.corestone_radius = 5
-- A corestone can be placed only above <corestone_miny>.

43
kingdoms/hud.lua Normal file
View File

@ -0,0 +1,43 @@
local huds = {}
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer < 0.1 then return end
timer = 0
for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name()
local pos = vector.round(player:getpos())
local pkingdom = kingdoms.player.kingdom(name)
local akingdom = kingdoms.bypos(pos)
kingdoms.spm(false)
local infostrings = {
akingdom and ("This area is owned by %s"):format(akingdom.longname) or "This area is neutral.",
pkingdom and ("You are a member of %s"):format(pkingdom.longname) or "You are neutral with "..kingdoms.utils.s("invite", #kingdoms.db.invites[name])..".",
kingdoms.is_protected(pos, name) and "You cannot dig here." or "You can dig here.",
}
kingdoms.spm(true)
local infostring = table.concat(infostrings, "\n")
local hud = huds[name]
if not hud then
hud = {}
huds[name] = hud
hud.id = player:hud_add({
hud_elem_type = "text",
name = "Kingdoms",
number = 0xFFFFFF,
position = {x=0, y=1},
offset = {x=8, y=-8},
text = infostring,
scale = {x=200, y=60},
alignment = {x=1, y=-1},
})
hud.oldinfo = infostring
return
elseif hud.oldinfo ~= infostring then
player:hud_change(hud.id, "text", infostring)
hud.oldinfo = infostring
end
end
end)

View File

@ -52,12 +52,12 @@ kingdoms.dbmeta.load()
minetest.after(kingdoms.config.save_delay, kingdoms.dbmeta.save_after)
minetest.register_on_shutdown(kingdoms.dbmeta.save)
-- Core mod files.
domodfile("utils.lua")
-- Mod interfaces.
domodfile("kingdom.lua")
domodfile("player.lua")
domodfile("hud.lua")
domodfile("corestone.lua")
-- All done!

View File

@ -1 +1,86 @@
kingdoms.db.kingdoms = {}
kingdoms.db.kingdoms = kingdoms.db.kingdoms or {}
local kcommand = {
params = "",
description = "Display the Kingdoms GUI.",
func = function(name)
local kingdom = kingdoms.player.kingdom(name)
if kingdom then
local membersstring = nil
for _,member in pairs(kingdom.members) do
membersstring = (membersstring and (membersstring .. ",") or "")
membersstring = membersstring .. minetest.formspec_escape(("%s - %d"):format(member.name, member.level))
end
membersstring = membersstring or ""
minetest.show_formspec(name, "kingdoms:joined",
"size[9,6]"
.."label[0,0;"..minetest.formspec_escape(("%s | You are level %d in this kingdom."):format(kingdom.longname, kingdom.members[name].level)).."]"
.."textlist[0,0.5;4,5;members;"..membersstring.."]"
)
else
local invitestring = nil
for _,invite in ipairs(kingdoms.db.invites[name]) do
invitestring = (invitestring and (invitestring .. ",") or "")
invitestring = invitestring .. minetest.formspec_escape(("%s from %s"):format(kingdoms.db.kingdoms[invite.kingdom].longname, invite.sender))
end
invitestring = invitestring or ""
minetest.show_formspec(name, "kingdoms:unjoined",
"size[9,6]"
.."textlist[0,0;4,5;invitations;"..invitestring.."]"
.."button[0,5;4,1;acceptinvite;Accept Invitation]"
.."field[4.75,0.5;4,0.5;name;Kingdom Name (will remove extra whitespace);]"
.."button[4.5,1;4,1;create;Create Kingdom]"
)
end
end
}
minetest.register_chatcommand("k", kcommand)
minetest.register_chatcommand("kingdoms", kcommand)
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "kingdoms:unjoined" then return false end
local name = player:get_player_name()
if fields.acceptinvite then
if not fields.invitations then
minetest.chat_send_player(name, "You must select an invitation.")
return true
end
local invite = kingdoms.db.invites[name][fields.invitations]
if not invite then
minetest.chat_send_player(name, "That invitation does not exist.")
return true
end
elseif fields.create then
local formattedname = fields.name:gsub("%s%s+", " "):gsub("^%s+", ""):gsub("%s+$", "")
if formattedname == "" then
minetest.chat_send_player(name, "You must name your kingdom something.")
return true
end
local kingdom = {
id = kingdoms.utils.uniqueid(),
longname = formattedname,
members = {},
}
for _,k in ipairs(kingdoms.db.kingdoms) do
if k.id == kingdom.id then
minetest.chat_send_player(name, "You have managed to collide with another kingdom's ID. Impressive. Try again for a new random ID.")
return true
end
if k.longname == kingdom.longname then
minetest.chat_send_player(name, "There is already a kingdom with that name.")
return true
end
end
kingdoms.db.players[name] = kingdom.id
kingdom.members[name] = {
name = name,
level = 100,
}
kingdoms.db.kingdoms[kingdom.id] = kingdom
kingdoms.log("action", ("Kingdom %s ('%s') was created by '%s'."):format(kingdom.id, kingdom.longname, name))
minetest.chat_send_player(name, "You are now the Monarch of "..kingdom.longname)
-- Switch to the other formspec.
kcommand.func(name)
return true
end
end)

View File

@ -1,6 +1,17 @@
kingdoms.player = {}
kingdoms.db.players = {}
kingdoms.db.players = kingdoms.db.players or {}
kingdoms.db.invites = kingdoms.db.invites or {}
minetest.register_on_joinplayer(function(player)
kingdoms.db.invites[player:get_player_name()] = kingdoms.db.invites[player:get_player_name()] or {}
end)
function kingdoms.player.kingdom(name)
return kingdoms.db.players[name]
return kingdoms.db.kingdoms[kingdoms.db.players[name]]
end
function kingdoms.player.kingdom_state(name)
local kingdom = kingdoms.player.kingdom(name)
if not kingdom then return nil end
return kingdom.members[name]
end

View File

@ -2,9 +2,17 @@ kingdoms.utils = {}
-- Return a UUID-like identifier.
function kingdoms.utils.uniqueid()
s = ("%x"):format(math.random(0, 0xFFFF))
for i=2,10 do
local s = ("%x"):format(math.random(0, 0xFFFF))
for i=2,4 do
s = s .. ("-%x"):format(math.random(0, 0xFFFF))
end
return s
end
function kingdoms.utils.s(label, number, s)
if number == 1 then
return ("%d %s"):format(number, label)
else
return ("%d %s%s"):format(number, label, s or "s")
end
end