mirror of
git://repo.or.cz/minetest_schemedit.git
synced 2025-01-09 17:40:32 +01:00
Complete overhaul of setting node probabilities
Node probabilities are now set with a special tool instead of saving it in a node. Also the reliance on external files has been eliminated. This method was very buggy anyway.
This commit is contained in:
parent
fd9502f179
commit
68a096f5fa
354
init.lua
354
init.lua
@ -3,7 +3,6 @@
|
|||||||
advschem = {}
|
advschem = {}
|
||||||
|
|
||||||
local path = minetest.get_worldpath().."/advschem.mt"
|
local path = minetest.get_worldpath().."/advschem.mt"
|
||||||
local marked = {}
|
|
||||||
advschem.markers = {}
|
advschem.markers = {}
|
||||||
|
|
||||||
-- [local function] Renumber table
|
-- [local function] Renumber table
|
||||||
@ -111,6 +110,107 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- [event] Transfer probabilities and force place on item placement into node
|
||||||
|
minetest.register_on_placenode(function(pos, newnode, player, oldnode, itemstack)
|
||||||
|
local smeta = itemstack:get_meta():to_table().fields
|
||||||
|
local nmeta = minetest.get_meta(pos)
|
||||||
|
if smeta.advschem_prob then
|
||||||
|
nmeta:set_string("advschem_prob", smeta_advschem_prob)
|
||||||
|
end
|
||||||
|
if smeta.advschem_force_place then
|
||||||
|
nmeta:set_string("advschem_force_place", smeta_advschem_force_place)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Helper function. Scans probabilities of all nodes in the given area and returns a prob_list
|
||||||
|
advschem.scan_metadata = function(pos1, pos2)
|
||||||
|
local prob_list = {}
|
||||||
|
|
||||||
|
for x=pos1.x, pos2.x do
|
||||||
|
for y=pos1.y, pos2.y do
|
||||||
|
for z=pos1.z, pos2.z do
|
||||||
|
local scanpos = {x=x, y=y, z=z}
|
||||||
|
local node = minetest.get_node_or_nil(scanpos)
|
||||||
|
|
||||||
|
local prob, force_place
|
||||||
|
if node == nil or node.name == "advschem:void" then
|
||||||
|
prob = 0
|
||||||
|
force_place = false
|
||||||
|
else
|
||||||
|
local meta = minetest.get_meta(scanpos)
|
||||||
|
|
||||||
|
prob = tonumber(meta:get_string("advschem_prob")) or 127
|
||||||
|
local fp = meta:get_string("advschem_force_place")
|
||||||
|
if fp == "true" then
|
||||||
|
force_place = true
|
||||||
|
else
|
||||||
|
force_place = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ostrpos = minetest.pos_to_string(scanpos)
|
||||||
|
prob_list[ostrpos] = {
|
||||||
|
pos = scanpos,
|
||||||
|
prob = prob,
|
||||||
|
force_place = force_place,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return prob_list
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sets probability and force_place metadata of an item.
|
||||||
|
-- Also updates item description.
|
||||||
|
-- The itemstack is updated in-place.
|
||||||
|
local function set_item_metadata(itemstack, prob, force_place)
|
||||||
|
local smeta = itemstack:get_meta()
|
||||||
|
local prob_desc = "\nProbability: "..(prob) or
|
||||||
|
smeta:get_string("advschem_prob") or "Not Set"
|
||||||
|
-- Update probability
|
||||||
|
if prob and prob >= 0 and prob < 127 then
|
||||||
|
smeta:set_string("advschem_prob", tostring(prob))
|
||||||
|
elseif prob and prob == 127 then
|
||||||
|
-- Clear prob metadata for default probability
|
||||||
|
prob_desc = ""
|
||||||
|
smeta:set_string("advschem_prob", nil)
|
||||||
|
else
|
||||||
|
prob_desc = "\nProbability: "..(smeta:get_string("advschem_prob") or
|
||||||
|
"Not Set")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update force place if value is not nil
|
||||||
|
if force_place then
|
||||||
|
smeta:set_string("advschem_force_place", "true")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update description
|
||||||
|
local desc = minetest.registered_items[itemstack:get_name()].description
|
||||||
|
local meta_desc = smeta:get_string("description")
|
||||||
|
if meta_desc and meta_desc ~= "" then
|
||||||
|
desc = meta_desc
|
||||||
|
end
|
||||||
|
|
||||||
|
local original_desc = smeta:get_string("original_description")
|
||||||
|
if original_desc and original_desc ~= "" then
|
||||||
|
desc = original_desc
|
||||||
|
else
|
||||||
|
smeta:set_string("original_description", desc)
|
||||||
|
end
|
||||||
|
|
||||||
|
local force_desc = ""
|
||||||
|
if smeta:get_string("advschem_force_place") == "true" then
|
||||||
|
force_desc = "\n".."Force Place"
|
||||||
|
end
|
||||||
|
|
||||||
|
desc = desc..minetest.colorize("#D79E9E", prob_desc..force_desc)
|
||||||
|
|
||||||
|
smeta:set_string("description", desc)
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
--- Formspec Tabs
|
--- Formspec Tabs
|
||||||
---
|
---
|
||||||
@ -205,7 +305,7 @@ advschem.add_form("main", {
|
|||||||
local path = minetest.get_worldpath().."/schems/"
|
local path = minetest.get_worldpath().."/schems/"
|
||||||
minetest.mkdir(path)
|
minetest.mkdir(path)
|
||||||
|
|
||||||
local plist = minetest.deserialize(meta.prob_list)
|
local plist = advschem.scan_metadata(pos1, pos2)
|
||||||
local probability_list = {}
|
local probability_list = {}
|
||||||
for _, i in pairs(plist) do
|
for _, i in pairs(plist) do
|
||||||
local prob = i.prob
|
local prob = i.prob
|
||||||
@ -254,14 +354,9 @@ advschem.add_form("main", {
|
|||||||
advschem.show_formspec(pos, minetest.get_player_by_name(name), "main")
|
advschem.show_formspec(pos, minetest.get_player_by_name(name), "main")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Update pos1 and pos2 in marked table (for interaction checking)
|
|
||||||
if update_positions then
|
if update_positions then
|
||||||
local pos1, pos2 = advschem.size(pos)
|
local pos1, pos2 = advschem.size(pos)
|
||||||
pos1, pos2 = advschem.sort_pos(pos1, pos2)
|
pos1, pos2 = advschem.sort_pos(pos1, pos2)
|
||||||
marked[minetest.pos_to_string(pos)] = {
|
|
||||||
pos1 = pos1,
|
|
||||||
pos2 = pos2,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
@ -298,7 +393,7 @@ advschem.add_form("prob", {
|
|||||||
]]
|
]]
|
||||||
else
|
else
|
||||||
form = form .. [[
|
form = form .. [[
|
||||||
label[1,0.2;Insert node in slot.]
|
label[1,0.2;Insert schematc node probability tool into slot.]
|
||||||
]]
|
]]
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -325,53 +420,20 @@ advschem.add_form("prob", {
|
|||||||
elseif fields.force_place or fields.save or
|
elseif fields.force_place or fields.save or
|
||||||
fields.key_enter_field == "probability" then
|
fields.key_enter_field == "probability" then
|
||||||
|
|
||||||
local prob_desc = "\nProbability: "..(fields.probability or
|
local prob = tonumber(fields.probability)
|
||||||
smeta:get_string("advschem_prob") or "Not Set")
|
local force_place
|
||||||
-- Update probability
|
|
||||||
if fields.probability ~= "" then
|
|
||||||
local prob = tonumber(fields.probability)
|
|
||||||
if prob and prob >= 0 and prob < 127 then
|
|
||||||
smeta:set_string("advschem_prob", fields.probability)
|
|
||||||
elseif prob and prob == 127 then
|
|
||||||
-- Clear prob metadata for default probability
|
|
||||||
prob_desc = ""
|
|
||||||
smeta:set_string("advschem_prob", nil)
|
|
||||||
else
|
|
||||||
prob_desc = "\nProbability: "..(smeta:get_string("advschem_prob") or
|
|
||||||
"Not Set")
|
|
||||||
advschem.show_formspec(pos, minetest.get_player_by_name(name), "prob")
|
|
||||||
end
|
|
||||||
else
|
|
||||||
smeta:set_string("advschem_prob", nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Update force place if fields value is not nil
|
|
||||||
if fields.force_place ~= nil then
|
if fields.force_place ~= nil then
|
||||||
smeta:set_string("advschem_force_place", fields.force_place)
|
if fields.force_place == "true" then
|
||||||
|
force_place = true
|
||||||
|
elseif fields.force_place == "false" then
|
||||||
|
force_place = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Update description
|
set_item_metadata(stack, prob, force_place)
|
||||||
local desc = minetest.registered_items[stack:get_name()].description
|
|
||||||
local meta_desc = smeta:get_string("description")
|
|
||||||
if meta_desc and meta_desc ~= "" then
|
|
||||||
desc = meta_desc
|
|
||||||
end
|
|
||||||
|
|
||||||
local original_desc = smeta:get_string("original_description")
|
advschem.show_formspec(pos, minetest.get_player_by_name(name), "prob")
|
||||||
if original_desc and original_desc ~= "" then
|
|
||||||
desc = original_desc
|
|
||||||
else
|
|
||||||
smeta:set_string("original_description", desc)
|
|
||||||
end
|
|
||||||
|
|
||||||
local force_desc = ""
|
|
||||||
if smeta:get_string("advschem_force_place") == "true" then
|
|
||||||
force_desc = "\n".."Force Place"
|
|
||||||
end
|
|
||||||
|
|
||||||
desc = desc..minetest.colorize("#D79E9E", prob_desc..force_desc)
|
|
||||||
|
|
||||||
smeta:set_string("description", desc)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Update itemstack
|
-- Update itemstack
|
||||||
@ -504,32 +566,65 @@ advschem.add_form("slice", {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
advschem.add_form("probtool", {
|
||||||
|
cache_name = false,
|
||||||
|
caption = "Schematic Node Probability Tool",
|
||||||
|
get = function(self, pos, name)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if not player then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local probtool = player:get_wielded_item()
|
||||||
|
if probtool:get_name() ~= "advschem:probtool" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta = probtool:get_meta()
|
||||||
|
local prob = tonumber(meta:get_string("advschem_prob"))
|
||||||
|
local force_place = meta:get_string("advschem_force_place")
|
||||||
|
|
||||||
|
if not prob then
|
||||||
|
prob = 127
|
||||||
|
end
|
||||||
|
if force_place == nil or force_place == "" then
|
||||||
|
force_place = "false"
|
||||||
|
end
|
||||||
|
local form = "size[5,4]"..
|
||||||
|
"label[0,0;Schematic Node Probability Tool]"..
|
||||||
|
"field[0.75,1;4,1;prob;Probability;"..prob.."]"..
|
||||||
|
"button_exit[0.25,3;2,1;cancel;Cancel]"..
|
||||||
|
"button_exit[2.75,3;2,1;submit;Okay]"..
|
||||||
|
"tooltip[submit;Use the new probability value for this tool]"..
|
||||||
|
"field_close_on_enter[prob;false]"
|
||||||
|
return form
|
||||||
|
end,
|
||||||
|
handle = function(self, pos, name, fields)
|
||||||
|
if fields.submit then
|
||||||
|
local prob = tonumber(fields.prob)
|
||||||
|
if prob then
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if not player then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local probtool = player:get_wielded_item()
|
||||||
|
if probtool:get_name() ~= "advschem:probtool" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
set_item_metadata(probtool, prob, false)
|
||||||
|
|
||||||
|
player:set_wielded_item(probtool)
|
||||||
|
|
||||||
|
-- TODO: Force place
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
---
|
---
|
||||||
--- API
|
--- API
|
||||||
---
|
---
|
||||||
|
|
||||||
-- [function] Load
|
|
||||||
function advschem.load()
|
|
||||||
local res = io.open(path, "r")
|
|
||||||
if res then
|
|
||||||
marked = minetest.deserialize(res:read("*a"))
|
|
||||||
res:close()
|
|
||||||
end
|
|
||||||
|
|
||||||
if type(marked) ~= "table" then
|
|
||||||
marked = {}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- [function] Save
|
|
||||||
function advschem.save()
|
|
||||||
local res = io.open(path, "w")
|
|
||||||
if res then
|
|
||||||
res:write(minetest.serialize(marked))
|
|
||||||
res:close()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Copies and modifies positions `pos1` and `pos2` so that each component of
|
--- Copies and modifies positions `pos1` and `pos2` so that each component of
|
||||||
-- `pos1` is less than or equal to the corresponding component of `pos2`.
|
-- `pos1` is less than or equal to the corresponding component of `pos2`.
|
||||||
-- Returns the new positions.
|
-- Returns the new positions.
|
||||||
@ -665,78 +760,6 @@ end
|
|||||||
--- Registrations
|
--- Registrations
|
||||||
---
|
---
|
||||||
|
|
||||||
-- [event] Save data on shut down
|
|
||||||
minetest.register_on_shutdown(advschem.save)
|
|
||||||
|
|
||||||
-- [event] Transfer probabilities and force place on place node
|
|
||||||
minetest.register_on_placenode(function(pos, newnode, player, oldnode, itemstack)
|
|
||||||
local smeta = itemstack:get_meta():to_table().fields
|
|
||||||
|
|
||||||
local prob
|
|
||||||
if smeta.advschem_prob and tonumber(smeta.advschem_prob) then
|
|
||||||
prob = tonumber(smeta.advschem_prob)
|
|
||||||
elseif newnode.name == "advschem:void" then
|
|
||||||
prob = 0
|
|
||||||
else
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local px, py, pz = pos.x, pos.y, pos.z
|
|
||||||
for strpos, r in pairs(marked) do
|
|
||||||
local ap1, ap2 = r.pos1, r.pos2
|
|
||||||
if (px >= ap1.x and px <= ap2.x) and
|
|
||||||
(py >= ap1.y and py <= ap2.y) and
|
|
||||||
(pz >= ap1.z and pz <= ap2.z) then
|
|
||||||
local realpos = minetest.string_to_pos(strpos)
|
|
||||||
local node = minetest.get_node_or_nil(realpos)
|
|
||||||
|
|
||||||
if node and node.name == "advschem:creator" then
|
|
||||||
local meta = minetest.get_meta(realpos)
|
|
||||||
local prob_list = minetest.deserialize(meta:get_string("prob_list"))
|
|
||||||
|
|
||||||
local force_place = false
|
|
||||||
if newnode.name ~= "advschem:void" and smeta.advschem_force_place == "true" then
|
|
||||||
force_place = true
|
|
||||||
end
|
|
||||||
|
|
||||||
local ostrpos = minetest.pos_to_string(pos)
|
|
||||||
prob_list[ostrpos] = {
|
|
||||||
pos = pos,
|
|
||||||
prob = prob,
|
|
||||||
force_place = force_place,
|
|
||||||
}
|
|
||||||
meta:set_string("prob_list", minetest.serialize(prob_list))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- [event] Remove probability on break node
|
|
||||||
minetest.register_on_dignode(function(pos, oldnode, player)
|
|
||||||
local original_strpos = minetest.pos_to_string(pos)
|
|
||||||
local px, py, pz = pos.x, pos.y, pos.z
|
|
||||||
for strpos, r in pairs(marked) do
|
|
||||||
local ap1, ap2 = r.pos1, r.pos2
|
|
||||||
if (px >= ap1.x and px <= ap2.x) and
|
|
||||||
(py >= ap1.y and py <= ap2.y) and
|
|
||||||
(pz >= ap1.z and pz <= ap2.z) then
|
|
||||||
local realpos = minetest.string_to_pos(strpos)
|
|
||||||
local meta = minetest.get_meta(realpos)
|
|
||||||
local prob_list = minetest.deserialize(meta:get_string("prob_list"))
|
|
||||||
|
|
||||||
if prob_list then
|
|
||||||
for _, i in pairs(prob_list) do
|
|
||||||
if _ == original_strpos then
|
|
||||||
prob_list[_] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
meta:set_string("prob_list", minetest.serialize(prob_list))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- [priv] schematic_override
|
-- [priv] schematic_override
|
||||||
minetest.register_privilege("schematic_override", {
|
minetest.register_privilege("schematic_override", {
|
||||||
description = "Allows you to access advschem nodes not owned by you",
|
description = "Allows you to access advschem nodes not owned by you",
|
||||||
@ -772,10 +795,6 @@ minetest.register_node("advschem:creator", {
|
|||||||
inv:set_size("probability", 1)
|
inv:set_size("probability", 1)
|
||||||
|
|
||||||
local pos1, pos2 = advschem.size(pos)
|
local pos1, pos2 = advschem.size(pos)
|
||||||
marked[minetest.pos_to_string(pos)] = {
|
|
||||||
pos1 = pos1,
|
|
||||||
pos2 = pos2,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Don't take item from itemstack
|
-- Don't take item from itemstack
|
||||||
return true
|
return true
|
||||||
@ -797,7 +816,7 @@ minetest.register_node("advschem:creator", {
|
|||||||
minetest.check_player_privs(player, "schematic_override") == true then
|
minetest.check_player_privs(player, "schematic_override") == true then
|
||||||
-- Get player attribute
|
-- Get player attribute
|
||||||
local tab = player:get_attribute("advschem:tab")
|
local tab = player:get_attribute("advschem:tab")
|
||||||
if not forms[tab] then
|
if not forms[tab] or not tab then
|
||||||
tab = "main"
|
tab = "main"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -817,9 +836,7 @@ minetest.register_node("advschem:creator", {
|
|||||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||||
if listname == "probability" then
|
if listname == "probability" then
|
||||||
local itemstring = stack:get_name()
|
local itemstring = stack:get_name()
|
||||||
if itemstring == "advschem:void" then
|
if itemstring ~= "advschem:probtool" then
|
||||||
return 0
|
|
||||||
elseif minetest.registered_items[itemstring].type ~= "node" then
|
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -832,6 +849,34 @@ minetest.register_node("advschem:creator", {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_tool("advschem:probtool", {
|
||||||
|
description = "Schematic Node Probability Tool",
|
||||||
|
wield_image = "advschem_probtool.png",
|
||||||
|
inventory_image = "advschem_probtool.png",
|
||||||
|
on_use = function(itemstack, placer, pointed_thing)
|
||||||
|
advschem.show_formspec(placer:getpos(), placer, "probtool", true)
|
||||||
|
end,
|
||||||
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
|
pos = pointed_thing.under
|
||||||
|
local nmeta = minetest.get_meta(pos)
|
||||||
|
local imeta = itemstack:get_meta()
|
||||||
|
local prob = tonumber(imeta:get_string("advschem_prob"))
|
||||||
|
local force_place = imeta:get_string("advschem_force_place")
|
||||||
|
|
||||||
|
if not prob or prob == 127 then
|
||||||
|
nmeta:set_string("advschem_prob", nil)
|
||||||
|
else
|
||||||
|
nmeta:set_string("advschem_prob", prob)
|
||||||
|
end
|
||||||
|
if force_place == "true" then
|
||||||
|
nmeta:set_string("advschem_force_place", "true")
|
||||||
|
else
|
||||||
|
nmeta:set_string("advschem_force_place", nil)
|
||||||
|
end
|
||||||
|
return itemstack
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
minetest.register_node("advschem:void", {
|
minetest.register_node("advschem:void", {
|
||||||
description = "Schematic Void",
|
description = "Schematic Void",
|
||||||
tiles = { "advschem_void.png" },
|
tiles = { "advschem_void.png" },
|
||||||
@ -897,8 +942,3 @@ minetest.register_chatcommand("placeschem", {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
---
|
|
||||||
--- Load Data
|
|
||||||
---
|
|
||||||
|
|
||||||
advschem.load()
|
|
||||||
|
BIN
textures/advschem_probtool.png
Normal file
BIN
textures/advschem_probtool.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 159 B |
Loading…
Reference in New Issue
Block a user