create git repository

master
orwell96 2016-05-28 23:12:48 +02:00
commit 03e760c21f
7 changed files with 425 additions and 0 deletions

2
depends.txt Normal file
View File

@ -0,0 +1,2 @@
economy
tyrant

348
init.lua Normal file
View File

@ -0,0 +1,348 @@
--tyrant_claim integration for tyrant
--adds "chunk"-based private area protection.
--[[for chunks to claim:
player uses protector tool
set first corner chunk
player uses protector tool a second time
set second corner chunk
calculate "cost" for all claimed chunks
show confirmation "claim n chunks?will cost ..., will span from y=pos+50 to y=pos-50,yes, no"
then: all chunks claimed added to a list
if player has no area yet:
>show setup display name
tyrant_claim.areas={
[player_name]={
name="display name of area",
allow_activate="list_of_pnames_separated_with_spaces",
allow_inventories="list_of_pnames_separated_with_spaces",
allow_all="list_of_pnames_separated_with_spaces",
claim={
[chunkxpos]={
[chunkzpos]={
ymin=int,
ymax=int
}
}
}
}
}
formspec:
<name_of_area>[edit]
<field allow_activate>
<field allow_inventories>
<field allow_all>
[save]
]]
-- Boilerplate to support localized strings if intllib mod is installed.
local S
if minetest.get_modpath("intllib") then
S = intllib.Getter()
else
-- If you use insertions, but not insertion escapes this will work:
S = function(s,a,...)a={a,...}return s:gsub("@(%d+)",function(n)return a[tonumber(n)]end)end
end
tyrant_claim={}
tyrant_claim.settings={
--TestDollar taken for a chunk
cost_per_chunk=100,
--settings for height of claimed chunk. the default setting makes the whole world column be owned by the player.
use_absolute_y=true,
--true:use abs_ymax and abs_ymin as absolute height values
--false:take current player y and range range_up/range_down nodes up and down.
abs_ymax=31000,
abs_ymin=-31000,
range_down=50,
range_up=50,
}
minetest.register_privilege("claim", {
description = "Can claim chunks.",
})
tyrant_claim.fpath=minetest.get_worldpath().."/tyrant_claim"
local file, err = io.open(tyrant_claim.fpath, "r")
if not file then
tyrant_claim.areas = {}
local er=err or "Unknown Error"
print("[tyrant_claim]Failed loading areas file "..er)
else
tyrant_claim.areas = minetest.deserialize(file:read("*a"))
if type(tyrant_claim.areas) ~= "table" then
tyrant_claim.areas={}
end
file:close()
end
tyrant_claim.save = function()
local datastr = minetest.serialize(tyrant_claim.areas)
if not datastr then
minetest.log("error", "[tyrant_claim] Failed to serialize area data!")
return
end
local file, err = io.open(tyrant_claim.fpath, "w")
if err then
return err
end
file:write(datastr)
file:close()
end
tyrant_claim.save_cntdn=10
minetest.register_globalstep(function(dtime)
--and it will save everything
if tyrant_claim.save_cntdn<=0 then
tyrant_claim.save()
tyrant_claim.save_cntdn=10 --10 seconds interval!
end
tyrant_claim.save_cntdn=tyrant_claim.save_cntdn-dtime
end)
tyrant_claim.tochunkpos=function(pos)
local rpos=vector.round(pos)
return {x=math.floor(rpos.x/16), z=math.floor(rpos.z/16)}
end
tyrant_claim.tonodepos_min=function(cpos, y)
return {x=cpos.x*16, y=y, z=cpos.z*16}
end
tyrant_claim.tonodepos_max=function(cpos, y)
return {x=cpos.x*16, y=y, z=cpos.z*16}
end
tyrant_claim.sort_coords=function(c1, c2)
return
{x=math.min(c1.x, c2.x), y=math.min(c1.y or 0, c2.y or 0), z=math.min(c1.z, c2.z)},
{x=math.max(c1.x, c2.x), y=math.max(c1.y or 0, c2.y or 0), z=math.max(c1.z, c2.z)}
end
tyrant_claim.firstmarker_chunk={}
tyrant_claim.placemarker=function(pos, player)
local pname=player:get_player_name()
if not tyrant_claim.firstmarker_chunk[pname] then
tyrant_claim.firstmarker_chunk[pname]=tyrant_claim.tochunkpos(pos)
minetest.chat_send_player(pname, S("Placed first corner of area at @1, set the second oopposite corner or click again to claim this chunk only.", minetest.pos_to_string(pos)))
return false
else
tyrant_claim.claim_chunks_within(player:get_player_name(), tyrant_claim.firstmarker_chunk[pname], tyrant_claim.tochunkpos(pos), math.floor(pos.y))
end
end
tyrant_claim.claim_chunks_within=function(pname, chunkpos1, chunkpos2, ypos)
local cpos1, cpos2=tyrant_claim.sort_coords(chunkpos1, chunkpos2)
local rpp1=tyrant_claim.tonodepos_min(cpos1, ypos-50)
local rpp2=tyrant_claim.tonodepos_max(cpos2, ypos+50)
local hpr=tyrant.get_area_priority_inside(rpp1, rpp2)
local area=math.abs(cpos2.x-cpos1.x+1)*math.abs(cpos2.z-cpos1.z+1)
local cost=tyrant_claim.settings.cost_per_chunk*area
local ymin=tyrant_claim.settings.use_absolute_y and tyrant_claim.settings.abs_ymin or ypos-tyrant_claim.settings.range_down
local ymax=tyrant_claim.settings.use_absolute_y and tyrant_claim.settings.abs_ymax or ypos+tyrant_claim.settings.range_up
if hpr>=2 then
tyrant.fs_message(pname, S("The area you've chosen intersects with one or more existing areas!"))
tyrant_claim.firstmarker_chunk[pname]=nil
return
elseif economy.moneyof(pname)<cost then
tyrant.fs_message(pname, "Insufficient funds: @1 chunks cost @2ŧ, you only have @3ŧ.", area, cost, economy.moneyof(pname))
tyrant_claim.firstmarker_chunk[pname]=nil
return
else
minetest.show_formspec(pname, "tyrant_claim_confirm_"..cpos1.x.."_"..cpos1.z.."_"..cpos2.x.."_"..cpos2.z.."_"..ypos,
"size[6,5]"..
"label[0.5,0.5;"..S("You are buying @1 Chunks (16x16 nodes) from y=@2 to @3.", area, ymin, ymax).."]"..
"label[0.5,1;"..S("They range from @1 to @2", minetest.pos_to_string(rpp1), minetest.pos_to_string(rpp2)).."]"..
"label[0.5,1.5;"..S("This costs @1ŧ", cost).."]"..
"button_exit[0.5,2;3,1;buy;"..S("Buy!").."]"..
"button_exit[0.5,3;3,1;cancel;"..S("Cancel").."]")
end
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
local x1, z1, x2, z2, ypos=string.match(formname, "tyrant_claim_confirm_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)")
if x1 and z1 and x2 and z2 and fields.buy then
local pname=player:get_player_name()
local cpos1, cpos2=tyrant_claim.sort_coords({x=x1, z=z1}, {x=x2, z=z2})
local rpp1=tyrant_claim.tonodepos_min(cpos1, ypos-50)
local rpp2=tyrant_claim.tonodepos_max(cpos2, ypos+50)
local hpr=tyrant.get_area_priority_inside(rpp1, rpp2)
local area=(cpos2.x-cpos1.x)*(cpos2.z-cpos1.z)
local cost=tyrant_claim.settings.cost_per_chunk*area
local ymin=tyrant_claim.settings.use_absolute_y and tyrant_claim.settings.abs_ymin or ypos-tyrant_claim.settings.range_down
local ymax=tyrant_claim.settings.use_absolute_y and tyrant_claim.settings.abs_ymax or ypos+tyrant_claim.settings.range_up
if hpr>=2 then
tyrant.fs_message(pname, S("The area you've chosen intersects with one or more existing areas!"))
tyrant_claim.firstmarker_chunk[pname]=nil
return
elseif not economy.canpay(pname, cost) then
tyrant.fs_message(pname, "Insufficient funds: @1 chunks cost @2ŧ, you only have @3ŧ.", area, cost, economy.moneyof(pname))
tyrant_claim.firstmarker_chunk[pname]=nil
return
else
for cntx=cpos1.x, cpos2.x do
for cntz=cpos1.z, cpos2.z do
if not tyrant_claim.areas[pname] then
tyrant_claim.areas[pname]={
name=S("Area of @1",pname),
allow_activate="",
allow_inventories="",
allow_all="",
claim={},
}
tyrant_claim.show_edit_area_name(pname)
end
if not tyrant_claim.areas[pname].claim[cntx] then tyrant_claim.areas[pname].claim[cntx]={} end
tyrant_claim.areas[pname].claim[cntx][cntz]={ymin=ymin, ymax=ymin}
end
end
economy.withdraw(pname, cost, S("Bought some private area"))
end
elseif formname=="tyrant_claim_manager" then
local pname=player:get_player_name()
if fields.save then
tyrant_claim.areas[pname].allow_activate=fields.activate
tyrant_claim.areas[pname].allow_inventories=fields.inventory
tyrant_claim.areas[pname].allow_all=fields.all
elseif fields.chname then
tyrant_claim.show_edit_area_name(pname);
end
elseif formname=="tyrant_claim_editname" then
local pname=player:get_player_name()
tyrant_claim.areas[pname].name=fields.newname or (tyrant_claim.areas[pname] and tyrant_claim.areas[pname].name or "")
end
end)
tyrant_claim.give_self_protection_stuff=function(pname)
tyrant_claim.firstmarker_chunk[pname]=nil
local inv=minetest.get_player_by_name(pname):get_inventory()
if not inv:contains_item("main", "tyrant_claim:selfprotector") then
inv:add_item("main", "tyrant_claim:selfprotector 1");
end
return true, S("Given marker tool and reset corners!")
end
minetest.register_craftitem("tyrant_claim:selfprotector",{
description = S(""),
inventory_image = "tyrant_claim_markertool.png",
stack_max = 1,
on_use = function(itemstack, user, pointed_thing)
if not pointed_thing or not pointed_thing.type=="node" then return end
local pos=pointed_thing.under
if not pos then return end
if tyrant_claim.placemarker(pos, user) then
itemstack:take_item()
end
return itemstack
end,
}
)
--register tyrant integration!
tyrant.register_integration("claim", {
get_all_area_ids=function()
return false, tyrant_claim.areas
end,
get_is_area_at=function(areaid, pos)
local cpos=tyrant_claim.tochunkpos(pos)
--areaid equals player name
return tyrant_claim.areas[areaid] and tyrant_claim.areas[areaid].claim and tyrant_claim.areas[areaid].claim[cpos.x] and tyrant_claim.areas[areaid].claim[cpos.x][cpos.z]
and tyrant_claim.areas[areaid].claim[cpos.x][cpos.z].ymax>=pos.y and tyrant_claim.areas[areaid].claim[cpos.x][cpos.z].ymin<=pos.y
end,
get_area_priority=function(areaid)
return 2
end,
check_permission=function(areaid, name, action)
if not name or name=="" or not tyrant_claim.areas[areaid] then
return true
end
if name==areaid then
return true
end
if action=="activate" then
local area=tyrant_claim.areas[areaid]
return string.match(" "..area.allow_activate.." ", " "..name.." ", 1, true) or string.match(" "..area.allow_all.." ", " "..name.." ", 1, true)
elseif action=="inv" then
local area=tyrant_claim.areas[areaid]
return string.match(" "..area.allow_inventories.." ", " "..name.." ", 1, true) or string.match(" "..area.allow_all.." ", " "..name.." ", 1, true)
elseif action=="build" then
local area=tyrant_claim.areas[areaid]
return string.match(" "..area.allow_all.." ", " "..name.." ", 1, true)
elseif action=="pvp" then
return name==areaid--when owner, then allow, else deny.
--this elseif is not neccessary, but for overlook reasons kept.
end
return true--on action=="punch" or "enter"
end,
get_area_intersects_with=function(areaid, p1, p2)
if not tyrant_claim.areas[areaid] or not tyrant_claim.areas[areaid].claim then return false end
local claim=tyrant_claim.areas[areaid].claim
for cposx, claimz in pairs(claim) do
for cposz, chunk in pairs(claimz) do
local pos1=tyrant_claim.tonodepos_min({x=cposx, z=cposz}, chunk.ymin)
local pos2=tyrant_claim.tonodepos_max({x=cposx, z=cposz}, chunk.ymax)
if (p1.x <= pos2.x and p2.x >= pos1.x) and
(p1.y <= pos2.y and p2.y >= pos1.y) and
(p1.z <= pos2.z and p2.z >= pos1.z) then
return true
end
end
end
return false
end,
is_hostile_mob_spawning_allowed=function(areaid)
return false
end,
on_area_info_requested=function(areaid, player_name)
if areaid==player_name then
tyrant_claim.show_area_manager(player_name)
end
end,
get_display_name=function(areaid)
return tyrant_claim.areas[areaid].name
end
})
tyrant_claim.show_area_manager=function(pname)
local area=tyrant_claim.areas[pname]
if not area then
minetest.chat_send_player(pname, "You don't have an area yet. Use the /protect command to create one or to extend it.")
return
end
minetest.show_formspec(pname, "tyrant_claim_manager", "size[8,8]label[0,0;"..S("Settings for @1's area",pname).."]label[0,5;"..S("Separate player names with spaces or write '@1a' to allow all", "@").."]"
.."field[0,2;8,1;activate;"..S("Players that may right-click nodes:")..";"..(area.allow_activate or "").."]"
.."field[0,3;8,1;inventory;"..S("Players that may right-click nodes and change inventories:")..";"..(area.allow_inventories or "").."]"
.."field[0,4;8,1;all;"..S("Players that may do everything they want:")..";"..(area.allow_all or "").."]"
.."button_exit[0,6;5,1;save;"..S("Save!").."]"
.."button[0,7.5;5,1;chname;"..S("Change area name").."]")
end
tyrant_claim.show_edit_area_name=function(pname)
local area= tyrant_claim.areas[pname]
minetest.show_formspec(pname, "tyrant_claim_editname", "field[newname;"..S("Type new name:")..";"..(area.name or "").."]")
end
core.register_chatcommand("protect", {
params = "",
description = S("Get area protection tool"),
privs = {claim=true},
func = function(name, param)
return tyrant_claim.give_self_protection_stuff(name)
end,
})
core.register_chatcommand("unclaim", {
params = "",
description = S("Sell the chunk in which you are standing."),
privs = {claim=true},
func = function(name, param)
local p= minetest.get_player_by_name(name)
if not p then return end
local c=tyrant_claim.tochunkpos(vector.round(p:getpos()))
if not tyrant_claim.areas[name] or not tyrant_claim.areas[name].claim or not
tyrant_claim.areas[name].claim[c.x][c.z] then
return false, S("This one does not belong to you.")
end
tyrant_claim.areas[name].claim[c.x][c.z]=nil
economy.deposit(name, tyrant_claim.settings.cost_per_chunk, S("Sold some private area"))
return true, S("Sold sucessfully.")
end,
})

30
locale/de.txt Normal file
View File

@ -0,0 +1,30 @@
Placed first corner of area at @1, set the second oopposite corner or click again to claim this chunk only.=Erste Ecke des Bereichs bei @1 gesetzt, zweite auf der gegenüberliegenden Ecke setzen! Oder klicke nochmal, um nur diesen Chunk zu kaufen.
The area you've chosen intersects with one or more existing areas!=Gewählter Bereich überschneidet sich mit einem oder mehreren bestehenden Gebieten!
Insufficient funds: @1 chunks cost @2ŧ, you only have @3ŧ.=Ungenügend Geld: @1 Chunks kosten @2ŧ, du hast aber nur @3ŧ.
You are buying @1 Chunks (16x16 nodes) from y=@2 to @3.=Du kaufst @1 Chunks (16x16 Blöcke) von y=@2 bis @3.
They range from @1 to @2=Diese reichen von @1 bis @2
This costs @1ŧ=Das kostet dich @1ŧ
Buy!=Kaufen!
Cancel=Abbrechen
Area of @1=Gebiet von @1
Bought some private area=Kauf von Gebiet
Sold some private area=Verkauf von Gebiet
Given marker tool and reset corners!=Markierungswerkzeug gegeben und beide Ecken zurückgesetzt!!!
Private area marker. Punch 2 corners that span a rectangle in X/Z direction.=Privatgebietsmarkierer. Klicke links auf 2 Blöcke, die in X/Z-Richtung ein Rechteck bilden. Y ist egal.
#nur für den fall, dass jemand die absicht hat, das hier zusammen mit mg_villages und meiner integration dafür betrieben wird.
#Du hast noch kein Gebiet. Nutze /protect, um den Gebietsmarkierer zu erhalten. Gebäude in Dörfern sind hiervon unabhängig.
You don't have an area yet. Use the /protect command to create one or to extend it.=Du hast noch kein Gebiet. Nutze /protect, um den Gebietsmarkierer zu erhalten.
Settings for @1's area=Einstellungen für das Gebiet von @1:
#@1 will be replaced by the @ character in every case, this is to escape it. (fallback uses the simple gsub command)
Separate player names with spaces or write '@1a' to allow all=Spielernamen mit Leerzeichen trennen, '@1a' erlaubt allen.
Players that may right-click nodes:=Folgende Spieler dürfen Blöcke aktivieren:
Players that may right-click nodes and change inventories:=Folgende Spieler dürfen Blöcke aktivieren und Inventare verändern:
Players that may do everything they want:=Folgende Spieler dürfen tun, was sie wollen:
Save!=Speichern!
Change area name=Namen des Gebiets ändern
Type new name:=Neuen Namen eingeben:
Get area protection tool=Erhalte den Gebietsmarkierer.
Sell the chunk in which you are standing.=Den Chunk, in dem du gerade stehst, wieder verkaufen.
This one does not belong to you.=Der gehört dir nicht.
Sold successfully.=Erfolgreich verkauft.

24
locale/de.txt~ Normal file
View File

@ -0,0 +1,24 @@
Placed first corner of area at @1, set the second oopposite corner or click again to claim this chunk only.=Erste Ecke des Bereichs bei @1 gesetzt, zweite auf der gegenüberliegenden Ecke setzen! Oder klicke nochmal, um nur diesen Chunk zu kaufen.
The area you've chosen intersects with one or more existing areas!=Gewählter Bereich überschneidet sich mit einem oder mehreren bestehenden Gebieten!
Insufficient funds: @1 chunks cost @2ŧ, you only have @3ŧ.=Ungenügend Geld: @1 Chunks kosten @2ŧ, du hast aber nur @3ŧ.
You are buying @1 Chunks (16x16 nodes) from y=@2 to @3.=Du kaufst @1 Chunks (16x16 Blöcke) von y=@2 bis @3.
They range from @1 to @2=Diese reichen von @1 bis @2
This costs @1ŧ=Das kostet dich @1ŧ
Buy!=Kaufen!
Cancel=Abbrechen
Area of @1=Gebiet von @1
Bought some private area=Kauf von Gebiet
Given marker tool and reset corners!=Markierungswerkzeug gegeben und beide Ecken zurückgesetzt!!!
Private area marker. Punch 2 corners that span a rectangle in X/Z direction.=Privatgebietsmarkierer. Klicke links auf 2 Blöcke, die in X/Z-Richtung ein Rechteck bilden. Y ist egal.
#nur für den fall, dass jemand die absicht hat, das hier zusammen mit mg_villages und meiner integration dafür betrieben wird.
#Du hast noch kein Gebiet. Nutze /protect, um den Gebietsmarkierer zu erhalten. Gebäude in Dörfern sind hiervon unabhängig.
You don't have an area yet. Use the /protect command to create one or to extend it.=Du hast noch kein Gebiet. Nutze /protect, um den Gebietsmarkierer zu erhalten.
Settings for @1's area=Einstellungen für das Gebiet von @1:
#@1 will be replaced by the @ character in every case, this is to escape it. (fallback uses the simple gsub command)
Separate player names with spaces or write '@1a' to allow all=Spielernamen mit Leerzeichen trennen, '@1a' erlaubt allen.
Players that may right-click nodes:=Folgende Spieler dürfen Blöcke aktivieren:
Players that may right-click nodes and change inventories:=Folgende Spieler dürfen Blöcke aktivieren und Inventare verändern:
Players that may do everything they want:=Folgende Spieler dürfen tun, was sie wollen:
Save!=Speichern!
Change area name=Namen des Gebiets ändern

20
readme.txt Normal file
View File

@ -0,0 +1,20 @@
tyrant_claim - Chunk-based self-protection based on tyrant and economy.
This mod allows players to protect areas based on chunks of 16x16 nodes for TestDollar
Inside init.lua there are some configuration options.
License
-------
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

1
readme.txt~ Normal file
View File

@ -0,0 +1 @@

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B