minetest_ltool/init.lua

676 lines
24 KiB
Lua
Raw Normal View History

2014-07-19 14:32:35 -07:00
ltool = {}
ltool.playerinfos = {}
ltool.default_edit_fields = {
2014-07-19 14:32:35 -07:00
axiom="",
rules_a="",
rules_b="",
rules_c="",
rules_d="",
trunk="",
leaves="",
leaves2="",
leaves2_chance="",
fruit="",
fruit_chance="",
angle="",
iterations="",
random_level="",
trunk_type="",
thin_branches="",
name = "",
2014-07-19 14:32:35 -07:00
}
2014-07-25 07:30:17 -07:00
minetest.register_node("ltool:sapling", {
description = "custom L-system tree sapling",
stack_max = 1,
drawtype = "plantlike",
tiles = { "ltool_sapling.png" },
inventory_image = "ltool_sapling.png",
wield_image = "ltool_sapling.png",
paramtype = "light",
paramtype2= "wallmounted",
walkable = false,
buildable_to = true,
groups = { dig_immediate = 3, not_in_creative_inventory=1 },
drop = "",
2014-07-25 07:30:17 -07:00
after_place_node = function(pos, placer, itemstack, pointed_thing)
-- Transfer metadata and start timer
local nodemeta = minetest.get_meta(pos)
local itemmeta = itemstack:get_metadata()
nodemeta:set_string("treedef", itemmeta)
local timer = minetest.get_node_timer(pos)
timer:start(5)
end,
on_timer = function(pos, elapsed)
-- Place tree
local meta = minetest.get_meta(pos)
local treedef = minetest.deserialize(meta:get_string("treedef"))
minetest.remove_node(pos)
minetest.spawn_tree(pos, treedef)
end,
})
do
local filepath = minetest.get_worldpath().."/ltool.mt"
local file = io.open(filepath, "r")
if(file) then
local string = file:read()
io.close(file)
if(string ~= nil) then
local savetable = minetest.deserialize(string)
2014-07-25 18:18:31 -07:00
if(savetable ~= nil) then
ltool.trees = savetable.trees
2014-07-25 18:18:31 -07:00
ltool.next_tree_id = savetable.next_tree_id
ltool.number_of_trees = savetable.number_of_trees
minetest.log("action", "[ltool] Tree data loaded from "..filepath..".")
else
minetest.log("error", "[ltool] Failed to load tree data from "..filepath..".")
end
2014-07-25 18:18:31 -07:00
else
minetest.log("error", "[ltool] Failed to load tree data from "..filepath..".")
end
2014-07-25 18:18:31 -07:00
else
ltool.trees = {}
ltool.number_of_trees = 0
ltool.next_tree_id = 1
end
end
2014-07-25 18:18:31 -07:00
function ltool.add_tree(name, author, treedef)
local id = ltool.next_tree_id
ltool.trees[id] = {name = name, author = author, treedef = treedef}
ltool.next_tree_id = ltool.next_tree_id + 1
ltool.number_of_trees = ltool.number_of_trees + 1
return id
end
2014-07-19 14:32:35 -07:00
ltool.seed = os.time()
ltool.loadtreeform = "size[6,7]"
function ltool.header(index)
2014-07-22 08:49:50 -07:00
return "tabheader[0,0;ltool_tab;Edit,Database,Plant,Cheat sheet;"..tostring(index)..";true;false]"
2014-07-19 14:32:35 -07:00
end
function ltool.edit(fields)
if(fields==nil) then
fields = ltool.default_edit_fields
2014-07-19 14:32:35 -07:00
end
local s = function(input)
if(input==nil) then
ret = ""
else
ret = minetest.formspec_escape(tostring(input))
end
return ret
end
return ""..
"field[0.2,-4;6,10;axiom;Axiom;"..s(fields.axiom).."]"..
"field[0.2,-3.4;6,10;rules_a;Rules set A;"..s(fields.rules_a).."]"..
"field[0.2,-2.7;6,10;rules_b;Rules set B;"..s(fields.rules_b).."]"..
"field[0.2,-2.1;6,10;rules_c;Rules set C;"..s(fields.rules_c).."]"..
"field[0.2,-1.5;6,10;rules_d;Rules set D;"..s(fields.rules_d).."]"..
"field[0.2,-0.9;3,10;trunk;Trunk node name;"..s(fields.trunk).."]"..
"field[0.2,-0.3;3,10;leaves;Leaves node name;"..s(fields.leaves).."]"..
"field[0.2,0.3;3,10;leaves2;Secondary leaves node name;"..s(fields.leaves2).."]"..
"field[0.2,0.9;3,10;leaves2_chance;Secondary leaves chance (in percent);"..s(fields.leaves2_chance).."]"..
"field[0.2,1.5;3,10;fruit;Fruit node name;"..s(fields.fruit).."]"..
"field[0.2,2.1;3,10;fruit_chance;Fruit chance (in percent);"..s(fields.fruit_chance).."]"..
"field[3.2,-0.9;3,10;angle;Angle (in degrees);"..s(fields.angle).."]"..
"field[3.2,-0.3;3,10;iterations;Iterations;"..s(fields.iterations).."]"..
"field[3.2,0.3;3,10;random_level;Randomness level;"..s(fields.random_level).."]"..
"field[3.2,0.9;3,10;trunk_type;Trunk type (single/double/crossed);"..s(fields.trunk_type).."]"..
"field[3.2,1.5;3,10;thin_branches;Thin branches? (true/false);"..s(fields.thin_branches).."]"..
"field[3.2,2.1;3,10;name;Name;"..s(fields.name).."]"..
"button[0,6.5;2,1;edit_save;Save]"
2014-07-19 14:32:35 -07:00
end
2014-07-23 17:41:39 -07:00
function ltool.database(index, playername)
2014-07-25 18:18:31 -07:00
local treestr, tree_ids = ltool.build_tree_textlist(index, playername)
if(treestr ~= nil) then
2014-07-25 18:18:31 -07:00
local indexstr
if(index == nil) then
indexstr = ""
else
indexstr = tostring(index)
end
ltool.playerinfos[playername].treeform.database.textlist = tree_ids
return ""..
"textlist[0,0;5,6;treelist;"..treestr..";"..tostring(index)..";false]"..
2014-07-25 19:18:04 -07:00
"button[0,6;2,1;database_rename;Rename tree]"..
"button[2.1,6;2,1;database_delete;Delete tree]"..
"button[0,6.5;2,1;database_copy;Copy to editor]"..
2014-07-25 07:42:46 -07:00
"button[2.1,6.5;2,1;database_update;Reload database]"
else
return "label[0,0;The tree database is empty.]"..
2014-07-25 07:42:46 -07:00
"button[2.1,6.5;2,1;database_update;Reload database]"
end
2014-07-19 14:32:35 -07:00
end
2014-07-22 08:49:50 -07:00
function ltool.cheat_sheet()
return ""..
"tablecolumns[text;text]"..
"tableoptions[background=#000000;highlight=#000000;border=false]"..
"table[0,0;6,7;cheat_sheet;"..
"Symbol,Action,"..
"G,Move forward one unit with the pen up,"..
"F,Move forward one unit with the pen down drawing trunks and branches,"..
"f,Move forward one unit with the pen down drawing leaves (100% chance),"..
"T,Move forward one unit with the pen down drawing trunks only,"..
"R,Move forward one unit with the pen down placing fruit,"..
"A,Replace with rules set A,"..
"B,Replace with rules set B,"..
"C,Replace with rules set C,"..
"D,Replace with rules set D,"..
"a,Replace with rules set A\\, chance 90%,"..
"b,Replace with rules set B\\, chance 80%,"..
"c,Replace with rules set C\\, chance 70%,"..
"d,Replace with rules set D\\, chance 60%,"..
"+,Yaw the turtle right by angle parameter,"..
"-,Yaw the turtle left by angle parameter,"..
"&,Pitch the turtle down by angle parameter,"..
"^,Pitch the turtle up by angle parameter,"..
"/,Roll the turtle to the right by angle parameter,"..
"*,Roll the turtle to the left by angle parameter,"..
"\\[,Save in stack current state info,"..
"\\],Recover from stack state info]"
end
2014-07-22 07:34:42 -07:00
function ltool.evaluate_edit_fields(fields)
local treedef = {}
-- Validation helper: Checks for invalid characters for the fields “axiom” and the 4 rule sets
local v = function(str)
local match = string.match(str, "[^][abcdfABCDFGTR+-/*&^]")
if(match==nil) then
return true
else
return false
end
end
if(v(fields.axiom) and v(fields.rules_a) and v(fields.rules_b) and v(fields.rules_c) and v(fields.rules_d)) then
treedef.rules_a = fields.rules_a
treedef.rules_b = fields.rules_b
treedef.rules_c = fields.rules_c
treedef.rules_d = fields.rules_d
treedef.axiom = fields.axiom
else
return nil, "The axiom or one of the rule sets contains at least one invalid character.\nSee the cheat sheet for a list of allowed characters."
end
2014-07-22 07:34:42 -07:00
treedef.trunk = fields.trunk
treedef.leaves = fields.leaves
treedef.leaves2 = fields.leaves2
treedef.leaves2_chance = fields.leaves2_chance
treedef.angle = tonumber(fields.angle)
2014-07-22 07:55:32 -07:00
if(treedef.angle == nil) then
return nil, "The field \"Angle\" must contain a number."
end
2014-07-22 07:34:42 -07:00
treedef.iterations = tonumber(fields.iterations)
2014-07-22 07:55:32 -07:00
if(treedef.iterations == nil) then
return nil, "The field \"Iterations\" must contain a natural number greater or equal to 0."
elseif(treedef.iterations < 0) then
return nil, "The field \"Iterations\" must contain a natural number greater or equal to 0."
end
2014-07-22 07:34:42 -07:00
treedef.random_level = tonumber(fields.random_level)
2014-07-22 07:55:32 -07:00
if(treedef.random_level == nil) then
return nil, "The field \"Randomness level\" must contain a number."
end
treedef.fruit = fields.fruit
treedef.fruit_chance = tonumber(fields.fruit_chance)
if(treedef.fruit_chance == nil) then
return nil, "The field \"Fruit chance\" must contain a number."
elseif(treedef.fruit_chance > 100 or treedef.fruit_chance < 0) then
return nil, "Fruit chance must be between 0% and 100%."
end
2014-07-22 07:34:42 -07:00
if(fields.trunk_type == "single" or fields.trunk_type == "double" or fields.trunk_type == "crossed") then
treedef.trunk_type = fields.trunk_type
else
return nil, "Trunk type must be \"single\", \"double\" or \"crossed\"."
end
treedef.thin_branches = fields.thin_branches
if(fields.thin_branches == "true") then
treedef.thin_branches = true
elseif(fields.thin_branches == "false") then
treedef.thin_branches = false
else
return nil, "Field \"Thin branches?\" must be \"true\" or \"false\"."
end
local name = fields.name
if(name == "") then
return nil, "Name is empty."
end
return treedef, name
end
function ltool.tree_to_fields(tree)
local s = function(i)
if(i==nil) then
return ""
else
return tostring(i)
end
end
local fields = {}
fields.axiom = s(tree.treedef.axiom)
fields.rules_a = s(tree.treedef.rules_a)
fields.rules_b = s(tree.treedef.rules_b)
fields.rules_c = s(tree.treedef.rules_c)
fields.rules_d = s(tree.treedef.rules_d)
fields.trunk = s(tree.treedef.trunk)
fields.leaves = s(tree.treedef.leaves)
fields.leaves2 = s(tree.treedef.leaves2)
fields.leaves2_chance = s(tree.treedef.leaves2)
fields.fruit = s(tree.treedef.leaves2)
fields.fruit_chance = s(tree.treedef.fruit_chance)
fields.angle = s(tree.treedef.angle)
fields.iterations = s(tree.treedef.iterations)
fields.random_level = s(tree.treedef.random_level)
fields.trunk_type = s(tree.treedef.trunk_type)
fields.thin_branches = s(tree.treedef.thin_branches)
fields.name = s(tree.name)
return fields
end
function ltool.plant(tree, fields)
if(tree ~= nil) then
if(fields==nil) then
fields = {}
end
local s = function(i)
if(i==nil) then return ""
else return tostring(minetest.formspec_escape(i))
end
end
local seed
if(fields.seed == nil) then
seed = tostring(ltool.seed)
else
seed = fields.seed
end
local dropdownindex
if(fields.plantmode == "Absolute coordinates") then
dropdownindex = 1
elseif(fields.plantmode == "Relative coordinates") then
dropdownindex = 2
else
dropdownindex = 1
end
return ""..
2014-07-23 07:14:03 -07:00
"label[0,-0.2;Selected tree: "..minetest.formspec_escape(tree.name).."]"..
"dropdown[-0.1,0.5;5;plantmode;Absolute coordinates,Relative coordinates;"..dropdownindex.."]"..
"field[0.2,-2.7;6,10;x;x;"..s(fields.x).."]"..
"field[0.2,-2.1;6,10;y;y;"..s(fields.y).."]"..
"field[0.2,-1.5;6,10;z;z;"..s(fields.z).."]"..
"field[0.2,0;6,10;seed;Seed;"..seed.."]"..
2014-07-25 07:30:17 -07:00
"button[0,6.5;2,1;plant_plant;Plant]"..
"button[2.1,6.5;2,1;sapling;Give me a sapling]"
else
return "label[0,0;No tree in database selected or database is empty.]"
end
2014-07-19 14:32:35 -07:00
end
function ltool.show_dialog(playername, formname, message)
local formspec = "size[6,2;]label[0,0.2;"..message.."]"..
"button[2,1.5;2,1;okay;OK]"
minetest.show_formspec(playername, formname, formspec)
end
2014-07-19 14:32:35 -07:00
2014-07-25 18:18:31 -07:00
function ltool.build_tree_textlist(index, playername)
2014-07-19 14:32:35 -07:00
local string = ""
2014-07-25 18:18:31 -07:00
local colorstring
if(ltool.number_of_trees == 0) then
return nil
end
2014-07-25 18:18:31 -07:00
local tree_ids = ltool.get_tree_ids()
for i=1,#tree_ids do
local tree_id = tree_ids[i]
local tree = ltool.trees[tree_id]
if(tree.author == playername) then
2014-07-23 17:41:39 -07:00
colorstring = "#FFFF00"
else
colorstring = ""
end
2014-07-25 18:18:31 -07:00
string = string .. colorstring .. tostring(tree_id) .. ": " .. minetest.formspec_escape(tree.name)
if(i~=#tree_ids) then
2014-07-19 14:32:35 -07:00
string = string .. ","
end
end
2014-07-25 18:18:31 -07:00
return string, tree_ids
2014-07-19 14:32:35 -07:00
end
2014-07-25 18:18:31 -07:00
-- returns a simple table of all the tree IDs
function ltool.get_tree_ids()
local ids = {}
for tree_id, _ in pairs(ltool.trees) do
table.insert(ids, tree_id)
end
return ids
end
--[[ In a table of tree IDs (returned by ltool.get_tree_ids, parameter tree_ids), this function
searches for the first occourance of the value searched_tree_id and returns its index.
This is basically a reverse lookup utility. ]]
function ltool.get_tree_id_index(searched_tree_id, tree_ids)
for i=1, #tree_ids do
local table_tree_id = tree_ids[i]
if(searched_tree_id == table_tree_id) then
return i
end
end
end
2014-07-19 14:32:35 -07:00
2014-07-25 18:18:31 -07:00
-- Returns the selected tree of the given player
function ltool.get_selected_tree(playername)
local sel = ltool.playerinfos[playername].dbsel
if(sel ~= nil) then
local tree_id = ltool.playerinfos[playername].treeform.database.textlist[sel]
if(tree_id ~= nil) then
return ltool.trees[tree_id]
end
end
return nil
end
function ltool.get_selected_tree_id(playername)
local sel = ltool.playerinfos[playername].dbsel
if(sel ~= nil) then
return ltool.playerinfos[playername].treeform.database.textlist[sel]
end
return nil
end
2014-07-19 14:32:35 -07:00
2014-07-19 14:32:35 -07:00
ltool.treeform = ltool.loadtreeform..ltool.header(1)..ltool.edit()
minetest.register_chatcommand("treeform",
{
params = "",
description = "Open L-system tree builder formular.",
privs = {privs=false},
func = function(playername, param)
local formspec = ltool.loadtreeform..ltool.header(1)..ltool.edit(ltool.playerinfos[playername].treeform.edit.fields)
minetest.show_formspec(playername, "ltool:treeform_edit", formspec)
2014-07-19 14:32:35 -07:00
end
})
2014-07-25 18:18:31 -07:00
function ltool.dbsel_to_tree(dbsel, playername)
return ltool.trees[ltool.playerinfos[playername].treeform.database.textlist[dbsel]]
end
function ltool.save_fields(playername,formname,fields)
if(formname=="ltool:treeform_edit") then
ltool.playerinfos[playername].treeform.edit.fields = fields
elseif(formname=="ltool:treeform_database") then
ltool.playerinfos[playername].treeform.database.fields = fields
elseif(formname=="ltool:treeform_plant") then
ltool.playerinfos[playername].treeform.plant.fields = fields
end
end
2014-07-19 14:32:35 -07:00
function ltool.process_form(player,formname,fields)
2014-07-22 07:34:42 -07:00
local playername = player:get_player_name()
2014-07-25 18:18:31 -07:00
local seltree = ltool.get_selected_tree(playername)
2014-07-26 05:58:12 -07:00
if(formname == "ltool:treeform_edit" or formname == "ltool:treeform_database" or formname == "ltool:treeform_plant" or formname == "ltool:treeform_cheat_sheet") then
2014-07-19 14:32:35 -07:00
if fields.ltool_tab ~= nil then
ltool.save_fields(playername, formname, fields)
2014-07-19 14:32:35 -07:00
local tab = tonumber(fields.ltool_tab)
2014-07-26 05:58:12 -07:00
local formspec, subformname, contents
2014-07-19 14:32:35 -07:00
if(tab==1) then
contents = ltool.edit(ltool.playerinfos[playername].treeform.edit.fields)
2014-07-26 05:58:12 -07:00
subformname = "edit"
2014-07-19 14:32:35 -07:00
elseif(tab==2) then
2014-07-23 17:41:39 -07:00
contents = ltool.database(ltool.playerinfos[playername].dbsel, playername)
2014-07-26 05:58:12 -07:00
subformname = "database"
2014-07-19 14:32:35 -07:00
elseif(tab==3) then
if(ltool.number_of_trees > 0) then
contents = ltool.plant(seltree, ltool.playerinfos[playername].treeform.plant.fields)
else
contents = ltool.plant(nil)
end
2014-07-26 05:58:12 -07:00
subformname = "plant"
2014-07-22 08:49:50 -07:00
elseif(tab==4) then
contents = ltool.cheat_sheet()
2014-07-26 05:58:12 -07:00
subformname = "cheat_sheet"
2014-07-19 14:32:35 -07:00
end
2014-07-22 08:49:50 -07:00
formspec = ltool.loadtreeform..ltool.header(tab)..contents
2014-07-26 05:58:12 -07:00
minetest.show_formspec(playername, "ltool:treeform_" .. subformname, formspec)
2014-07-19 14:32:35 -07:00
return
end
2014-07-26 05:58:12 -07:00
end
if(formname == "ltool:treeform_plant") then
if(fields.plant_plant) then
2014-07-25 18:18:31 -07:00
if(seltree ~= nil) then
minetest.log("action","[ltool] Planting tree")
local treedef = seltree.treedef
local x,y,z = tonumber(fields.x), tonumber(fields.y), tonumber(fields.z)
local tree_pos
local fail = function()
ltool.save_fields(playername, formname, fields)
ltool.show_dialog(playername, "ltool:treeform_error_badplantfields", "Error: The coordinates must be numbers.")
2014-07-23 07:14:03 -07:00
end
2014-07-25 18:18:31 -07:00
if(fields.plantmode == "Absolute coordinates") then
if(type(x)~="number" or type(y) ~= "number" or type(z) ~= "number") then
fail()
return
end
tree_pos = {x=fields.x, y=fields.y, z=fields.z}
elseif(fields.plantmode == "Relative coordinates") then
if(type(x)~="number" or type(y) ~= "number" or type(z) ~= "number") then
fail()
return
end
tree_pos = player:getpos()
tree_pos.x = tree_pos.x + fields.x
tree_pos.y = tree_pos.y + fields.y
tree_pos.z = tree_pos.z + fields.z
else
minetest.log("error", "[ltool] fields.plantmode = "..tostring(fields.plantmode))
2014-07-23 07:14:03 -07:00
end
2014-07-25 18:18:31 -07:00
if(tonumber(fields.seed)~=nil) then
treedef.seed = tonumber(fields.seed)
end
minetest.spawn_tree(tree_pos, treedef)
treedef.seed = nil
2014-07-23 07:14:03 -07:00
end
2014-07-25 07:30:17 -07:00
elseif(fields.sapling) then
2014-07-25 18:18:31 -07:00
if(seltree ~= nil) then
local sapling = ItemStack("ltool:sapling")
-- TODO: Copy the seed into the sapling, too.
sapling:set_metadata(minetest.serialize(seltree.treedef))
local leftover = player:get_inventory():add_item("main", sapling)
if(not leftover:is_empty()) then
ltool.save_fields(playername, formname, fields)
ltool.show_dialog(playername, "ltool:treeform_error_sapling", "Error: The sapling could not be given to you. Probably your inventory is full.")
end
2014-07-25 18:18:31 -07:00
end
2014-07-26 05:58:12 -07:00
end
elseif(formname == "ltool:treeform_edit") then
if(fields.edit_save) then
2014-07-22 07:34:42 -07:00
local param1, param2
param1, param2 = ltool.evaluate_edit_fields(fields)
2014-07-22 07:55:32 -07:00
if(param1 ~= nil) then
2014-07-22 07:34:42 -07:00
local treedef = param1
local name = param2
local add = true
for k,v in pairs(ltool.trees) do
if(v.name == name) then
ltool.save_fields(playername, formname, fields)
if(v.author == playername) then
local formspec = "size[6,2;]label[0,0.2;You already have a tree with this name. Do you want to replace it?]"..
"button[0,1.5;2,1;replace_yes;Yes]"..
"button[2,1.5;2,1;replace_no;No]"
minetest.show_formspec(playername, "ltool:treeform_replace", formspec)
else
ltool.show_dialog(playername, "ltool:treeform_error_nameclash", "Error: This name is already taken by someone else.\nPlease choose a different name.")
end
add = false
end
end
if(add == true) then
ltool.add_tree(name, playername, treedef)
end
2014-07-19 14:32:35 -07:00
else
ltool.save_fields(playername, formname, fields)
2014-07-22 07:34:42 -07:00
local formspec = "size[6,2;]label[0,0.2;Error: The tree definition is invalid.]"..
"label[0,0.4;"..minetest.formspec_escape(param2).."]"..
"button[2,1.5;2,1;okay;OK]"
minetest.show_formspec(playername, "ltool:treeform_error_badtreedef", formspec)
2014-07-19 14:32:35 -07:00
end
2014-07-26 05:58:12 -07:00
end
elseif(formname == "ltool:treeform_database") then
if(fields.treelist) then
local event = minetest.explode_textlist_event(fields.treelist)
if(event.type == "CHG") then
ltool.playerinfos[playername].dbsel = event.index
2014-07-23 17:41:39 -07:00
local formspec = ltool.loadtreeform..ltool.header(2)..ltool.database(event.index, playername)
2014-07-26 05:58:12 -07:00
minetest.show_formspec(playername, "ltool:treeform_database", formspec)
end
2014-07-19 14:32:35 -07:00
elseif(fields.database_copy) then
2014-07-25 18:18:31 -07:00
if(seltree ~= nil) then
if(ltool.playerinfos[playername] ~= nil) then
local formspec = ltool.loadtreeform..ltool.header(1)..ltool.edit(ltool.tree_to_fields(seltree))
2014-07-26 05:58:12 -07:00
minetest.show_formspec(playername, "ltool:treeform_edit", formspec)
2014-07-25 18:18:31 -07:00
end
else
ltool.show_dialog(playername, "ltool:treeform_error_nodbsel", "Error: No tree is selected.")
end
2014-07-21 17:08:07 -07:00
elseif(fields.database_update) then
2014-07-23 17:41:39 -07:00
local formspec = ltool.loadtreeform..ltool.header(2)..ltool.database(ltool.playerinfos[playername].dbsel, playername)
2014-07-26 05:58:12 -07:00
minetest.show_formspec(playername, "ltool:treeform_database", formspec)
elseif(fields.database_delete) then
2014-07-25 18:18:31 -07:00
if(seltree ~= nil) then
if(playername == seltree.author) then
local remove_id = ltool.get_selected_tree_id(playername)
if(remove_id ~= nil) then
ltool.trees[remove_id] = nil
ltool.number_of_trees = ltool.number_of_trees - 1
for k,v in pairs(ltool.playerinfos) do
if(v.dbsel ~= nil) then
if(v.dbsel > ltool.number_of_trees) then
v.dbsel = ltool.number_of_trees
end
if(v.dbsel < 1) then
v.dbsel = 1
end
end
end
local formspec = ltool.loadtreeform..ltool.header(2)..ltool.database(ltool.playerinfos[playername].dbsel, playername)
2014-07-26 05:58:12 -07:00
minetest.show_formspec(playername, "ltool:treeform_database", formspec)
end
2014-07-25 18:18:31 -07:00
else
ltool.show_dialog(playername, "ltool:treeform_error_delete", "Error: This tree is not your own. You may only delete your own trees.")
end
else
ltool.show_dialog(playername, "ltool:treeform_error_nodbsel", "Error: No tree is selected.")
end
2014-07-25 19:18:04 -07:00
elseif(fields.database_rename) then
if(seltree ~= nil) then
if(playername == seltree.author) then
local formspec = "field[newname;New name:;"..minetest.formspec_escape(seltree.name).."]"
minetest.show_formspec(playername, "ltool:treeform_rename", formspec)
else
ltool.show_dialog(playername, "ltool:treeform_error_rename_forbidden", "Error: This tree is not your own. You may only rename your own trees.")
2014-07-25 19:18:04 -07:00
end
else
ltool.show_dialog(playername, "ltool:treeform_error_nodbsel", "Error: No tree is selected.")
2014-07-25 19:18:04 -07:00
end
end
elseif(formname == "ltool:treeform_replace") then
local editfields = ltool.playerinfos[playername].treeform.edit.fields
local newtreedef, newname = ltool.evaluate_edit_fields(editfields)
if(fields.replace_yes) then
for tree_id,tree in pairs(ltool.trees) do
if(tree.name == newname) then
--[[ The old tree is deleted and a
new one with a new ID is created ]]
local new_tree_id = ltool.next_tree_id
ltool.trees[new_tree_id] = {}
ltool.trees[new_tree_id].treedef = newtreedef
ltool.trees[new_tree_id].name = newname
ltool.trees[new_tree_id].author = tree.author
ltool.next_tree_id = ltool.next_tree_id + 1
ltool.trees[tree_id] = nil
end
end
end
local formspec = ltool.loadtreeform..ltool.header(1)..ltool.edit(editfields)
minetest.show_formspec(playername, "ltool:treeform_edit", formspec)
2014-07-25 19:18:04 -07:00
elseif(formname == "ltool:treeform_rename") then
if(fields.newname ~= "") then
seltree.name = fields.newname
local formspec = ltool.loadtreeform..ltool.header(2)..ltool.database(ltool.playerinfos[playername].dbsel, playername)
2014-07-26 05:58:12 -07:00
minetest.show_formspec(playername, "ltool:treeform_database", formspec)
2014-07-25 19:18:04 -07:00
else
ltool.show_dialog(playername, "ltool:treeform_error_bad_rename", "Error: This name is empty. The tree name must be non-empty.")
2014-07-19 14:32:35 -07:00
end
elseif(formname == "ltool:treeform_error_badtreedef" or formname == "ltool:treeform_error_nameclash") then
local formspec = ltool.loadtreeform..ltool.header(1)..ltool.edit(ltool.playerinfos[playername].treeform.edit.fields)
2014-07-26 05:58:12 -07:00
minetest.show_formspec(playername, "ltool:treeform_edit", formspec)
elseif(formname == "ltool:treeform_error_badplantfields" or formname == "ltool:treeform_error_sapling") then
local formspec = ltool.loadtreeform..ltool.header(3)..ltool.plant(seltree, ltool.playerinfos[playername].treeform.plant.fields)
2014-07-26 05:58:12 -07:00
minetest.show_formspec(playername, "ltool:treeform_plant", formspec)
elseif(formname == "ltool:treeform_error_delete" or formname == "ltool:treeform_error_rename_forbidden" or formname == "ltool:treeform_error_nodbsel") then
local formspec = ltool.loadtreeform..ltool.header(2)..ltool.database(ltool.playerinfos[playername].dbsel, playername)
2014-07-26 05:58:12 -07:00
minetest.show_formspec(playername, "ltool:treeform_database", formspec)
elseif(formname == "ltool:treeform_error_bad_rename") then
local formspec = "field[newname;New name:;"..minetest.formspec_escape(seltree.name).."]"
minetest.show_formspec(playername, "ltool:treeform_rename", formspec)
2014-07-19 14:32:35 -07:00
end
end
function ltool.leave(player)
ltool.playerinfos[player:get_player_name()] = nil
end
function ltool.join(player)
2014-07-25 18:18:31 -07:00
local infotable = {}
infotable.dbsel = nil
infotable.treeform = {}
infotable.treeform.database = {}
--[[ This table stores a mapping of the textlist IDs in the database formspec and the tree IDs.
It is updated each time ltool.database is called. ]]
infotable.treeform.database.textlist = nil
--[[ the “fields” tables store the values of the input fields of a formspec. It is updated
whenever the formspec is changed, i.e. on tab change ]]
infotable.treeform.database.fields = {}
infotable.treeform.plant = {}
infotable.treeform.plant.fields = {}
infotable.treeform.edit = {}
infotable.treeform.edit.fields = {}
2014-07-25 18:18:31 -07:00
ltool.playerinfos[player:get_player_name()] = infotable
2014-07-19 14:32:35 -07:00
end
function ltool.save_to_file()
local savetable = {}
savetable.trees = ltool.trees
2014-07-25 18:18:31 -07:00
savetable.number_of_trees = ltool.number_of_trees
savetable.next_tree_id = ltool.next_tree_id
local savestring = minetest.serialize(savetable)
local filepath = minetest.get_worldpath().."/ltool.mt"
local file = io.open(filepath, "w")
if(file) then
file:write(savestring)
io.close(file)
minetest.log("action", "[ltool] Tree data saved to "..filepath..".")
else
minetest.log("error", "[ltool] Failed to write ltool data to "..filepath".")
end
end
2014-07-19 14:32:35 -07:00
minetest.register_on_player_receive_fields(ltool.process_form)
minetest.register_on_leaveplayer(ltool.leave)
minetest.register_on_joinplayer(ltool.join)
minetest.register_on_shutdown(ltool.save_to_file)