From 885ac993dacaf143bc7e80954eaa0bd5c60946bc Mon Sep 17 00:00:00 2001 From: BrunoMine Date: Fri, 3 Apr 2020 22:20:54 -0300 Subject: [PATCH] Update code --- city.lua | 29 ++++++++++++- data_base.lua | 8 ++-- depends.txt | 1 + init.lua | 15 ++++++- node_fix.lua | 29 +++++++++++++ property.lua | 17 ++++++-- property_stone.lua | 35 +++++++++++++++- protected_area.lua | 2 +- seller_node.lua | 1 + sfinv_menu.lua | 95 ++++++++++++++++++++++++++++++++++++++++++ teleporter.lua | 21 ++++------ time_count.lua | 35 ++++++++++++++++ voxelmanip.lua | 100 +++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 364 insertions(+), 24 deletions(-) create mode 100644 node_fix.lua create mode 100644 sfinv_menu.lua create mode 100644 time_count.lua create mode 100644 voxelmanip.lua diff --git a/city.lua b/city.lua index 0c30ff2..976c1e4 100644 --- a/city.lua +++ b/city.lua @@ -38,6 +38,12 @@ cidades.remove_active_city = function(city_id, def) cidades.db.ms:set_string("active_cities", minetest.serialize(cidades.active_cities)) end +-- On create city callback +cidades.registered_on_create_city = {} +cidades.register_on_create_city = function(func) + table.insert(cidades.registered_on_create_city, func) +end + -- Create city cidades.create_city = function(city_id, pos) @@ -58,8 +64,21 @@ cidades.create_city = function(city_id, pos) -- Place schem minetest.place_schematic(minp, city.schem_path) + local epa = city.extra_protected_area or {} + -- Protect area - local area_id = cidades.protect_area("Server city", city.name, minp, maxp) + local area_id = cidades.protect_area("Server city", city.name, + { + x = minp.x - (epa.xn or epa.x or cidades.extra_protect_side_area), + y = minp.y - (epa.yn or epa.y or cidades.extra_protect_bottom_area), + z = minp.z - (epa.zn or epa.z or cidades.extra_protect_side_area) + }, + { + x = maxp.x + (epa.xp or epa.x or cidades.extra_protect_side_area), + y = maxp.y + (epa.yp or epa.y or cidades.extra_protect_top_area), + z = maxp.z + (epa.zp or epa.z or cidades.extra_protect_side_area) + } + ) -- Insert active city cidades.insert_active_city(city_id, { @@ -70,6 +89,11 @@ cidades.create_city = function(city_id, pos) area_id = area_id, }) + -- Run on create city callback + for _,f in ipairs(cidades.registered_on_create_city) do + f(city_id) + end + end minetest.register_chatcommand("create_city", { @@ -81,7 +105,8 @@ minetest.register_chatcommand("create_city", { return end - cidades.create_city(param, minetest.get_player_by_name(name):get_pos()) + cidades.create_city(param, vector.round(minetest.get_player_by_name(name):get_pos())) minetest.chat_send_player(name, cidades.registered_cities[param].name.." created.") + end, }) diff --git a/data_base.lua b/data_base.lua index 91e3609..85ee53b 100644 --- a/data_base.lua +++ b/data_base.lua @@ -13,13 +13,13 @@ cidades.db = {} cidades.db.ms = minetest.get_mod_storage() -- Set City def -cidades.db.set_city = function(city_name, data) - cidades.db.ms:set_string("city_"..city_name, minetest.serialize(data)) +cidades.db.set_city = function(city_id, data) + cidades.db.ms:set_string("city_"..city_id, minetest.serialize(data)) end -- Get City def -cidades.db.get_city = function(city_name) - return minetest.deserialize(cidades.db.ms:get_string("city_"..city_name)) +cidades.db.get_city = function(city_id) + return minetest.deserialize(cidades.db.ms:get_string("city_"..city_id)) end diff --git a/depends.txt b/depends.txt index 7e289ad..bd6ebaa 100644 --- a/depends.txt +++ b/depends.txt @@ -1,2 +1,3 @@ default areas +sfinv_menu diff --git a/init.lua b/init.lua index ada51e4..14ee90f 100644 --- a/init.lua +++ b/init.lua @@ -11,17 +11,26 @@ cidades = {} cidades.money_item = (minetest.settings:get("cidades_money_item") or "default:apple") +cidades.extra_protect_side_area = tonumber(minetest.settings:get("cidades_extra_protect_side_area") or 200) +cidades.extra_protect_top_area = tonumber(minetest.settings:get("cidades_extra_protect_top_area") or 5000) +cidades.extra_protect_bottom_area = tonumber(minetest.settings:get("cidades_extra_protect_bottom_area") or 50) + +cidades.max_days_inactive_owner = tonumber(minetest.settings:get("cidades_max_days_inactive_owner") or 60) + local modpath = minetest.get_modpath("cidades") dofile(modpath.."/data_base.lua") +dofile(modpath.."/time_count.lua") dofile(modpath.."/protected_area.lua") dofile(modpath.."/number_nodes.lua") +dofile(modpath.."/voxelmanip.lua") dofile(modpath.."/land.lua") dofile(modpath.."/city.lua") dofile(modpath.."/city_builder.lua") ---dofile(modpath.."/city_stone.lua") + +dofile(modpath.."/node_fix.lua") dofile(modpath.."/property.lua") dofile(modpath.."/property_builder.lua") @@ -31,3 +40,7 @@ dofile(modpath.."/teleporter.lua") dofile(modpath.."/seller_node.lua") +dofile(modpath.."/sfinv_menu.lua") + + + diff --git a/node_fix.lua b/node_fix.lua new file mode 100644 index 0000000..1075d3a --- /dev/null +++ b/node_fix.lua @@ -0,0 +1,29 @@ +--[[ + Mod Cidades for Minetest + Copyright (C) 2020 BrunoMine (https://github.com/BrunoMine) + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Node fix + ]] + +-- Register node fix +local node_list = {} +cidades.registered_node_fix = {} +cidades.register_node_fix = function(nodename, func) + node_list[nodename] = true + cidades.registered_node_fix[nodename] = func +end + +cidades.register_on_create_city(function(city_id) + local city_data = cidades.active_cities[city_id] + + local nodes = cidades.vm.get(city_data.minp, city_data.maxp, minetest.deserialize(minetest.serialize(node_list))) + + for nn,ptb in pairs(nodes) do + for _,pos in ipairs(ptb) do + cidades.registered_node_fix[nn](pos, city_id) + end + end +end) diff --git a/property.lua b/property.lua index 0d6966c..4d68720 100644 --- a/property.lua +++ b/property.lua @@ -128,6 +128,8 @@ end -- Set owner cidades.set_owner = function(player, pos, data) + local city_id = minetest.get_meta(pos):get_string("city_id") + -- Update property stone minetest.set_node(pos, {name="cidades:property_stone_purchased"}) @@ -148,12 +150,14 @@ cidades.set_owner = function(player, pos, data) -- Update metadata data.pos = pos + data.city_id = city_id data.width = (data.radius * 2) + 1 data.minp = minp data.maxp = maxp data.soil_node = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name data.owner = player:get_player_name() data.area_id = area_id + data.last_login = cidades.get_date_hash() -- Update data base cidades.db.set_property(data.owner, data) @@ -165,9 +169,6 @@ end -- Reset owner cidades.reset_property = function(pos, data) - -- Update property stone - minetest.set_node({x=pos.x, y=pos.y-3, z=pos.z}, {name="cidades:property_stone_for_sale"}) - -- Update data base cidades.db.reset_property(data.owner) @@ -183,6 +184,12 @@ cidades.reset_property = function(pos, data) -- Place seller minetest.set_node({x=pos.x, y=pos.y+3, z=pos.z}, {name="cidades:seller"}) + -- Update property stone + minetest.set_node(pos, {name="cidades:property_stone_for_sale"}) + + -- Save city_id + minetest.get_meta(pos):set_string("city_id", data.city_id) + -- Update metadata data.owner = nil end @@ -200,3 +207,7 @@ minetest.register_chatcommand("reset_property", { cidades.db.reset_property(name) end, }) + + + + diff --git a/property_stone.lua b/property_stone.lua index 01b3882..01b64f4 100644 --- a/property_stone.lua +++ b/property_stone.lua @@ -20,6 +20,10 @@ minetest.register_node("cidades:property_stone_for_sale", { sounds = default.node_sound_stone_defaults(), }) +cidades.register_node_fix("cidades:property_stone_for_sale", function(pos, city_id) + minetest.get_meta(pos):set_string("city_id", city_id) +end) + -- Property Stone Purchased minetest.register_node("cidades:property_stone_purchased", { @@ -42,10 +46,23 @@ cidades.check_property_stone = function(pos) if cidades.db.check_property(data.owner) == false then cidades.reset_property(pos, data) end + + -- Check las login + local db_data = cidades.db.get_property(data.owner) + if cidades.get_date_hash() - db_data.last_login > cidades.max_days_inactive_owner then + cidades.reset_property(pos, data) + end end +minetest.register_lbm({ + name = "cidades:check_property", + nodenames = {"cidades:property_stone_purchased"}, + run_at_every_load = true, + action = function(pos, node) + cidades.check_property_stone(pos) + end, +}) --- Check property stones minetest.register_abm{ label = "check purchased property", nodenames = {"cidades:property_stone_purchased"}, @@ -55,3 +72,19 @@ minetest.register_abm{ cidades.check_property_stone(pos) end, } + + +-- Update last login +local update_last_login = function(player) + if not player then return end + local name = player:get_player_name() + + if cidades.db.check_property(name) == false then return end + + local data = cidades.db.get_property(name) + data.last_login = cidades.get_date_hash() +end + +minetest.register_on_joinplayer(function(player) + update_last_login(player) +end) diff --git a/protected_area.lua b/protected_area.lua index 1e34fcc..cb3b4f6 100644 --- a/protected_area.lua +++ b/protected_area.lua @@ -3,7 +3,7 @@ Copyright (C) 2020 BrunoMine (https://github.com/BrunoMine) You should have received a copy of the GNU General Public License - along with this program. If not, see 5. + along with this program. If not, see . Protected area ]] diff --git a/seller_node.lua b/seller_node.lua index 07b13b0..4a3e23d 100644 --- a/seller_node.lua +++ b/seller_node.lua @@ -51,6 +51,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) return minetest.chat_send_player(name, "You already own land. Sell it to buy that one.") end + -- Check payment if player:get_inventory():contains_item("main", cidades.money_item.." "..data.cost) == false then return minetest.chat_send_player(name, "You can not pay that.") end diff --git a/sfinv_menu.lua b/sfinv_menu.lua new file mode 100644 index 0000000..a4439b7 --- /dev/null +++ b/sfinv_menu.lua @@ -0,0 +1,95 @@ +--[[ + Mod Cidades for Minetest + Copyright (C) 2020 BrunoMine (https://github.com/BrunoMine) + + You should have received a copy of the GNU General Public License + along with this program. If not, see 5. + + Sfinv_Menu + ]] + +local formspec_with_land = "size[6,4]" + ..default.gui_bg + ..default.gui_bg_img + .."label[0.5,0;Choose a city]" + .."textlist[0.5,0.8;4.8,3;city;]" + + +local show_formspec = function(player) + local name = player:get_player_name() + if player:get_attribute("cidades:teleporter_choose") ~= nil then + minetest.show_formspec(name, "cidades:my_land", formspec.."button_exit[1,4.2;4,1;teleport;Go]") + else + minetest.show_formspec(name, "cidades:my_land", formspec) + end +end + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + + if formname == "cidades:my_land" then + local name = player:get_player_name() + + if fields.sell then + + minetest.show_formspec(name, "cidades:sell_my_land", "size[5,2.8]" + ..default.gui_bg + ..default.gui_bg_img + .."label[0,0;Are you sure? " + .."\nAll items and blocks that are on " + .."\nthe land will be removed automatically." + .."]" + .."button_exit[0,2;2,1;yes;Yes]" + .."button_exit[3,2;2,1;no;No]" + ) + + end + + end + + if formname == "cidades:sell_my_land" then + local name = player:get_player_name() + + if fields.yes then + if cidades.db.check_property(name) == true then + -- Remove registry + cidades.db.reset_property(name) + minetest.chat_send_player(name, "Your land has been sold.") + end + end + end +end) + + +-- Sfinv Buttom +sfinv_menu.register_button("cidades:my_land", { + title = "My Property", + icon = "default_apple.png", + func = function(player) + local name = player:get_player_name() + + if cidades.db.check_property(name) == false then + minetest.show_formspec(name, "cidades:my_land", "size[5,1]" + ..default.gui_bg + ..default.gui_bg_img + .."label[0.5,0;You do not have a property." + .."\nBuy a property in a city.]") + return + else + local data = cidades.db.get_property(name) + local city = cidades.active_cities[data.city_id] or {} + local city_name = city.name or "No defined" + + minetest.show_formspec(name, "cidades:my_land", "size[3,2.8]" + ..default.gui_bg + ..default.gui_bg_img + .."label[0,0;My Property" + .."\nCity: "..city_name + .."\nPrice: "..data.cost + .."]" + .."button[0,2;3,1;sell;Sell my property]" + ) + return + end + end, +}) diff --git a/teleporter.lua b/teleporter.lua index a55a012..ba21b48 100644 --- a/teleporter.lua +++ b/teleporter.lua @@ -13,12 +13,13 @@ local cities_string_list = "" local cities_list = {} --- Fosmpec padrao +-- Fosmpec local formspec = "size[6,5]" ..default.gui_bg ..default.gui_bg_img .."label[0.5,0;Choose a city]" - .."label[0.5,0;Choose a city]" + .."textlist[0.5,0.8;4.8,3;city;]" + .."button_exit[1,4.2;4,1;teleport;Go]" -- Atualizar lista de vilas local update_list = function() @@ -41,16 +42,12 @@ local update_list = function() }) end - if cities_string_list ~= "" then - - -- Update formspec - formspec = "size[6,5]" - ..default.gui_bg - ..default.gui_bg_img - .."label[0.5,0;Choose a city]" - .."textlist[0.5,0.8;4.8,3;city;"..cities_string_list.."]" - - end + -- Update formspec + formspec = "size[6,5]" + ..default.gui_bg + ..default.gui_bg_img + .."label[0.5,0;Choose a city]" + .."textlist[0.5,0.8;4.8,3;city;"..cities_string_list.."]" end update_list() diff --git a/time_count.lua b/time_count.lua new file mode 100644 index 0000000..efe26b3 --- /dev/null +++ b/time_count.lua @@ -0,0 +1,35 @@ +--[[ + Mod Cidades for Minetest + Copyright (C) 2020 BrunoMine (https://github.com/BrunoMine) + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Time count + ]] + +local days_until_month = { + 31, -- month 1 + 59, -- month 2 + 90, -- month 3 + 120,-- ... + 151, + 181, + 212, + 243, + 273, + 304, + 334, + 365 +} + +-- Get date hash +cidades.get_date_hash = function() + local years = tonumber(os.date("%Y")) -2000 -1 + local months = tonumber(os.date("%m")) -1 + local days = tonumber(os.date("%d")) -1 + + local hash = years*365 + days_until_month[months] + days + + return hash +end diff --git a/voxelmanip.lua b/voxelmanip.lua new file mode 100644 index 0000000..d719a6f --- /dev/null +++ b/voxelmanip.lua @@ -0,0 +1,100 @@ +--[[ + Mod Cidades for Minetest + Copyright (C) 2020 BrunoMine (https://github.com/BrunoMine) + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Voxel manip + ]] + +cidades.vm = {} + +--Place nodes +cidades.vm.place = function(minp, maxp, nodename) + + minp, maxp = vector.round(minp), vector.round(maxp) + + local c_node = minetest.get_content_id(nodename) + + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(minp, maxp) + local data = vm:get_data() + local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} + + -- Set nodes + for i in area:iter( + minp.x, minp.y, minp.z, + maxp.x, maxp.y, maxp.z + ) do + data[i] = c_node + end + + vm:set_data(data) + vm:write_to_map() +end + +-- Replace nodes +cidades.vm.replace = function(minp, maxp, replace) + + minp, maxp = vector.round(minp), vector.round(maxp) + + local repl = {} + for old, new in pairs(replace) do + repl[minetest.get_content_id(old)] = minetest.get_content_id(new) + end + + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(minp, maxp) + local data = vm:get_data() + local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} + + -- Replace nodes + for i in area:iter( + minp.x, minp.y, minp.z, + maxp.x, maxp.y, maxp.z + ) do + + data[i] = repl[data[i]] or data[i] + end + + vm:set_data(data) + vm:write_to_map() + +end + +-- Get nodes +cidades.vm.get = function(minp, maxp, nodes) + + minp, maxp = vector.round(minp), vector.round(maxp) + + local mod = {} + local nodes_found = {} + for nn,_ in pairs(nodes) do + mod[minetest.get_content_id(nn)] = nn + nodes[nn] = {} + end + + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(minp, maxp) + local data = vm:get_data() + local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} + + -- Find area + for i in area:iter( + minp.x, minp.y, minp.z, + maxp.x, maxp.y, maxp.z + ) do + if mod[data[i]] then + nodes_found[mod[data[i]]] = nodes_found[mod[data[i]]] or {} + table.insert(nodes_found[mod[data[i]]], area:position(i)) + + end + end + + vm:set_data(data) + vm:write_to_map() + + return nodes_found +end +