commit 03e760c21f3e9928fb6e8f52b927d926b398ab70 Author: orwell96 Date: Sat May 28 23:12:48 2016 +0200 create git repository diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..5221a49 --- /dev/null +++ b/depends.txt @@ -0,0 +1,2 @@ +economy +tyrant \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..34ae5b9 --- /dev/null +++ b/init.lua @@ -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: +[edit] + + + +[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)=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, +}) diff --git a/locale/de.txt b/locale/de.txt new file mode 100644 index 0000000..4af6299 --- /dev/null +++ b/locale/de.txt @@ -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. diff --git a/locale/de.txt~ b/locale/de.txt~ new file mode 100644 index 0000000..f9d7964 --- /dev/null +++ b/locale/de.txt~ @@ -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 diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..5910d89 --- /dev/null +++ b/readme.txt @@ -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 + + 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. \ No newline at end of file diff --git a/readme.txt~ b/readme.txt~ new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/readme.txt~ @@ -0,0 +1 @@ + diff --git a/textures/tyrant_claim_markertool.png b/textures/tyrant_claim_markertool.png new file mode 100644 index 0000000..35cf95f Binary files /dev/null and b/textures/tyrant_claim_markertool.png differ